Skip to content

Commit

Permalink
feat: support creating SkImage
Browse files Browse the repository at this point in the history
  • Loading branch information
doodlewind committed Jan 18, 2021
1 parent bb0c108 commit 3945321
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 48 deletions.
35 changes: 17 additions & 18 deletions skia-c/skia_c.cpp
Expand Up @@ -722,28 +722,27 @@ extern "C"
SkSafeUnref(mask_filter);
}

skiac_data *skiac_data_create(uint8_t *addr, size_t size)
{
auto sk_data = SkData::MakeWithCopy(reinterpret_cast<const void *>(addr), size);
if (sk_data)
{
return reinterpret_cast<skiac_data *>(sk_data.get());
}
else
{
return nullptr;
}
}
// SkData

uint8_t *skiac_data_get_ptr(skiac_data *c_data)
void skiac_sk_data_destroy(skiac_data *c_data)
{
return (uint8_t *)reinterpret_cast<SkData *>(c_data)->data();
auto data = reinterpret_cast<SkData *>(c_data);
SkSafeUnref(data);
}

// SkData
void skiac_sk_data_destroy(skiac_data *c_data)
// Image

skiac_image *skiac_image_make_from_buffer(uint8_t *ptr, size_t size)
{
auto sk_data = reinterpret_cast<SkData *>(c_data);
SkSafeUnref(sk_data);
auto data = SkData::MakeWithCopy(reinterpret_cast<const void *>(ptr), size);
auto codec = SkCodec::MakeFromData(data);
auto info = codec->getInfo();
auto row_bytes = info.width() * info.bytesPerPixel();
auto bitmap = SkBitmap();
bitmap.installPixels(info, nullptr, row_bytes);
auto image = SkImage::MakeFromBitmap(bitmap);

printf("width: %d, height %d, row_bytes %d\n", info.width(), info.height(), row_bytes);
return reinterpret_cast<skiac_image *>(image.release());
}
}
14 changes: 9 additions & 5 deletions skia-c/skia_c.hpp
Expand Up @@ -2,17 +2,19 @@
#define SKIA_CAPI_H

#include <include/codec/SkCodec.h>
#include <include/core/SkData.h>
#include <include/core/SkPathEffect.h>
#include <include/core/SkBitmap.h>
#include <include/core/SkCanvas.h>
#include <include/core/SkData.h>
#include <include/core/SkGraphics.h>
#include <include/core/SkImage.h>
#include <include/core/SkPaint.h>
#include <include/core/SkPathEffect.h>
#include <include/core/SkSurface.h>
#include <include/core/SkMaskFilter.h>
#include <include/effects/SkDashPathEffect.h>
#include <include/effects/SkGradientShader.h>

#include <cstdio>
#include <stdint.h>

typedef struct skiac_surface skiac_surface;
Expand Down Expand Up @@ -214,11 +216,13 @@ extern "C"
void skiac_mask_filter_destroy(skiac_mask_filter *c_mask_filter);

// SkData
skiac_data *skiac_data_create(uint8_t *addr, size_t size);

uint8_t *skiac_data_get_ptr(skiac_data *c_data);

void skiac_sk_data_destroy(skiac_data *c_data);

// Image
skiac_image *skiac_image_make_from_buffer(uint8_t *ptr, size_t size);
uint32_t skiac_image_get_width(skiac_image *image);
uint32_t skiac_image_get_height(skiac_image *image);
}

#endif // SKIA_CAPI_H
17 changes: 9 additions & 8 deletions src/image.rs
Expand Up @@ -3,8 +3,6 @@ use std::slice;

use napi::*;

use crate::sk::*;

