Skip to content

Commit

Permalink
fix: drawImage canvas implementation (#989)
Browse files Browse the repository at this point in the history
  • Loading branch information
Brooooooklyn authored Feb 4, 2025
1 parent 341cdd1 commit 1420291
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
21 changes: 21 additions & 0 deletions __test__/regression.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,3 +266,24 @@ test('putImageData double free', (t) => {
ctx.putImageData(imgData, 0, 0, 0, 0, canvas.width, canvas.height)
})
})

// https://github.com/Brooooooklyn/canvas/issues/987
test('draw-canvas-on-canvas', async (t) => {
const backCanvas = createCanvas(1920, 1080)
const backCtx = backCanvas.getContext('2d')

const picCanvas = createCanvas(640, 480)
const picCtx = picCanvas.getContext('2d')

backCtx.fillStyle = '#000000'
backCtx.fillRect(0, 0, 1920, 1080)

// load images from disk or from a URL
const catImage = await loadImage(join(__dirname, 'javascript.png'))

picCtx.drawImage(catImage, 0, 0, catImage.width, catImage.height)

backCtx.drawImage(picCanvas, 240, 0, 1440, 1080)

await snapshotImage(t, { ctx: backCtx, canvas: backCanvas })
})
Binary file added __test__/snapshots/draw-canvas-on-canvas.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 11 additions & 5 deletions skia-c/skia_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,19 +363,25 @@ extern "C"
int filter_quality,
skiac_paint *c_paint)
{
const auto src_rect = SkRect::MakeXYWH(sx, sy, s_width, s_height);
const auto dst_rect = SkRect::MakeXYWH(dx, dy, d_width, d_height);
auto fq = enable_smoothing ? filter_quality : 0;
const auto sampling = SamplingOptionsFromFQ(fq);
auto paint = reinterpret_cast<const SkPaint *>(c_paint);
if (is_canvas) {
auto srcSurface = reinterpret_cast<SkSurface *>(c_bitmap);
auto src_surface = reinterpret_cast<SkSurface *>(c_bitmap);
CANVAS_CAST->save();
// Translate to the destination position
CANVAS_CAST->translate(dx, dy);
CANVAS_CAST->clipRect(SkRect::MakeWH(d_width, d_height));
srcSurface->draw(CANVAS_CAST, -sx, -sy, sampling, paint);
// Scale using the ratio of destination size to source surface size
CANVAS_CAST->scale(
d_width / src_surface->width(),
d_height / src_surface->height()
);
// Draw the surface directly
src_surface->draw(CANVAS_CAST, -sx, -sy, sampling, paint);
CANVAS_CAST->restore();
} else {
const auto src_rect = SkRect::MakeXYWH(sx, sy, s_width, s_height);
const auto dst_rect = SkRect::MakeXYWH(dx, dy, d_width, d_height);
CANVAS_CAST->drawImageRect(SkImages::RasterFromBitmap(*BITMAP_CAST), src_rect, dst_rect, sampling, paint, SkCanvas::kFast_SrcRectConstraint);
}
}
Expand Down

0 comments on commit 1420291

Please sign in to comment.