diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index 1e8d9e5f..762029a8 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -448,7 +448,7 @@ jobs: fail-fast: false matrix: node: ['20', '22'] - runs-on: ubuntu-latest + runs-on: ubuntu-24.04-arm steps: - uses: actions/checkout@v4 @@ -473,16 +473,7 @@ jobs: shell: bash - name: Install dependencies - run: | - yarn config set supportedArchitectures.cpu "arm64" - yarn config set supportedArchitectures.libc "glibc" - yarn install --immutable --mode=skip-build - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: arm64 - - - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + run: yarn install --immutable --mode=skip-build - name: Setup and run tests uses: addnab/docker-run-action@v3 @@ -506,7 +497,7 @@ jobs: needs: - build - runs-on: ubuntu-latest + runs-on: ubuntu-24.04-arm steps: - uses: actions/checkout@v4 @@ -536,13 +527,6 @@ jobs: yarn config set supportedArchitectures.libc "musl" yarn install --immutable --mode=skip-build - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: arm64 - - - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - - name: Setup and run tests uses: addnab/docker-run-action@v3 with: diff --git a/build.rs b/build.rs index 73254b23..08eff892 100644 --- a/build.rs +++ b/build.rs @@ -164,7 +164,7 @@ fn main() { .cpp_set_stdlib("stdc++") .flag("-static") .include("/usr/arm-linux-gnueabihf/include") - .include(format!("/usr/arm-linux-gnueabihf/include/c++/8")); + .include("/usr/arm-linux-gnueabihf/include/c++/8"); println!("cargo:rustc-link-lib=static=stdc++"); println!("cargo:rustc-link-search=/usr/lib/gcc-cross/arm-linux-gnueabihf/8"); } diff --git a/skia-c/skia_c.cpp b/skia-c/skia_c.cpp index e26e6619..3a8578bb 100644 --- a/skia-c/skia_c.cpp +++ b/skia-c/skia_c.cpp @@ -293,14 +293,10 @@ extern "C" void skiac_surface_get_bitmap(skiac_surface *c_surface, skiac_bitmap_info *info) { - auto image = SURFACE_CAST->makeImageSnapshot(); - auto bitmap = new SkBitmap(); - auto image_info = image->imageInfo(); - bitmap->allocPixels(image_info); - image->readPixels(image_info, bitmap->getPixels(), bitmap->rowBytes(), 0, 0); - info->bitmap = reinterpret_cast(bitmap); - info->width = (size_t)image_info.width(); - info->height = (size_t)image_info.height(); + info->is_canvas = true; + info->bitmap = reinterpret_cast(c_surface); + info->width = (size_t)SURFACE_CAST->width(); + info->height = (size_t)SURFACE_CAST->height(); } // Canvas @@ -354,6 +350,7 @@ extern "C" void skiac_canvas_draw_image( skiac_canvas *c_canvas, skiac_bitmap *c_bitmap, + bool is_canvas, float sx, float sy, float s_width, @@ -368,11 +365,19 @@ extern "C" { 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 sk_image = SkImages::RasterFromBitmap(*BITMAP_CAST); auto fq = enable_smoothing ? filter_quality : 0; const auto sampling = SamplingOptionsFromFQ(fq); auto paint = reinterpret_cast(c_paint); - CANVAS_CAST->drawImageRect(sk_image, src_rect, dst_rect, sampling, paint, SkCanvas::kFast_SrcRectConstraint); + if (is_canvas) { + auto srcSurface = reinterpret_cast(c_bitmap); + CANVAS_CAST->save(); + CANVAS_CAST->translate(dx, dy); + CANVAS_CAST->clipRect(SkRect::MakeWH(d_width, d_height)); + srcSurface->draw(CANVAS_CAST, -sx, -sy, sampling, paint); + CANVAS_CAST->restore(); + } else { + CANVAS_CAST->drawImageRect(SkImages::RasterFromBitmap(*BITMAP_CAST), src_rect, dst_rect, sampling, paint, SkCanvas::kFast_SrcRectConstraint); + } } void skiac_canvas_draw_path(skiac_canvas *c_canvas, skiac_path *c_path, skiac_paint *c_paint) diff --git a/skia-c/skia_c.hpp b/skia-c/skia_c.hpp index f05fe7be..a523a90c 100644 --- a/skia-c/skia_c.hpp +++ b/skia-c/skia_c.hpp @@ -224,6 +224,7 @@ struct skiac_bitmap_info skiac_bitmap *bitmap; int width; int height; + bool is_canvas; }; struct skiac_string @@ -294,6 +295,7 @@ extern "C" void skiac_canvas_draw_image( skiac_canvas *c_canvas, skiac_bitmap *c_bitmap, + bool is_canvas, float sx, float sy, float s_width, diff --git a/src/ctx.rs b/src/ctx.rs index 796d21a9..97ecfc39 100644 --- a/src/ctx.rs +++ b/src/ctx.rs @@ -712,7 +712,6 @@ impl Context { d_width: f32, d_height: f32, ) -> Result<()> { - let bitmap = bitmap.0.bitmap; let mut paint: Paint = self.fill_paint()?; paint.set_alpha((self.state.global_alpha * 255.0).round() as u8); Self::render_canvas( diff --git a/src/sk.rs b/src/sk.rs index 3c5f2fc1..75e041f4 100644 --- a/src/sk.rs +++ b/src/sk.rs @@ -111,6 +111,7 @@ pub mod ffi { pub bitmap: *mut skiac_bitmap, pub width: i32, pub height: i32, + pub is_canvas: bool, } #[repr(C)] @@ -373,6 +374,7 @@ pub mod ffi { pub fn skiac_canvas_draw_image( canvas: *mut skiac_canvas, bitmap: *mut skiac_bitmap, + is_image: bool, sx: f32, sy: f32, s_width: f32, @@ -1822,6 +1824,7 @@ impl Surface { bitmap: ptr::null_mut(), width: 0, height: 0, + is_canvas: true, }; unsafe { ffi::skiac_surface_get_bitmap(self.ptr, &mut bitmap_info) }; Bitmap(bitmap_info) @@ -2068,7 +2071,7 @@ impl Canvas { pub fn draw_image( &mut self, - image: *mut ffi::skiac_bitmap, + image: &Bitmap, sx: f32, sy: f32, s_width: f32, @@ -2084,7 +2087,8 @@ impl Canvas { unsafe { ffi::skiac_canvas_draw_image( self.0, - image, + image.0.bitmap, + image.0.is_canvas, sx, sy, s_width, @@ -3439,7 +3443,7 @@ impl Drop for ImageFilter { #[repr(transparent)] #[derive(Debug)] -pub(crate) struct Bitmap(pub(crate) ffi::skiac_bitmap_info); +pub struct Bitmap(pub(crate) ffi::skiac_bitmap_info); unsafe impl Send for Bitmap {} unsafe impl Sync for Bitmap {} @@ -3450,6 +3454,7 @@ impl Bitmap { bitmap: ptr::null_mut(), width: 0, height: 0, + is_canvas: false, }; unsafe { ffi::skiac_bitmap_make_from_buffer(ptr, size, &mut bitmap_info); @@ -3467,6 +3472,7 @@ impl Bitmap { bitmap: ptr::null_mut(), width: 0, height: 0, + is_canvas: false, }; unsafe { let is_valid = ffi::skiac_bitmap_make_from_svg( @@ -3502,6 +3508,7 @@ impl Bitmap { bitmap: ptr::null_mut(), width: 0, height: 0, + is_canvas: false, }; unsafe { ffi::skiac_bitmap_make_from_svg( @@ -3545,6 +3552,7 @@ impl Bitmap { bitmap, width: row_bytes as i32, height: (size / row_bytes / 4) as i32, + is_canvas: false, }) } } @@ -3552,7 +3560,9 @@ impl Bitmap { impl Drop for Bitmap { fn drop(&mut self) { unsafe { - ffi::skiac_bitmap_destroy(self.0.bitmap); + if !self.0.is_canvas { + ffi::skiac_bitmap_destroy(self.0.bitmap); + } } } }