Skip to content

Commit

Permalink
fix: use drawPicture in some blending modes such as destination-in (
Browse files Browse the repository at this point in the history
#755)

* wip: fix issue #695

* chore: modify render_canvas to associated function

* test: add some tests

* chore: format codes

* fix: fix clippy errors
  • Loading branch information
nieyuyao committed Dec 12, 2023
1 parent e566efe commit 35f7f72
Show file tree
Hide file tree
Showing 10 changed files with 446 additions and 172 deletions.
36 changes: 36 additions & 0 deletions __test__/index.spec.ts
Expand Up @@ -175,3 +175,39 @@ test('stroke-and-filling-jpeg', async (t) => {
ctx.fill()
await snapshotImage(t, t.context, 'jpeg')
})

test('composition-destination-in', async (t) => {
const { ctx } = t.context
t.context.canvas.width = 300
t.context.canvas.height = 300
ctx.fillStyle = 'red'
ctx.fillRect(0, 0, 300, 300)
ctx.save()
ctx.globalCompositeOperation = 'destination-in';
ctx.fillStyle = 'green';
ctx.beginPath();
ctx.arc(150, 150, 100, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
ctx.restore()

await snapshotImage(t, t.context, 'png')
})

test('composition-source-in', async (t) => {
const { ctx } = t.context
t.context.canvas.width = 300
t.context.canvas.height = 300
ctx.fillStyle = 'red'
ctx.fillRect(0, 0, 300, 300)
ctx.save()
ctx.globalCompositeOperation = 'source-in';
ctx.fillStyle = 'green';
ctx.beginPath();
ctx.arc(150, 150, 100, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
ctx.restore()

await snapshotImage(t, t.context, 'png')
})
Binary file added __test__/snapshots/composition-destination-in.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added __test__/snapshots/composition-source-in.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 26 additions & 1 deletion skia-c/skia_c.cpp
Expand Up @@ -94,7 +94,6 @@ extern "C"
auto color_space = COLOR_SPACE_CAST;
auto info = SkImageInfo::Make(width, height, kRGBA_8888_SkColorType, alphaType, color_space);
auto surface = SkSurfaces::Raster(info);

if (surface)
{
// The surface ref count will equal one after the pointer is returned.
Expand Down Expand Up @@ -631,6 +630,12 @@ extern "C"
CANVAS_CAST->drawImageRect(image, src_rect, dst_rect, sampling, nullptr, SkCanvas::kFast_SrcRectConstraint);
}

void skiac_canvas_draw_picture(skiac_canvas *c_canvas, skiac_picture *c_picture, skiac_matrix *c_matrix, skiac_paint *c_paint) {
auto picture = reinterpret_cast<SkPicture *>(c_picture);
CANVAS_CAST->drawPicture(picture, MATRIX_CAST, PAINT_CAST);
}


// Paint

skiac_paint *skiac_paint_create()
Expand Down Expand Up @@ -784,6 +789,26 @@ extern "C"
return reinterpret_cast<skiac_path *>(new_path);
}

// SkPictureRecorder
skiac_picture_recorder *skiac_picture_recorder_create() {
return reinterpret_cast<skiac_picture_recorder *>(new SkPictureRecorder());
}

void skiac_picture_recorder_begin_recording(skiac_picture_recorder *c_picture_recorder, float x, float y, float width, float height) {
auto rect = SkRect::MakeXYWH(x, y, width, height);
reinterpret_cast<SkPictureRecorder *>(c_picture_recorder)->beginRecording(rect);
}

skiac_canvas*skiac_picture_recorder_get_recording_canvas(skiac_picture_recorder *c_picture_recorder) {
auto canvas = reinterpret_cast<SkPictureRecorder *>(c_picture_recorder)->getRecordingCanvas();
return reinterpret_cast<skiac_canvas *>(canvas);
}

skiac_picture* skiac_picture_recorder_finish_recording_as_picture(skiac_picture_recorder *c_picture_recorder) {
auto picture = reinterpret_cast<SkPictureRecorder *>(c_picture_recorder)->finishRecordingAsPicture();
return reinterpret_cast<skiac_picture *>(picture.release());
}

void skiac_path_swap(skiac_path *c_path, skiac_path *other_path)
{
auto other = reinterpret_cast<SkPath *>(other_path);
Expand Down
9 changes: 9 additions & 0 deletions skia-c/skia_c.hpp
Expand Up @@ -70,6 +70,8 @@ typedef struct skiac_typeface skiac_typeface;
typedef struct skiac_font_mgr skiac_font_mgr;
typedef struct skiac_typeface_font_provider skiac_typeface_font_provider;
typedef struct skiac_w_memory_stream skiac_w_memory_stream;
typedef struct skiac_picture_recorder skiac_picture_recorder;
typedef struct skiac_picture skiac_picture;

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
#define SK_FONT_FILE_PREFIX "C:/Windows/Fonts"
Expand Down Expand Up @@ -317,6 +319,7 @@ extern "C"
void skiac_canvas_reset(skiac_canvas *c_canvas);
void skiac_canvas_write_pixels(skiac_canvas *c_canvas, int width, int height, uint8_t *pixels, size_t row_bytes, int x, int y);
void skiac_canvas_write_pixels_dirty(skiac_canvas *c_canvas, int width, int height, uint8_t *pixels, size_t row_bytes, size_t length, float x, float y, float dirty_x, float dirty_y, float dirty_width, float dirty_height, uint8_t cs);
void skiac_canvas_draw_picture(skiac_canvas *c_canvas, skiac_picture *c_picture, skiac_matrix *c_matrix, skiac_paint *c_paint);

// Paint
skiac_paint *skiac_paint_create();
Expand Down Expand Up @@ -495,6 +498,12 @@ extern "C"

// SkSVG
void skiac_svg_text_to_path(const uint8_t *data, size_t length, skiac_font_collection *c_collection, skiac_sk_data *output_data);

// SkPictureRecorder
skiac_picture_recorder *skiac_picture_recorder_create();
void skiac_picture_recorder_begin_recording(skiac_picture_recorder *c_picture_recorder, float x, float y, float width, float height);
skiac_canvas *skiac_picture_recorder_get_recording_canvas(skiac_picture_recorder *c_picture_recorder);
skiac_picture *skiac_picture_recorder_finish_recording_as_picture(skiac_picture_recorder *c_picture_recorder);
}

#endif // SKIA_CAPI_H

0 comments on commit 35f7f72

Please sign in to comment.