From d1137a549e6278c14e265253862fa7ff9bb6dbfa Mon Sep 17 00:00:00 2001 From: LongYinan Date: Tue, 4 Mar 2025 17:11:21 +0800 Subject: [PATCH] fix: create pattern from Canvas (#1013) --- __test__/regression.spec.ts | 18 ++++++++++++++++++ __test__/snapshots/canvas-pattern-1010.png | Bin 0 -> 20121 bytes index.d.ts | 15 +++------------ skia-c/skia_c.cpp | 15 ++++++++++++++- skia-c/skia_c.hpp | 1 + src/pattern.rs | 4 ++++ src/sk.rs | 15 +++++++++++++-- 7 files changed, 53 insertions(+), 15 deletions(-) create mode 100644 __test__/snapshots/canvas-pattern-1010.png diff --git a/__test__/regression.spec.ts b/__test__/regression.spec.ts index c181e47d..3b8edb0a 100644 --- a/__test__/regression.spec.ts +++ b/__test__/regression.spec.ts @@ -305,3 +305,21 @@ test('draw-avif-image', async (t) => { ctx.drawImage(image, 0, 0) await snapshotImage(t, { ctx, canvas }) }) + +// https://github.com/Brooooooklyn/canvas/issues/1010 +test('canvas-pattern-1010', async (t) => { + const canvas = createCanvas(512, 512) + const tmpCanvas = createCanvas(512, 512) + const ctx = canvas.getContext('2d') + const tmpCtx = tmpCanvas.getContext('2d') + const image = await loadImage(join(__dirname, 'javascript.png')) + tmpCtx.drawImage(image, 0, 0) + const pattern = ctx.createPattern(image, 'repeat') + const pattern2 = ctx.createPattern(tmpCanvas, 'repeat') + ctx.fillStyle = pattern + ctx.fillRect(0, 0, 512 / 2, 512) + + ctx.fillStyle = pattern2 + ctx.fillRect(512 / 2, 0, 512 / 2, 512) + await snapshotImage(t, { ctx, canvas }) +}) diff --git a/__test__/snapshots/canvas-pattern-1010.png b/__test__/snapshots/canvas-pattern-1010.png new file mode 100644 index 0000000000000000000000000000000000000000..e3aedc57a5490808dbd34f8be368862c51d6effa GIT binary patch literal 20121 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 azq33vxn$nP!@%R^7(8A5T-G@yGywqBd%2bX literal 0 HcmV?d00001 diff --git a/index.d.ts b/index.d.ts index 5a690bba..40338625 100644 --- a/index.d.ts +++ b/index.d.ts @@ -107,9 +107,7 @@ export interface DOMMatrix extends DOMMatrixReadOnly { toJSON(): { [K in OmitNeverOfMatrix]: DOMMatrix[K] } } -type OmitMatrixMethod = { - [K in keyof DOMMatrix]: DOMMatrix[K] extends (...args: any[]) => any ? never : K -} +type OmitMatrixMethod = { [K in keyof DOMMatrix]: DOMMatrix[K] extends (...args: any[]) => any ? never : K } type OmitNeverOfMatrix = OmitMatrixMethod[keyof OmitMatrixMethod] @@ -278,7 +276,7 @@ export interface SKRSContext2D dh: number, ): void createPattern( - image: Image | ImageData, + image: Image | ImageData | Canvas | SvgCanvas, repeat: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat' | null, ): CanvasPattern getContextAttributes(): { alpha: boolean; desynchronized: boolean } @@ -393,14 +391,7 @@ export function createCanvas(width: number, height: number): Canvas export function createCanvas(width: number, height: number, svgExportFlag: SvgExportFlag): SvgCanvas interface IGlobalFonts { - readonly families: { - family: string - styles: { - weight: number - width: string - style: string - }[] - }[] + readonly families: { family: string; styles: { weight: number; width: string; style: string }[] }[] // return true if succeeded register(font: Buffer, nameAlias?: string): boolean // absolute path diff --git a/skia-c/skia_c.cpp b/skia-c/skia_c.cpp index f720e7d6..70ca0c40 100644 --- a/skia-c/skia_c.cpp +++ b/skia-c/skia_c.cpp @@ -1644,6 +1644,7 @@ extern "C" } skiac_shader *skiac_bitmap_get_shader( + bool is_canvas, skiac_bitmap *c_bitmap, int repeat_x, int repeat_y, @@ -1652,7 +1653,19 @@ extern "C" skiac_transform c_ts) { const auto ts = conv_from_transform(c_ts); - auto bitmap = reinterpret_cast(c_bitmap); + SkBitmap *bitmap; + if (is_canvas) { + auto surface = reinterpret_cast(c_bitmap); + auto bm = new SkBitmap(); + bm->allocPixels(surface->imageInfo()); + if (surface->readPixels(*bm, 0, 0)) { + bitmap = bm; + } else { + return nullptr; + } + } else { + bitmap = reinterpret_cast(c_bitmap); + } auto shader = bitmap->makeShader((SkTileMode)repeat_x, (SkTileMode)repeat_y, SkSamplingOptions({B, C}), &ts).release(); if (shader) { diff --git a/skia-c/skia_c.hpp b/skia-c/skia_c.hpp index bf876951..bd9f0ac2 100644 --- a/skia-c/skia_c.hpp +++ b/skia-c/skia_c.hpp @@ -515,6 +515,7 @@ extern "C" size_t skiac_bitmap_get_width(skiac_bitmap *c_bitmap); size_t skiac_bitmap_get_height(skiac_bitmap *c_bitmap); skiac_shader *skiac_bitmap_get_shader( + bool is_canvas, skiac_bitmap *c_bitmap, int repeat_x, int repeat_y, diff --git a/src/pattern.rs b/src/pattern.rs index 168effeb..30921394 100644 --- a/src/pattern.rs +++ b/src/pattern.rs @@ -55,6 +55,7 @@ impl CanvasPattern { repetition: Option, ) -> Result { let mut inner_bitmap = None; + let mut is_canvas = false; let bitmap = match input { Either4::A(image) => image .bitmap @@ -80,12 +81,14 @@ impl CanvasPattern { let canvas_bitmap = canvas.ctx.context.surface.get_bitmap(); let ptr = canvas_bitmap.0.bitmap; inner_bitmap = Some(canvas_bitmap); + is_canvas = true; ptr } Either4::D(svg_canvas) => { let canvas_bitmap = svg_canvas.ctx.context.surface.get_bitmap(); let ptr = canvas_bitmap.0.bitmap; inner_bitmap = Some(canvas_bitmap); + is_canvas = true; ptr } }; @@ -110,6 +113,7 @@ impl CanvasPattern { bitmap, repeat_x, repeat_y, + is_canvas, }), bitmap: inner_bitmap, }) diff --git a/src/sk.rs b/src/sk.rs index 180a4991..c8f84ccc 100644 --- a/src/sk.rs +++ b/src/sk.rs @@ -849,6 +849,7 @@ pub mod ffi { pub fn skiac_bitmap_get_height(c_bitmap: *mut skiac_bitmap) -> usize; pub fn skiac_bitmap_get_shader( + is_canvas: bool, c_bitmap: *mut skiac_bitmap, repeat_x: i32, repeat_y: i32, @@ -2973,6 +2974,7 @@ impl Shader { } pub fn from_bitmap( + is_canvas: bool, bitmap: *mut ffi::skiac_bitmap, repeat_x: TileMode, repeat_y: TileMode, @@ -2981,8 +2983,15 @@ impl Shader { ts: Transform, ) -> Option { unsafe { - let shader_ptr = - ffi::skiac_bitmap_get_shader(bitmap, repeat_x as i32, repeat_y as i32, b, c, ts.into()); + let shader_ptr = ffi::skiac_bitmap_get_shader( + is_canvas, + bitmap, + repeat_x as i32, + repeat_y as i32, + b, + c, + ts.into(), + ); Shader::from_ptr(shader_ptr) } } @@ -3581,11 +3590,13 @@ pub struct ImagePattern { pub(crate) repeat_x: TileMode, pub(crate) repeat_y: TileMode, pub(crate) transform: Transform, + pub(crate) is_canvas: bool, } impl ImagePattern { pub(crate) fn get_shader(&self) -> Option { Shader::from_bitmap( + self.is_canvas, self.bitmap, self.repeat_x, self.repeat_y,