From 9b5ff743da637824f94e34aacc39ea43cac13864 Mon Sep 17 00:00:00 2001 From: Kris <1611248+Rinzwind@users.noreply.github.com> Date: Sat, 31 Aug 2024 12:35:59 +0200 Subject: [PATCH] Extended AeCanvas to support setting a FormSet as background. --- .../AeFilesystemResources.extension.st | 6 ++++ .../AeCanvasTest.class.st | 27 ++++++++++++++++++ src/Alexandrie-Canvas/AeCanvas.class.st | 21 ++++++++++++++ tests/canvas/renderFormSet.png | Bin 0 -> 3452 bytes tests/images/removeIcon-2x.png | Bin 0 -> 687 bytes 5 files changed, 54 insertions(+) create mode 100644 tests/canvas/renderFormSet.png create mode 100644 tests/images/removeIcon-2x.png diff --git a/src/Alexandrie-Cairo-Tests/AeFilesystemResources.extension.st b/src/Alexandrie-Cairo-Tests/AeFilesystemResources.extension.st index b3ff5de..3028654 100644 --- a/src/Alexandrie-Cairo-Tests/AeFilesystemResources.extension.st +++ b/src/Alexandrie-Cairo-Tests/AeFilesystemResources.extension.st @@ -12,6 +12,12 @@ AeFilesystemResources class >> imagesDirectory [ ^ self testsDirectory / 'images' ] +{ #category : #'*Alexandrie-Cairo-Tests' } +AeFilesystemResources class >> removeIcon2xPNG [ + + ^ self imagesDirectory / 'removeIcon-2x.png' +] + { #category : #'*Alexandrie-Cairo-Tests' } AeFilesystemResources class >> removeIconPNG [ diff --git a/src/Alexandrie-Canvas-Tests/AeCanvasTest.class.st b/src/Alexandrie-Canvas-Tests/AeCanvasTest.class.st index 9a8439f..467f17e 100644 --- a/src/Alexandrie-Canvas-Tests/AeCanvasTest.class.st +++ b/src/Alexandrie-Canvas-Tests/AeCanvasTest.class.st @@ -307,6 +307,33 @@ AeCanvasTest >> renderForm [ ^ aeCanvas ] +{ #category : #tests } +AeCanvasTest >> renderFormSet [ + + | aeCanvas aForm aFormSet | + + SystemVersion current major >= 12 ifFalse: [ self skip ]. "Earlier versions do not have FormSet" + + aeCanvas := AeCanvas newFor: ((AeCairoImageSurface extent: (60@20) * 2) deviceScale: 2 asPoint; yourself). + aeCanvas clear: Color paleGreen. + + aForm := Form fromFileNamed: AeFilesystemResources removeIcon2xPNG. + aFormSet := FormSet extent: aForm extent // 2 depth: aForm depth forms: { aForm }. + + aeCanvas pathScale: ((aeCanvas extent / aeCanvas deviceScale) / aFormSet extent) asFloatPoint. + aeCanvas pathFactory: [ :cairoContext | + "Tip: Use another path to clip the form" + cairoContext rectangleTo: aFormSet extent ]. + + aeCanvas + setBackgroundWithFormSet: aFormSet + alpha: 1.0. + aeCanvas setBorderOff. + aeCanvas drawFigure. + + ^ aeCanvas +] + { #category : #private } AeCanvasTest >> renderGlyphs: aCairoGlyphsArray scaledFont: aCairoScaledFont on: aeCanvas [ diff --git a/src/Alexandrie-Canvas/AeCanvas.class.st b/src/Alexandrie-Canvas/AeCanvas.class.st index a38a970..9e01f0f 100644 --- a/src/Alexandrie-Canvas/AeCanvas.class.st +++ b/src/Alexandrie-Canvas/AeCanvas.class.st @@ -32,6 +32,7 @@ Class { 'hasBackground', 'borderWidth', 'formToCairoSurfaceCache', + 'formSetToCairoSurfaceCache', 'backgroundAlpha', 'cairoSurface', 'backgroundSourceBlock', @@ -414,6 +415,15 @@ AeCanvas >> initializeCaches [ factory: [ :form | AeCairoImageSurface fromForm: form ]; yourself. + formSetToCairoSurfaceCache := LRUCache new + maximumWeight: 400; + factory: [ :formSet | + | scale | + scale := self deviceScale max rounded. + (AeCairoImageSurface fromForm: (formSet asFormAtScale: scale)) + deviceScale: scale asPoint; + yourself ]; + yourself. ] { #category : #initialization } @@ -693,6 +703,17 @@ AeCanvas >> setBackgroundWithForm: aForm alpha: aDouble [ ] +{ #category : #'API - background' } +AeCanvas >> setBackgroundWithFormSet: aFormSet alpha: aDouble [ + + self + setBackgroundWith: [ + | aCairoSurface | + aCairoSurface := formSetToCairoSurfaceCache at: aFormSet. + cairoContext sourceSurface: aCairoSurface x: 0.0 y: 0.0 ] + alpha: aDouble +] + { #category : #'API - border' } AeCanvas >> setBorderBlock: aBlockClosure [ diff --git a/tests/canvas/renderFormSet.png b/tests/canvas/renderFormSet.png new file mode 100644 index 0000000000000000000000000000000000000000..14604b016380c13dcfec00974bd7c30d27392f32 GIT binary patch literal 3452 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 VYR8H2YTW<;002ovPDHLkV1nhzIr9Jj literal 0 HcmV?d00001