diff --git a/src/Alexandrie-Cairo/AeCairoContext.class.st b/src/Alexandrie-Cairo/AeCairoContext.class.st index bcae66a..53d8ec8 100644 --- a/src/Alexandrie-Cairo/AeCairoContext.class.st +++ b/src/Alexandrie-Cairo/AeCairoContext.class.st @@ -1435,6 +1435,19 @@ AeCairoContext >> rotateByRadians: angle [ double angle ) ) ] +{ #category : #'API - matrix' } +AeCairoContext >> rotateByRadians: angle aboutX: centerX y: centerY [ + "Modifies the current transformation matrix (CTM) by rotating the user-space axes by angle radians about a center received as argument. + + See: https://www.cairographics.org/cookbook/transform_about_point/ + See: https://www.cairographics.org/cookbook/matrix_conventions/" + + self + translateByX: centerX y: centerY; + rotateByRadians: angle; + translateByX: centerX negated y: centerY negated +] + { #category : #'API - path' } AeCairoContext >> roundedRectangleLeft: l top: t right: r bottom: b tl: tlR tr: trR br: brR bl: blR [ "Append the path of a rounded rectangle. diff --git a/src/Alexandrie-Canvas-Tests/AeCanvasTest.class.st b/src/Alexandrie-Canvas-Tests/AeCanvasTest.class.st index 467f17e..a2f82f2 100644 --- a/src/Alexandrie-Canvas-Tests/AeCanvasTest.class.st +++ b/src/Alexandrie-Canvas-Tests/AeCanvasTest.class.st @@ -461,6 +461,48 @@ AeCanvasTest >> renderOpenFigure [ ^ aeCanvas ] +{ #category : #tests } +AeCanvasTest >> renderWithRotation [ + + | aeCanvas extent | + extent := 40 @ 30. + aeCanvas := AeCanvas extent: extent. + + aeCanvas pathRotateByRadians: 15 degreesToRadians. + + aeCanvas pathFactory: [ :cairoContext | + cairoContext rectangleTo: extent / 2 ]. + + aeCanvas setBackgroundWith: [ + aeCanvas setSourceColor: Color purple ]. + aeCanvas setBorderOff. + aeCanvas drawFigure. + + ^ aeCanvas +] + +{ #category : #tests } +AeCanvasTest >> renderWithRotationAboutCenter [ + + | aeCanvas extent | + extent := 40 @ 30. + aeCanvas := AeCanvas extent: extent. + + aeCanvas + pathRotateByRadians: 45 degreesToRadians + about: extent / 2. + + aeCanvas pathFactory: [ :cairoContext | + cairoContext rectangleTo: extent ]. + + aeCanvas setBackgroundWith: [ + aeCanvas setSourceColor: Color cyan ]. + aeCanvas setBorderOff. + aeCanvas drawFigure. + + ^ aeCanvas +] + { #category : #tests } AeCanvasTest >> renderZWJEmojiWithHarfbuzz [ diff --git a/src/Alexandrie-Canvas/AeCanvas.class.st b/src/Alexandrie-Canvas/AeCanvas.class.st index 9e01f0f..7f2ce9a 100644 --- a/src/Alexandrie-Canvas/AeCanvas.class.st +++ b/src/Alexandrie-Canvas/AeCanvas.class.st @@ -552,6 +552,20 @@ AeCanvas >> pathFactory: aUnaryBlock [ borderPathBlock := nil. ] +{ #category : #'API - transformations' } +AeCanvas >> pathRotateByRadians: angle [ + "Rotate by an angle, expressed in radians, about 0@0." + + cairoContext rotateByRadians: angle +] + +{ #category : #'API - transformations' } +AeCanvas >> pathRotateByRadians: angle about: aPoint [ + "Rotate by an angle, expressed in radians, about aPoint." + + cairoContext rotateByRadians: angle aboutX: aPoint x y: aPoint y +] + { #category : #'API - transformations' } AeCanvas >> pathScale: aPoint [ diff --git a/tests/canvas/renderWithRotation.png b/tests/canvas/renderWithRotation.png new file mode 100644 index 0000000..841f517 Binary files /dev/null and b/tests/canvas/renderWithRotation.png differ diff --git a/tests/canvas/renderWithRotationAboutCenter.png b/tests/canvas/renderWithRotationAboutCenter.png new file mode 100644 index 0000000..23eff80 Binary files /dev/null and b/tests/canvas/renderWithRotationAboutCenter.png differ