tim Rowledge uploaded a new version of Graphics to project The Trunk:
http://source.squeak.org/trunk/Graphics-tpr.342.mcz ==================== Summary ==================== Name: Graphics-tpr.342 Author: tpr Time: 8 June 2016, 10:22:17.667271 am UUID: ef647385-8d46-494e-93b4-e3df81b23313 Ancestors: Graphics-topa.341 When scaling a Form via WarpBlt class>>#rotate:degrees:center:scaleBy:smoothing: the scaling factor seems to have been left out in the calculation of the returned offset. This meant that Scratch sprites did Bad Things at times. The only non-Scratch client I could find for this method is SketchMorph, but that ignores the returned offset anyway; thus it seems reasonable to makes things work ok for Scratch. =============== Diff against Graphics-topa.341 =============== Item was changed: ----- Method: WarpBlt class>>rotate:degrees:center:scaleBy:smoothing: (in category 'form rotation') ----- + rotate: srcForm degrees: angleInDegrees center: rotationCenter scaleBy: scalePoint smoothing: cellSize + "Rotate the given Form angleInDegrees about the given rotationCenter and scale its width and height by x and y of the given scale + point. Smooth using the given cell size, an integer between 1 and 3, where 1 means no smoothing. + Return a pair where the first element is the rotated Form and the second is the position offset required to align the center of the rotated Form with that of the original. + Note that the dimensions of the resulting Form generally differ from those of the original." + | srcRect srcCenter radians dstOrigin dstCorner p dstRect inverseScale quad dstForm warpSrc newRotationPoint oldOffset | - rotate: srcForm degrees: angleInDegrees center: aPoint scaleBy: scalePoint smoothing: cellSize - "Rotate the given Form the given number of degrees about the given center and scale its width and height by x and y of the given scale point. Smooth using the given cell size, an integer between 1 and 3, where 1 means no smoothing. Return a pair where the first element is the rotated Form and the second is the position offset required to align the center of the rotated Form with that of the original. Note that the dimensions of the resulting Form generally differ from those of the original." - - | srcRect center radians dstOrigin dstCorner p dstRect inverseScale quad dstForm newCenter warpSrc | srcRect := srcForm boundingBox. + srcCenter := srcRect center. - center := srcRect center. radians := angleInDegrees degreesToRadians. + dstOrigin := dstCorner := srcCenter. + srcRect corners + do: [:corner | + "find the limits of a rectangle that just encloses the rotated + original; in general, this rectangle will be larger than the + original (e.g., consider a square rotated by 45 degrees)" + p := (corner - srcCenter scaleBy: scalePoint) + srcCenter. + p := (p rotateBy: radians about: srcCenter) rounded. + dstOrigin := dstOrigin min: p. + dstCorner := dstCorner max: p]. - dstOrigin := dstCorner := center. - srcRect corners do: [:corner | - "find the limits of a rectangle that just encloses the rotated - original; in general, this rectangle will be larger than the - original (e.g., consider a square rotated by 45 degrees)" - p := ((corner - center) scaleBy: scalePoint) + center. - p := (p rotateBy: radians about: center) rounded. - dstOrigin := dstOrigin min: p. - dstCorner := dstCorner max: p]. - "rotate the enclosing rectangle back to get the source quadrilateral" dstRect := dstOrigin corner: dstCorner. + inverseScale := 1.0 / scalePoint x @ (1.0 / scalePoint y). + quad := dstRect innerCorners + collect: [:corner | + p := corner rotateBy: radians negated about: srcCenter. + (p - srcCenter scaleBy: inverseScale) + srcCenter]. - inverseScale := (1.0 / scalePoint x)@(1.0 / scalePoint y). - quad := dstRect innerCorners collect: [:corner | - p := corner rotateBy: radians negated about: center. - ((p - center) scaleBy: inverseScale) + center]. "make a Form to hold the result and do the rotation" warpSrc := srcForm. + srcForm isColorForm + ifTrue: [warpSrc := Form extent: srcForm extent depth: 16. + srcForm displayOn: warpSrc. + dstForm := Form extent: dstRect extent depth: 16 + "use 16-bit depth to allow smoothing"] + ifFalse: [dstForm := srcForm species extent: dstRect extent depth: srcForm depth]. - (srcForm isColorForm) - ifTrue: [ - cellSize > 1 | true "ar 12/27/2001: Always enable - else sketches won't work" - ifTrue: [ - warpSrc := Form extent: srcForm extent depth: 16. - srcForm displayOn: warpSrc. - dstForm := Form extent: dstRect extent depth: 16] "use 16-bit depth to allow smoothing" - ifFalse: [ - dstForm := srcForm species extent: dstRect extent depth: srcForm depth]] - ifFalse: [ - dstForm := srcForm species extent: dstRect extent depth: srcForm depth]. - (WarpBlt toForm: dstForm) sourceForm: warpSrc; colorMap: (warpSrc colormapIfNeededFor: dstForm); + cellSize: cellSize; + combinationRule: Form paint; + copyQuad: quad toRect: dstForm boundingBox. - cellSize: cellSize; "installs a new colormap if cellSize > 1" - combinationRule: Form paint; - copyQuad: quad toRect: dstForm boundingBox. + "installs a new colormap if cellSize > 1" + dstForm isColorForm + ifTrue: [dstForm colors: srcForm colors copy]. + + oldOffset := rotationCenter - srcCenter truncated * scalePoint. + newRotationPoint := dstForm extent / 2.0 + (oldOffset rotateBy: radians about: 0 @ 0). + + ^ Array with: dstForm with: newRotationPoint - rotationCenter! - (dstForm isColorForm) ifTrue: [dstForm colors: srcForm colors copy]. - newCenter := (center rotateBy: radians about: aPoint) truncated. - ^ Array with: dstForm with: dstRect origin + (newCenter - center) - ! |
Free forum by Nabble | Edit this page |