#[derive(Debug, Clone)]
pub struct ImageData {
pub(crate) width: u32,
Expand Down Expand Up @@ -123,7 +121,7 @@ fn image_data_constructor(ctx: CallContext) -> Result<JsUndefined> {
pub struct Image {
pub(crate) width: u32,
pub(crate) height: u32,
data: Option<SurfaceDataRef>,
image: Option<crate::sk::Image>,
}

impl Image {
Expand All @@ -148,13 +146,13 @@ impl Image {

#[js_function]
fn image_constructor(ctx: CallContext) -> Result<JsUndefined> {
let image = Image {
let js_image = Image {
width: 0u32,
height: 0u32,
data: None,
image: None,
};
let mut this = ctx.this_unchecked::<JsObject>();
ctx.env.wrap(&mut this, image)?;
ctx.env.wrap(&mut this, js_image)?;
ctx.env.get_undefined()
}

Expand Down Expand Up @@ -187,7 +185,7 @@ fn get_src(ctx: CallContext) -> Result<JsUndefined> {
#[js_function(1)]
fn set_src(ctx: CallContext) -> Result<JsUndefined> {
let this = ctx.this_unchecked::<JsObject>();
let image = ctx.env.unwrap::<Image>(&this)?;
let js_image = ctx.env.unwrap::<Image>(&this)?;

let src_arg = ctx.get::<JsUnknown>(0)?;
let src_data_ab = unsafe { src_arg.cast::<JsTypedArray>() }.into_value()?;
Expand All @@ -200,7 +198,10 @@ fn set_src(ctx: CallContext) -> Result<JsUndefined> {
let length = src_data_ab.len();
println!("buffer length {}", length);

image.data.get_or_insert(SurfaceDataRef::new(src_data_ab.as_ptr() as *mut u8, length));
js_image.image.get_or_insert(crate::sk::Image::from_buffer(
src_data_ab.as_ptr() as *mut u8,
length,
));

ctx.env.get_undefined()
}
50 changes: 33 additions & 17 deletions src/sk.rs
Expand Up @@ -63,6 +63,12 @@ mod ffi {
_unused: [u8; 0],
}

#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct skiac_image {
_unused: [u8; 0],
}

#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct skiac_transform {
Expand Down Expand Up @@ -391,11 +397,13 @@ mod ffi {

pub fn skiac_mask_filter_destroy(mask_filter: *mut skiac_mask_filter);

pub fn skiac_data_create(ptr: *mut u8, size: usize) -> *mut skiac_data;
pub fn skiac_sk_data_destroy(c_data: *mut skiac_data);

pub fn skiac_image_make_from_buffer(ptr: *mut u8, size: usize) -> *mut skiac_image;

pub fn skiac_data_get_ptr(c_data: *mut skiac_data) -> *mut u8;
// pub fn skiac_image_get_width(image: *mut skiac_image) -> u32;

pub fn skiac_sk_data_destroy(c_data: *mut skiac_data);
// pub fn skiac_image_get_height(image: *mut skiac_image) -> u32;
}
}

Expand Down Expand Up @@ -1049,20 +1057,6 @@ impl<'a> Deref for SurfaceDataMut<'a> {
pub struct SurfaceDataRef(pub(crate) ffi::skiac_sk_data);

impl SurfaceDataRef {
pub fn new(ptr: *mut u8, size: usize) -> SurfaceDataRef {
unsafe {
let mut data_ref = SurfaceDataRef(ffi::skiac_sk_data {
ptr: ptr,
size: size,
data: ffi::skiac_data_create(ptr, size),
});
// update ptr from copied SkData
data_ref.0.ptr = ffi::skiac_data_get_ptr(data_ref.0.data);

data_ref
}
}

pub fn slice(&self) -> &'static [u8] {
unsafe { slice::from_raw_parts(self.0.ptr, self.0.size) }
}
Expand Down Expand Up @@ -2029,6 +2023,28 @@ impl Drop for MaskFilter {
}
}


#[derive(Debug)]
pub struct Image {
width: u32,
height: u32,
image: *mut ffi::skiac_image,
}

impl Image {
pub fn from_buffer(ptr: *mut u8, size: usize) -> Self {
unsafe {
let image = ffi::skiac_image_make_from_buffer(ptr, size);

Image {
width: 0,
height: 0,
image
}
}
}
}

#[inline(always)]
fn radians_to_degrees(rad: f32) -> f32 {
(rad / PI) * 180.0
Expand Down

0 comments on commit 3945321

Please sign in to comment.