From 582e4f4b2d6a2c43cac977bbadd0ec66c756c126 Mon Sep 17 00:00:00 2001 From: Armin Sander Date: Sat, 22 May 2021 09:25:03 +0200 Subject: [PATCH 01/14] m92: Update Skia --- README.md | 6 +++--- skia-bindings/Cargo.toml | 2 +- skia-bindings/skia | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9f837cb59..bc2c925f0 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ [![crates.io](https://img.shields.io/crates/v/skia-safe)](https://crates.io/crates/skia-safe) [![license](https://img.shields.io/crates/l/skia-safe)](LICENSE) [![Build Status](https://dev.azure.com/pragmatrix-github/rust-skia/_apis/build/status/rust-skia.rust-skia?branchName=master)](https://dev.azure.com/pragmatrix-github/rust-skia/_build/latest?definitionId=2&branchName=master) -Skia Submodule Status: chrome/m91 ([upstream changes][skia-upstream], [our changes][skia-ours]). +Skia Submodule Status: chrome/m92 ([upstream changes][skia-upstream], [our changes][skia-ours]). -[skia-upstream]: https://github.com/rust-skia/skia/compare/m91-0.39.3...google:chrome/m91 -[skia-ours]: https://github.com/google/skia/compare/chrome/m91...rust-skia:m91-0.39.3 +[skia-upstream]: https://github.com/rust-skia/skia/compare/m92-0.40.0...google:chrome/m92 +[skia-ours]: https://github.com/google/skia/compare/chrome/m92...rust-skia:m92-0.40.0 ## Goals diff --git a/skia-bindings/Cargo.toml b/skia-bindings/Cargo.toml index 90d110851..18636ff24 100644 --- a/skia-bindings/Cargo.toml +++ b/skia-bindings/Cargo.toml @@ -32,7 +32,7 @@ doctest = false # Metadata used from inside the packaged crate that defines where to download skia and depot_tools archives from. # Note: use short hashes here because of filesystem path size restrictions. [package.metadata] -skia = "m91-0.39.3" +skia = "m92-0.40.0" depot_tools = "a110bf6" [features] diff --git a/skia-bindings/skia b/skia-bindings/skia index 74276ea93..e59695d76 160000 --- a/skia-bindings/skia +++ b/skia-bindings/skia @@ -1 +1 @@ -Subproject commit 74276ea938c607ceeebad2812d20189f0eb48adb +Subproject commit e59695d762b97d12ec9b041ac6a6743f30a36e86 From 3dd076fba21b4bb2f69a2a2e931f386de27f1da8 Mon Sep 17 00:00:00 2001 From: Armin Sander Date: Sat, 22 May 2021 09:35:28 +0200 Subject: [PATCH 02/14] m92: Fix bindings compilation --- skia-bindings/src/bindings.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/skia-bindings/src/bindings.cpp b/skia-bindings/src/bindings.cpp index 60a43f043..7863d7dfa 100644 --- a/skia-bindings/src/bindings.cpp +++ b/skia-bindings/src/bindings.cpp @@ -88,7 +88,6 @@ // utils/ #include "include/utils/SkCamera.h" #include "include/utils/SkCustomTypeface.h" -#include "include/utils/SkInterpolator.h" #include "include/utils/SkNullCanvas.h" #include "include/utils/SkParsePath.h" #include "include/utils/SkShadowUtils.h" @@ -2280,6 +2279,7 @@ extern "C" SkColorFilter* C_SkOverdrawColorFilter_MakeWithSkColors(const SkColor extern "C" { +/* SkRuntimeEffect *C_SkRuntimeEffect_Make( const SkString *sksl, const SkRuntimeEffect::Options *options, @@ -2289,6 +2289,7 @@ SkRuntimeEffect *C_SkRuntimeEffect_Make( *error = r.errorText; return r.effect.release(); } +*/ SkShader *C_SkRuntimeEffect_makeShader(const SkRuntimeEffect *self, SkData *uniforms, SkShader **children, size_t childCount, const SkMatrix *localMatrix, bool isOpaque) { @@ -2326,6 +2327,7 @@ const SkRuntimeEffect::Uniform* C_SkRuntimeEffect_uniforms(const SkRuntimeEffect return &*uniforms.begin(); } +/* const SkString* C_SkRuntimeEffect_children(const SkRuntimeEffect* self, size_t* count) { auto children = self->children(); *count = children.count(); @@ -2337,6 +2339,7 @@ const SkRuntimeEffect::Varying* C_SkRuntimeEffect_varyings(const SkRuntimeEffect *count = varyings.count(); return &*varyings.begin(); } +*/ } @@ -2699,7 +2702,8 @@ C_SkCustomTypefaceBuilder_setGlyph3(SkCustomTypefaceBuilder *self, SkGlyphID gly self->setGlyph(glyph, advance, sp(picture)); } */ - + +/* extern "C" void C_SkInterpolator_destruct(SkInterpolator* self) { self->~SkInterpolator(); } @@ -2715,6 +2719,7 @@ extern "C" void C_SkInterpolator_setReset(SkInterpolator* self, bool reset) { extern "C" void C_SkInterpolator_setMirror(SkInterpolator* self, bool mirror) { self->setMirror(mirror); } +*/ extern "C" SkCanvas* C_SkMakeNullCanvas() { return SkMakeNullCanvas().release(); From 701ff90c49408a4e11fa8eb6eeb90341b0e7e936 Mon Sep 17 00:00:00 2001 From: Armin Sander Date: Sat, 22 May 2021 09:45:40 +0200 Subject: [PATCH 03/14] m92: Force skia-safe to compile --- skia-safe/src/core/path_effect.rs | 16 ++--- skia-safe/src/core/vertices.rs | 11 +++- skia-safe/src/effects/runtime_effect.rs | 85 ++++++++++++++----------- skia-safe/src/utils.rs | 2 +- skia-safe/src/utils/interpolator.rs | 3 + skia-safe/src/utils/parse_path.rs | 18 +++--- skia-safe/tests/send_sync.rs | 10 +-- 7 files changed, 83 insertions(+), 62 deletions(-) diff --git a/skia-safe/src/core/path_effect.rs b/skia-safe/src/core/path_effect.rs index 02437aabd..6bd03e760 100644 --- a/skia-safe/src/core/path_effect.rs +++ b/skia-safe/src/core/path_effect.rs @@ -148,14 +148,14 @@ impl PathEffect { } } - pub fn compute_fast_bounds(&self, src: impl AsRef) -> Rect { - let mut r: Rect = Rect::default(); - unsafe { - self.native() - .computeFastBounds(r.native_mut(), src.as_ref().native()) - }; - r - } + // pub fn compute_fast_bounds(&self, src: impl AsRef) -> Rect { + // let mut r: Rect = Rect::default(); + // unsafe { + // self.native() + // .computeFastBounds(r.native_mut(), src.as_ref().native()) + // }; + // r + // } // TODO: rename to to_points()? pub fn as_points( diff --git a/skia-safe/src/core/vertices.rs b/skia-safe/src/core/vertices.rs index 972483971..c2fcef1d1 100644 --- a/skia-safe/src/core/vertices.rs +++ b/skia-safe/src/core/vertices.rs @@ -1,9 +1,9 @@ use crate::{prelude::*, Color, Point, Rect}; use skia_bindings::{ - self as sb, SkPoint, SkVertices, SkVertices_Attribute, SkVertices_Attribute_Type, + self as sb, SkPoint, SkVertices, /* SkVertices_Attribute, SkVertices_Attribute_Type, */ SkVertices_Builder, }; -use std::{ffi::CStr, fmt, marker::PhantomData, os::raw::c_char, ptr, slice}; +use std::{/* ffi::CStr, */ fmt, /* marker::PhantomData, os::raw::c_char, */ ptr, slice}; #[deprecated(since = "0.29.0", note = "removed without replacement")] pub type BoneIndices = [u32; 4]; @@ -24,6 +24,8 @@ fn test_vertices_vertex_mode_naming() { let _ = VertexMode::Triangles; } +/* + #[repr(u8)] #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum AttributeType { @@ -46,6 +48,9 @@ fn test_attribute_usage_naming() { let _ = AttributeUsage::Vector; } +*/ + +/* #[repr(C)] #[derive(Copy, Clone, Eq, Debug)] pub struct Attribute<'a> { @@ -119,6 +124,8 @@ impl Attribute<'_> { } } +*/ + pub type Vertices = RCHandle; unsafe impl Send for Vertices {} unsafe impl Sync for Vertices {} diff --git a/skia-safe/src/effects/runtime_effect.rs b/skia-safe/src/effects/runtime_effect.rs index 593369efd..7543aef12 100644 --- a/skia-safe/src/effects/runtime_effect.rs +++ b/skia-safe/src/effects/runtime_effect.rs @@ -1,11 +1,11 @@ -use crate::{ - interop::{self, AsStr}, - prelude::*, - ColorFilter, Data, Matrix, Shader, -}; +use crate::{interop::AsStr, prelude::*, ColorFilter, Data, Matrix, Shader}; use skia_bindings::{ - self as sb, SkRefCntBase, SkRuntimeEffect, SkRuntimeEffect_Options, SkRuntimeEffect_Uniform, - SkRuntimeEffect_Varying, + self as sb, + SkRefCntBase, + SkRuntimeEffect, + SkRuntimeEffect_Options, + SkRuntimeEffect_Uniform, + // SkRuntimeEffect_Varying, }; use std::{ffi::CStr, fmt}; @@ -50,9 +50,9 @@ impl Uniform { uniform::Flags::from_bits(self.native().flags).unwrap() } - pub fn marker(&self) -> u32 { - self.native().marker - } + // pub fn marker(&self) -> u32 { + // self.native().marker + // } pub fn is_array(&self) -> bool { self.flags().contains(uniform::Flags::ARRAY) @@ -75,13 +75,15 @@ pub mod uniform { bitflags! { pub struct Flags : u32 { const ARRAY = sb::SkRuntimeEffect_Uniform_Flags_kArray_Flag as _; - const MARKER = sb::SkRuntimeEffect_Uniform_Flags_kMarker_Flag as _; - const MARKER_NORMALS = sb::SkRuntimeEffect_Uniform_Flags_kMarkerNormals_Flag as _; + // const MARKER = sb::SkRuntimeEffect_Uniform_Flags_kMarker_Flag as _; + // const MARKER_NORMALS = sb::SkRuntimeEffect_Uniform_Flags_kMarkerNormals_Flag as _; const SRGB_UNPREMUL = sb::SkRuntimeEffect_Uniform_Flags_kSRGBUnpremul_Flag as _; } } } +/* + pub type Varying = Handle; unsafe impl Send for Varying {} unsafe impl Sync for Varying {} @@ -111,6 +113,8 @@ impl Varying { } } +*/ + pub type RuntimeEffect = RCHandle; impl NativeRefCountedBase for SkRuntimeEffect { @@ -125,10 +129,15 @@ pub struct Options { impl NativeTransmutable for Options {} +/* pub fn new(sksl: impl AsRef) -> Result { new_with_options(sksl, None) } +*/ + +/* + pub fn new_with_options<'a>( sksl: impl AsRef, options: impl Into>, @@ -142,12 +151,14 @@ pub fn new_with_options<'a>( .ok_or_else(|| error.as_str().to_owned()) } +*/ + impl fmt::Debug for RuntimeEffect { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("RuntimeEffect") .field("uniform_size", &self.uniform_size()) .field("uniforms", &self.uniforms()) - .field("varyings", &self.varyings()) + // .field("varyings", &self.varyings()) .finish() } } @@ -237,22 +248,22 @@ impl RuntimeEffect { } } - pub fn children(&self) -> impl Iterator { - unsafe { - let mut count: usize = 0; - let ptr = sb::C_SkRuntimeEffect_children(self.native(), &mut count); - let slice = safer::from_raw_parts(ptr, count); - slice.iter().map(|str| str.as_str()) - } - } - - pub fn varyings(&self) -> &[Varying] { - unsafe { - let mut count: usize = 0; - let ptr = sb::C_SkRuntimeEffect_varyings(self.native(), &mut count); - safer::from_raw_parts(Varying::from_native_ptr(ptr), count) - } - } + // pub fn children(&self) -> impl Iterator { + // unsafe { + // let mut count: usize = 0; + // let ptr = sb::C_SkRuntimeEffect_children(self.native(), &mut count); + // let slice = safer::from_raw_parts(ptr, count); + // slice.iter().map(|str| str.as_str()) + // } + // } + + // pub fn varyings(&self) -> &[Varying] { + // unsafe { + // let mut count: usize = 0; + // let ptr = sb::C_SkRuntimeEffect_varyings(self.native(), &mut count); + // safer::from_raw_parts(Varying::from_native_ptr(ptr), count) + // } + // } #[deprecated(since = "0.35.0", note = "Use find_uniform()")] pub fn find_input(&self, name: impl AsRef) -> Option<&Uniform> { @@ -265,14 +276,14 @@ impl RuntimeEffect { .map(|ptr| Uniform::from_native_ref(unsafe { &*ptr })) } - pub fn find_child(&self, name: impl AsRef) -> Option { - unsafe { - self.native() - .findChild(name.as_ref().as_ptr()) - .try_into() - .ok() - } - } + // pub fn find_child(&self, name: impl AsRef) -> Option { + // unsafe { + // self.native() + // .findChild(name.as_ref().as_ptr()) + // .try_into() + // .ok() + // } + // } } // TODO: wrap SkRuntimeEffectBuilder, SkRuntimeShaderBuilder diff --git a/skia-safe/src/utils.rs b/skia-safe/src/utils.rs index 7daee94aa..9fdefcce8 100644 --- a/skia-safe/src/utils.rs +++ b/skia-safe/src/utils.rs @@ -5,7 +5,7 @@ mod custom_typeface; pub use custom_typeface::*; pub mod interpolator; -pub use interpolator::Interpolator; +// pub use interpolator::Interpolator; mod null_canvas; pub use null_canvas::*; diff --git a/skia-safe/src/utils/interpolator.rs b/skia-safe/src/utils/interpolator.rs index 935612482..d32ffea66 100644 --- a/skia-safe/src/utils/interpolator.rs +++ b/skia-safe/src/utils/interpolator.rs @@ -1,5 +1,6 @@ //! This wrapper combines SkInterpolatorBase and SkInterpolator into the type Interpolator. +/* use crate::{prelude::*, scalar, Point}; use skia_bindings::{self as sb, SkInterpolator, SkUnitCubicInterp}; use std::{fmt, time::Duration}; @@ -170,3 +171,5 @@ pub fn unit_cubic_interp(value: scalar, b: impl Into, c: impl Into let c = c.into(); unsafe { SkUnitCubicInterp(value, b.x, b.y, c.x, c.y) } } + +*/ diff --git a/skia-safe/src/utils/parse_path.rs b/skia-safe/src/utils/parse_path.rs index 884f8882a..527b6d25d 100644 --- a/skia-safe/src/utils/parse_path.rs +++ b/skia-safe/src/utils/parse_path.rs @@ -1,5 +1,5 @@ use crate::{ - interop, + // interop, prelude::{IfBoolSome, NativeAccess}, Path, }; @@ -12,19 +12,19 @@ pub fn from_svg(svg: impl AsRef) -> Option { unsafe { sb::SkParsePath_FromSVGString(str.as_ptr(), path.native_mut()) }.if_true_some(path) } -pub fn to_svg(path: &Path) -> String { - let mut svg = interop::String::default(); - unsafe { sb::SkParsePath_ToSVGString(path.native(), svg.native_mut()) }; +// pub fn to_svg(path: &Path) -> String { +// let mut svg = interop::String::default(); +// unsafe { sb::SkParsePath_ToSVGString(path.native(), svg.native_mut()) }; - svg.as_str().into() -} +// svg.as_str().into() +// } impl Path { pub fn from_svg(svg: impl AsRef) -> Option { from_svg(svg) } - pub fn to_svg(&self) -> String { - to_svg(self) - } + // pub fn to_svg(&self) -> String { + // to_svg(self) + // } } diff --git a/skia-safe/tests/send_sync.rs b/skia-safe/tests/send_sync.rs index 0e62fe0da..8277d986c 100644 --- a/skia-safe/tests/send_sync.rs +++ b/skia-safe/tests/send_sync.rs @@ -103,7 +103,7 @@ mod core { assert_impl_all!(typeface::LocalizedString: Send, Sync); assert_impl_all!(Typeface: Send, Sync); assert_not_impl_any!(typeface::LocalizedStringsIter: Send, Sync); - assert_not_impl_any!(vertices::Attribute: Send, Sync); + // assert_not_impl_any!(vertices::Attribute: Send, Sync); assert_impl_all!(Vertices: Send, Sync); assert_impl_all!(vertices::Builder: Send, Sync); // core/sampling_options.rs @@ -140,7 +140,7 @@ mod effects { use static_assertions::*; assert_impl_all!(runtime_effect::Uniform: Send, Sync); - assert_impl_all!(runtime_effect::Varying: Send, Sync); + // assert_impl_all!(runtime_effect::Varying: Send, Sync); assert_not_impl_any!(RuntimeEffect: Send, Sync); assert_impl_all!(runtime_effect::Options: Send, Sync); assert_impl_all!(image_filters::CropRect: Send, Sync); @@ -271,12 +271,12 @@ mod svg { } mod utils { - use skia_safe::utils::interpolator::TimeToT; + // use skia_safe::utils::interpolator::TimeToT; use skia_safe::utils::*; use static_assertions::*; assert_impl_all!(CustomTypefaceBuilder: Send, Sync); - assert_impl_all!(Interpolator: Send, Sync); - assert_impl_all!(TimeToT: Send, Sync); + // assert_impl_all!(Interpolator: Send, Sync); + // assert_impl_all!(TimeToT: Send, Sync); } pub mod assert { From a0dc2ad2390821070d8642b8984025039307e680 Mon Sep 17 00:00:00 2001 From: Armin Sander Date: Sat, 22 May 2021 12:54:37 +0200 Subject: [PATCH 04/14] m92: Update effects/ --- skia-bindings/src/bindings.cpp | 26 ++--- skia-safe/src/effects/runtime_effect.rs | 149 ++++++++++++------------ 2 files changed, 85 insertions(+), 90 deletions(-) diff --git a/skia-bindings/src/bindings.cpp b/skia-bindings/src/bindings.cpp index 7863d7dfa..57f74185d 100644 --- a/skia-bindings/src/bindings.cpp +++ b/skia-bindings/src/bindings.cpp @@ -2279,17 +2279,25 @@ extern "C" SkColorFilter* C_SkOverdrawColorFilter_MakeWithSkColors(const SkColor extern "C" { -/* -SkRuntimeEffect *C_SkRuntimeEffect_Make( +SkRuntimeEffect *C_SkRuntimeEffect_MakeForColorFilter( const SkString *sksl, const SkRuntimeEffect::Options *options, SkString *error) { - auto r = SkRuntimeEffect::Make(*sksl, *options); + auto r = SkRuntimeEffect::MakeForColorFilter(*sksl, *options); + *error = r.errorText; + return r.effect.release(); +} + +SkRuntimeEffect *C_SkRuntimeEffect_MakeForShader( + const SkString *sksl, + const SkRuntimeEffect::Options *options, + SkString *error) +{ + auto r = SkRuntimeEffect::MakeForShader(*sksl, *options); *error = r.errorText; return r.effect.release(); } -*/ SkShader *C_SkRuntimeEffect_makeShader(const SkRuntimeEffect *self, SkData *uniforms, SkShader **children, size_t childCount, const SkMatrix *localMatrix, bool isOpaque) { @@ -2327,20 +2335,12 @@ const SkRuntimeEffect::Uniform* C_SkRuntimeEffect_uniforms(const SkRuntimeEffect return &*uniforms.begin(); } -/* -const SkString* C_SkRuntimeEffect_children(const SkRuntimeEffect* self, size_t* count) { +const SkRuntimeEffect::Child* C_SkRuntimeEffect_children(const SkRuntimeEffect* self, size_t* count) { auto children = self->children(); *count = children.count(); return &*children.begin(); } -const SkRuntimeEffect::Varying* C_SkRuntimeEffect_varyings(const SkRuntimeEffect* self, size_t* count) { - auto varyings = self->varyings(); - *count = varyings.count(); - return &*varyings.begin(); -} -*/ - } // diff --git a/skia-safe/src/effects/runtime_effect.rs b/skia-safe/src/effects/runtime_effect.rs index 7543aef12..5ebcf809e 100644 --- a/skia-safe/src/effects/runtime_effect.rs +++ b/skia-safe/src/effects/runtime_effect.rs @@ -1,4 +1,9 @@ -use crate::{interop::AsStr, prelude::*, ColorFilter, Data, Matrix, Shader}; +use crate::{ + interop::{self, AsStr}, + prelude::*, + ColorFilter, Data, Matrix, Shader, +}; +use sb::SkRuntimeEffect_Child; use skia_bindings::{ self as sb, SkRefCntBase, @@ -50,10 +55,6 @@ impl Uniform { uniform::Flags::from_bits(self.native().flags).unwrap() } - // pub fn marker(&self) -> u32 { - // self.native().marker - // } - pub fn is_array(&self) -> bool { self.flags().contains(uniform::Flags::ARRAY) } @@ -75,45 +76,31 @@ pub mod uniform { bitflags! { pub struct Flags : u32 { const ARRAY = sb::SkRuntimeEffect_Uniform_Flags_kArray_Flag as _; - // const MARKER = sb::SkRuntimeEffect_Uniform_Flags_kMarker_Flag as _; - // const MARKER_NORMALS = sb::SkRuntimeEffect_Uniform_Flags_kMarkerNormals_Flag as _; const SRGB_UNPREMUL = sb::SkRuntimeEffect_Uniform_Flags_kSRGBUnpremul_Flag as _; } } } -/* +#[deprecated(since = "0.0.0", note = "Use Child instead")] +pub type Varying = Child; -pub type Varying = Handle; -unsafe impl Send for Varying {} -unsafe impl Sync for Varying {} +pub type Child = Handle; +unsafe impl Send for Child {} +unsafe impl Sync for Child {} -impl NativeDrop for SkRuntimeEffect_Varying { +impl NativeDrop for SkRuntimeEffect_Child { fn drop(&mut self) { - panic!("native type SkRuntimeEffect::Varying can't be owned by Rust"); + panic!("native type SkRuntimeEffect::Child can't be owned in Rust"); } } -impl fmt::Debug for Varying { +impl fmt::Debug for Child { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Varying") - .field("name", &self.name()) - .field("width", &self.width()) - .finish() - } -} - -impl Varying { - pub fn name(&self) -> &str { - self.native().name.as_str() - } - - pub fn width(&self) -> i32 { - self.native().width + self.native().fmt(f) } } -*/ +pub use sb::SkRuntimeEffect_Child_Type as ChildType; pub type RuntimeEffect = RCHandle; @@ -122,48 +109,63 @@ impl NativeRefCountedBase for SkRuntimeEffect { } #[repr(C)] -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct Options { pub force_no_inline: bool, + pub enforce_es2_restrictions: bool, } impl NativeTransmutable for Options {} -/* -pub fn new(sksl: impl AsRef) -> Result { - new_with_options(sksl, None) -} - -*/ - -/* - -pub fn new_with_options<'a>( - sksl: impl AsRef, - options: impl Into>, -) -> Result { - let str = interop::String::from_str(sksl); - let options = options.into().copied().unwrap_or_default(); - let mut error = interop::String::default(); - RuntimeEffect::from_ptr(unsafe { - sb::C_SkRuntimeEffect_Make(str.native(), options.native(), error.native_mut()) - }) - .ok_or_else(|| error.as_str().to_owned()) +impl Default for Options { + fn default() -> Self { + Options { + force_no_inline: false, + enforce_es2_restrictions: true, + } + } } -*/ - impl fmt::Debug for RuntimeEffect { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("RuntimeEffect") .field("uniform_size", &self.uniform_size()) .field("uniforms", &self.uniforms()) - // .field("varyings", &self.varyings()) .finish() } } impl RuntimeEffect { + pub fn make_for_color_filer<'a>( + sksl: impl AsRef, + options: impl Into>, + ) -> Result { + let str = interop::String::from_str(sksl); + let options = options.into().copied().unwrap_or_default(); + let mut error = interop::String::default(); + RuntimeEffect::from_ptr(unsafe { + sb::C_SkRuntimeEffect_MakeForColorFilter( + str.native(), + options.native(), + error.native_mut(), + ) + }) + .ok_or_else(|| error.to_string()) + } + + pub fn make_for_shader<'a>( + sksl: impl AsRef, + options: impl Into>, + ) -> Result { + let str = interop::String::from_str(sksl); + let options = options.into().copied().unwrap_or_default(); + let mut error = interop::String::default(); + RuntimeEffect::from_ptr(unsafe { + sb::C_SkRuntimeEffect_MakeForShader(str.native(), options.native(), error.native_mut()) + }) + .ok_or_else(|| error.to_string()) + } + pub fn make_shader<'a>( &self, uniforms: impl Into, @@ -248,22 +250,13 @@ impl RuntimeEffect { } } - // pub fn children(&self) -> impl Iterator { - // unsafe { - // let mut count: usize = 0; - // let ptr = sb::C_SkRuntimeEffect_children(self.native(), &mut count); - // let slice = safer::from_raw_parts(ptr, count); - // slice.iter().map(|str| str.as_str()) - // } - // } - - // pub fn varyings(&self) -> &[Varying] { - // unsafe { - // let mut count: usize = 0; - // let ptr = sb::C_SkRuntimeEffect_varyings(self.native(), &mut count); - // safer::from_raw_parts(Varying::from_native_ptr(ptr), count) - // } - // } + pub fn children(&self) -> &[Child] { + unsafe { + let mut count: usize = 0; + let ptr = sb::C_SkRuntimeEffect_children(self.native(), &mut count); + safer::from_raw_parts(Child::from_native_ptr(ptr), count) + } + } #[deprecated(since = "0.35.0", note = "Use find_uniform()")] pub fn find_input(&self, name: impl AsRef) -> Option<&Uniform> { @@ -276,14 +269,11 @@ impl RuntimeEffect { .map(|ptr| Uniform::from_native_ref(unsafe { &*ptr })) } - // pub fn find_child(&self, name: impl AsRef) -> Option { - // unsafe { - // self.native() - // .findChild(name.as_ref().as_ptr()) - // .try_into() - // .ok() - // } - // } + pub fn find_child(&self, name: impl AsRef) -> Option<&Child> { + unsafe { self.native().findChild(name.as_ref().as_ptr()) } + .into_option() + .map(|ptr| Child::from_native_ref(unsafe { &*ptr })) + } } // TODO: wrap SkRuntimeEffectBuilder, SkRuntimeShaderBuilder @@ -296,4 +286,9 @@ mod tests { fn options_layout() { super::Options::test_layout() } + + #[test] + fn test_child_type_naming() { + let _ = super::ChildType::ColorFilter; + } } From b31776e7e52987b5fdc3c86135b4b3138530c217 Mon Sep 17 00:00:00 2001 From: Armin Sander Date: Sat, 22 May 2021 13:30:05 +0200 Subject: [PATCH 05/14] m92: Update core/canvas.rs --- skia-safe/src/core/canvas.rs | 146 ++++++++++++++++++++++++++++++++++- 1 file changed, 143 insertions(+), 3 deletions(-) diff --git a/skia-safe/src/core/canvas.rs b/skia-safe/src/core/canvas.rs index 813074b51..593bd0e95 100644 --- a/skia-safe/src/core/canvas.rs +++ b/skia-safe/src/core/canvas.rs @@ -2,9 +2,9 @@ use crate::gpu; use crate::{ prelude::*, scalar, u8cpu, Bitmap, BlendMode, ClipOp, Color, Color4f, Data, Drawable, - FilterMode, Font, IPoint, IRect, ISize, Image, ImageFilter, ImageInfo, Matrix, Paint, Path, - Picture, Pixmap, Point, QuickReject, RRect, Rect, Region, SamplingOptions, Shader, Surface, - SurfaceProps, TextBlob, TextEncoding, Vector, Vertices, M44, + FilterMode, Font, GlyphId, IPoint, IRect, ISize, Image, ImageFilter, ImageInfo, Matrix, Paint, + Path, Picture, Pixmap, Point, QuickReject, RRect, RSXform, Rect, Region, SamplingOptions, + Shader, Surface, SurfaceProps, TextBlob, TextEncoding, Vector, Vertices, M44, }; use skia_bindings as sb; use skia_bindings::{ @@ -165,6 +165,24 @@ pub struct TopLayerPixels<'a> { pub origin: IPoint, } +/// Used to pass either a slice of [`Point`] or [`RSXform`] to [`Canvas::draw_glyphs_at`]. +pub enum GlyphPositions<'a> { + Points(&'a [Point]), + RSXforms(&'a [RSXform]), +} + +impl<'a> From<&'a [Point]> for GlyphPositions<'a> { + fn from(points: &'a [Point]) -> Self { + Self::Points(points) + } +} + +impl<'a> From<&'a [RSXform]> for GlyphPositions<'a> { + fn from(rs_xforms: &'a [RSXform]) -> Self { + Self::RSXforms(rs_xforms) + } +} + /// [`Canvas`] provides an interface for drawing, and how the drawing is clipped and transformed. /// [`Canvas`] contains a stack of [`Matrix`] and clip values. /// @@ -1749,6 +1767,128 @@ impl Canvas { self } + /// Draws glyphs at positions relative to origin styled with font and paint with + /// supporting utf8 and cluster information. + /// + /// This function draw glyphs at the given positions relative to the given origin. + /// It does not perform typeface fallback for glyphs not found in the SkTypeface in font. + /// + /// The drawing obeys the current transform matrix and clipping. + /// + /// All elements of paint: [`crate::PathEffect`], [`crate::MaskFilter`], [`Shader`], + /// [`crate::ColorFilter`], and [`ImageFilter`]; apply to text. By default, draws filled black + /// glyphs. + /// + /// - `count` number of glyphs to draw + /// - `glyphs` the array of glyphIDs to draw + /// - `positions` where to draw each glyph relative to origin + /// - `clusters` array of size count of cluster information + /// - `utf8_text` utf8text supporting information for the glyphs + /// - `origin` the origin of all the positions + /// - `font` typeface, text size and so, used to describe the text + /// - `paint` blend, color, and so on, used to draw + #[allow(clippy::too_many_arguments)] + pub fn draw_glyphs_utf8( + &mut self, + glyphs: &[GlyphId], + positions: &[Point], + clusters: &[u32], + utf8_text: impl AsRef, + origin: impl Into, + font: &Font, + paint: &Paint, + ) { + let count = glyphs.len(); + if count == 0 { + return; + } + assert_eq!(positions.len(), count); + assert_eq!(clusters.len(), count); + let utf8_text = utf8_text.as_ref().as_bytes(); + let origin = origin.into(); + unsafe { + self.native_mut().drawGlyphs( + count.try_into().unwrap(), + glyphs.as_ptr(), + positions.native().as_ptr(), + clusters.as_ptr(), + utf8_text.len().try_into().unwrap(), + utf8_text.as_ptr() as _, + origin.into_native(), + font.native(), + paint.native(), + ) + } + } + + /// Draws count glyphs, at positions relative to origin styled with font and paint. + /// + /// This function draw glyphs at the given positions relative to the given origin. + /// It does not perform typeface fallback for glyphs not found in the SkTypeface in font. + /// + /// The drawing obeys the current transform matrix and clipping. + /// + /// All elements of paint: [`crate::PathEffect`], [`crate::MaskFilter`], [`Shader`], + /// [`crate::ColorFilter`], and [`ImageFilter`]; apply to text. By default, draws filled black + /// glyphs. + /// + /// - `count` number of glyphs to draw + /// - `glyphs` the array of glyphIDs to draw + /// - `positions` where to draw each glyph relative to origin, either a `&[Point]` or + /// `&[RSXform]` slice + /// - `origin` the origin of all the positions + /// - `font` typeface, text size and so, used to describe the text + /// - `paint` blend, color, and so on, used to draw + pub fn draw_glyphs_at<'a>( + &mut self, + glyphs: &[GlyphId], + positions: impl Into>, + origin: impl Into, + font: &Font, + paint: &Paint, + ) { + let count = glyphs.len(); + if count == 0 { + return; + } + let positions: GlyphPositions = positions.into(); + let origin = origin.into(); + + let glyphs = glyphs.as_ptr(); + let origin = origin.into_native(); + let font = font.native(); + let paint = paint.native(); + + match positions { + GlyphPositions::Points(points) => { + assert_eq!(points.len(), count); + unsafe { + self.native_mut().drawGlyphs1( + count.try_into().unwrap(), + glyphs, + points.native().as_ptr(), + origin, + font, + paint, + ) + } + } + GlyphPositions::RSXforms(xforms) => { + assert_eq!(xforms.len(), count); + unsafe { + self.native_mut().drawGlyphs2( + count.try_into().unwrap(), + glyphs, + xforms.native().as_ptr(), + origin, + font, + paint, + ) + } + } + } + } + /// Draws [`TextBlob`] blob at `(origin.x, origin.y)`, using clip, [`Matrix`], and [`Paint`] /// paint. /// From d0c2e0de4d37bdf031122d4b62f21c7f7742b3b1 Mon Sep 17 00:00:00 2001 From: Armin Sander Date: Mon, 24 May 2021 12:50:16 +0200 Subject: [PATCH 06/14] Rerun the build when bindings.h has changed --- skia-bindings/build_support/skia.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/skia-bindings/build_support/skia.rs b/skia-bindings/build_support/skia.rs index a99b3a5a7..f7fa9c468 100644 --- a/skia-bindings/build_support/skia.rs +++ b/skia-bindings/build_support/skia.rs @@ -189,6 +189,9 @@ pub struct FinalBuildConfiguration { /// the BuildConfiguration). pub definitions: Definitions, + /// The binding headers that are used. + pub binding_headers: Vec, + /// The binding source files to compile. pub binding_sources: Vec, @@ -421,6 +424,8 @@ impl FinalBuildConfiguration { files }; + let binding_headers = vec!["src/bindings.h".into()]; + let binding_sources = { let mut sources: Vec = vec!["src/bindings.cpp".into()]; if features.gl { @@ -450,6 +455,7 @@ impl FinalBuildConfiguration { gn_args, ninja_files, definitions: build.definitions.clone(), + binding_headers, binding_sources, use_system_libraries, } @@ -812,6 +818,10 @@ fn generate_bindings(build: &FinalBuildConfiguration, output_directory: &Path) { let mut cc_build = Build::new(); + for header in &build.binding_headers { + cargo::rerun_if_changed(header.to_str().unwrap()); + } + for source in &build.binding_sources { cc_build.file(source); let source = source.to_str().unwrap(); From e596f07c3a1571341c8c39b5585756212c2e7bb7 Mon Sep 17 00:00:00 2001 From: Armin Sander Date: Mon, 24 May 2021 12:51:16 +0200 Subject: [PATCH 07/14] Use VecSink to simplify passing std::vectors from C++ to Rust --- skia-bindings/src/bindings.cpp | 16 +- skia-bindings/src/bindings.h | 23 ++- skia-bindings/src/paragraph.cpp | 106 +++--------- skia-bindings/src/shaper.cpp | 7 +- skia-safe/src/core/font.rs | 34 +++- skia-safe/src/interop.rs | 12 +- skia-safe/src/interop/cpp.rs | 50 ++++++ .../src/modules/paragraph/font_collection.rs | 46 ++--- skia-safe/src/modules/paragraph/metrics.rs | 10 +- skia-safe/src/modules/paragraph/paragraph.rs | 158 +++++++----------- skia-safe/src/modules/paragraph/text_style.rs | 18 +- skia-safe/src/modules/shaper.rs | 6 +- skia-safe/src/prelude.rs | 17 +- 13 files changed, 246 insertions(+), 257 deletions(-) create mode 100644 skia-safe/src/interop/cpp.rs diff --git a/skia-bindings/src/bindings.cpp b/skia-bindings/src/bindings.cpp index 57f74185d..aa6cbdb28 100644 --- a/skia-bindings/src/bindings.cpp +++ b/skia-bindings/src/bindings.cpp @@ -1282,6 +1282,10 @@ extern "C" void C_SkFont_ConstructFromTypefaceWithSizeScaleAndSkew(SkFont* unini new(uninitialized) SkFont(sp(typeface), size, scaleX, skewX); } +extern "C" void C_SkFont_destruct(SkFont* self) { + self->~SkFont(); +} + extern "C" bool C_SkFont_Equals(const SkFont* self, const SkFont* other) { return *self == *other; } @@ -1306,8 +1310,16 @@ extern "C" void C_SkFont_setTypeface(SkFont* self, SkTypeface* tf) { self->setTypeface(sp(tf)); } -extern "C" void C_SkFont_destruct(SkFont* self) { - self->~SkFont(); +extern "C" void C_SkFont_getIntercepts( + const SkFont* self, + const SkGlyphID glyphs[], + int count, + const SkPoint pos[], + SkScalar top, SkScalar bottom, + const SkPaint* paint, + VecSink* vs) { + auto r = self->getIntercepts(glyphs, count, pos, top, bottom, paint); + vs->set(r); } // diff --git a/skia-bindings/src/bindings.h b/skia-bindings/src/bindings.h index 0bb67c27b..4867066e6 100644 --- a/skia-bindings/src/bindings.h +++ b/skia-bindings/src/bindings.h @@ -15,7 +15,28 @@ inline sk_sp sp(T* pt) { return sk_sp(pt); } -// Used in textlayout::Paragraph::findTypefaces() +extern "C" struct TraitObject { + void* data; + void* vtable; +}; + +/// A VecSink is passed from Rust to C++ for receiving a slice of values. +template struct VecSink { + TraitObject fn_trait; + void (*set_fn)(T *, size_t, TraitObject); + + void set(T* ptr, size_t len) { + set_fn(ptr, len, fn_trait); + } + + void set(std::vector& v) { + if (v.empty()) { + set_fn(nullptr, 0, fn_trait); + } else { + set_fn(v.data(), v.size(), fn_trait); + } + } +}; struct SkStrings { std::vector strings; diff --git a/skia-bindings/src/paragraph.cpp b/skia-bindings/src/paragraph.cpp index 0130434fb..f7ec23d71 100644 --- a/skia-bindings/src/paragraph.cpp +++ b/skia-bindings/src/paragraph.cpp @@ -22,32 +22,6 @@ using namespace skia::textlayout; // FontCollection.h // -struct Typefaces { - std::vector> typefaces; -}; - -extern "C" { - void C_Typefaces_construct(Typefaces* uninitialized) { - new(uninitialized)Typefaces(); - } - - void C_Typefaces_destruct(Typefaces* self) { - self->~Typefaces(); - } - - size_t C_Typefaces_count(const Typefaces* faces) { - return faces->typefaces.size(); - } - - SkTypeface* C_Typefaces_get(const Typefaces* faces, size_t i) { - return faces->typefaces[i].get(); - } - - SkTypeface* C_Typefaces_release(Typefaces* faces, size_t i) { - return faces->typefaces[i].release(); - } -} - extern "C" { FontCollection* C_FontCollection_new() { return new FontCollection(); @@ -81,9 +55,9 @@ extern "C" { return self->getFallbackManager().release(); } - void C_FontCollection_findTypefaces(FontCollection* self, const SkStrings* familyNames, SkFontStyle fontStyle, Typefaces* typefaces) { + void C_FontCollection_findTypefaces(FontCollection* self, const SkStrings* familyNames, SkFontStyle fontStyle, VecSink>* typefaces) { auto tfs = self->findTypefaces(familyNames->strings, fontStyle); - typefaces->typefaces = std::move(tfs); + typefaces->set(tfs); } SkTypeface* C_FontCollection_defaultFallback(FontCollection* self, SkUnichar unicode, SkFontStyle fontStyle, const SkString* locale) { @@ -215,37 +189,6 @@ extern "C" { // Paragraph.h // -struct TextBoxes { - std::vector textBoxes; -}; - -extern "C" { - void C_TextBoxes_destruct(TextBoxes* self) { - self->~TextBoxes(); - } - - const TextBox* C_TextBoxes_ptr_count(const TextBoxes* boxes, size_t* count) { - *count = boxes->textBoxes.size(); - return &boxes->textBoxes.front(); - } -} - -struct LineMetricsVector { - std::vector lineMetrics; -}; - -extern "C" { - void C_LineMetricsVector_destruct(LineMetricsVector* self) { - self->~LineMetricsVector(); - } - - const LineMetrics* C_LineMetricsVector_ptr_count(const LineMetricsVector* metrics, size_t* count) { - *count = metrics->lineMetrics.size(); - return &metrics->lineMetrics.front(); - } -} - - extern "C" { void C_Paragraph_delete(Paragraph* self) { delete self; @@ -260,14 +203,14 @@ extern "C" { } void C_Paragraph_getRectsForRange(Paragraph *self, unsigned start, unsigned end, RectHeightStyle rectHeightStyle, - RectWidthStyle rectWidthStyle, TextBoxes* uninitialized) { + RectWidthStyle rectWidthStyle, VecSink* textBoxes) { auto v = self->getRectsForRange(start, end, rectHeightStyle, rectWidthStyle); - new(uninitialized) TextBoxes{std::move(v)}; + textBoxes->set(v); } - void C_Paragraph_getRectsForPlaceholders(Paragraph* self, TextBoxes* uninitialized) { + void C_Paragraph_getRectsForPlaceholders(Paragraph* self, VecSink* result) { auto v = self->getRectsForPlaceholders(); - new(uninitialized) TextBoxes{std::move(v)}; + result->set(v); } void C_Paragraph_getGlyphPositionAtCoordinate(Paragraph* self, SkScalar x, SkScalar y, PositionWithAffinity* position) { @@ -280,11 +223,12 @@ extern "C" { range[1] = sk_range.end; } - void C_Paragraph_getLineMetrics(Paragraph* self, LineMetricsVector* uninitialized) { - auto v = new(uninitialized) LineMetricsVector(); - self->getLineMetrics(v->lineMetrics); + void C_Paragraph_getLineMetrics(Paragraph* self, VecSink* result) { + std::vector vec; + self->getLineMetrics(vec); + result->set(vec); } - + size_t C_Paragraph_lineNumber(Paragraph* self) { return self->lineNumber(); } @@ -363,6 +307,11 @@ extern "C" { self->~TextStyle(); } + const TextShadow* C_TextStyle_getShadows(const std::vector* self, size_t* len) { + *len = self->size(); + return len != 0 ? self->data() : nullptr; + } + void C_TextStyle_addShadow(TextStyle* self, const TextShadow* shadow) { self->addShadow(*shadow); } @@ -371,6 +320,11 @@ extern "C" { self->resetShadows(); } + const FontFeature* C_TextStyle_getFontFeatures(const std::vector* self, size_t* len) { + *len = self->size(); + return len != 0 ? self->data() : nullptr; + } + void C_TextStyle_addFontFeature(TextStyle* self, const SkString* fontFeature, int value) { self->addFontFeature(*fontFeature, value); } @@ -394,24 +348,6 @@ extern "C" { } } -struct FontFeatures { - std::vector fontFeatures; -}; - -extern "C" const FontFeature *C_FontFeatures_ptr_count(const FontFeatures *features, size_t *count) { - *count = features->fontFeatures.size(); - return &features->fontFeatures.front(); -} - -struct TextShadows { - std::vector textShadows; -}; - -extern "C" const TextShadow *C_TextShadows_ptr_count(const TextShadows *shadows, size_t *count) { - *count = shadows->textShadows.size(); - return &shadows->textShadows.front(); -} - // // TypefaceFontProvider // diff --git a/skia-bindings/src/shaper.cpp b/skia-bindings/src/shaper.cpp index 90f2c2177..5dfa29d8f 100644 --- a/skia-bindings/src/shaper.cpp +++ b/skia-bindings/src/shaper.cpp @@ -2,6 +2,8 @@ #define SK_SHAPER_HARFBUZZ_AVAILABLE #endif +#include "bindings.h" + #include "modules/skshaper/include/SkShaper.h" #include "include/core/SkFontMgr.h" @@ -113,11 +115,6 @@ extern "C" void C_SkShaper_RunHandler_delete(SkShaper::RunHandler* self) { delete self; } -extern "C" struct TraitObject { - void* data; - void* vtable; -}; - namespace RunHandler { extern "C" typedef void (*BeginLine)(TraitObject); extern "C" typedef void (*RunInfo)(TraitObject, const SkShaper::RunHandler::RunInfo*); diff --git a/skia-safe/src/core/font.rs b/skia-safe/src/core/font.rs index 44c091bf4..6f7fbed5c 100644 --- a/skia-safe/src/core/font.rs +++ b/skia-safe/src/core/font.rs @@ -1,10 +1,8 @@ -use crate::prelude::*; use crate::{ - scalar, FontHinting, FontMetrics, GlyphId, Paint, Path, Point, Rect, TextEncoding, Typeface, - Unichar, + interop::VecSink, prelude::*, scalar, FontHinting, FontMetrics, GlyphId, Paint, Path, Point, + Rect, TextEncoding, Typeface, Unichar, }; -use skia_bindings as sb; -use skia_bindings::{SkFont, SkFont_PrivFlags}; +use skia_bindings::{self as sb, SkFont, SkFont_PrivFlags}; use std::{fmt, ptr}; pub use skia_bindings::SkFont_Edging as Edging; @@ -391,6 +389,32 @@ impl Font { } } + pub fn get_intercepts<'a>( + &self, + glyphs: &[GlyphId], + pos: &[Point], + (top, bottom): (scalar, scalar), + paint: impl Into>, + ) -> Vec { + assert_eq!(glyphs.len(), pos.len()); + let count = glyphs.len().try_into().unwrap(); + let mut r: Vec = Vec::new(); + let mut set = |scalars: &[scalar]| r = scalars.to_vec(); + unsafe { + sb::C_SkFont_getIntercepts( + self.native(), + glyphs.as_ptr(), + count, + pos.native().as_ptr(), + top, + bottom, + paint.into().native_ptr_or_null(), + VecSink::new(&mut set).native_mut(), + ); + } + r + } + pub fn get_path(&self, glyph_id: GlyphId) -> Option { let mut path = Path::default(); unsafe { self.native().getPath(glyph_id, path.native_mut()) }.if_true_some(path) diff --git a/skia-safe/src/interop.rs b/skia-safe/src/interop.rs index 7ca8db31a..e2c35008a 100644 --- a/skia-safe/src/interop.rs +++ b/skia-safe/src/interop.rs @@ -1,12 +1,14 @@ -/// Simple Skia types that are not exported and used to -/// to marshal between Rust and Skia types only. +/// Skia and C++ types that are used to to marshal between Rust and C++. +mod cpp; +pub use cpp::*; + mod stream; -pub(crate) use self::stream::*; +pub use self::stream::*; mod string; -pub(crate) use self::string::*; +pub use self::string::*; #[cfg(feature = "textlayout")] mod strings; #[cfg(feature = "textlayout")] -pub(crate) use self::strings::*; +pub use self::strings::*; diff --git a/skia-safe/src/interop/cpp.rs b/skia-safe/src/interop/cpp.rs new file mode 100644 index 000000000..583eafed1 --- /dev/null +++ b/skia-safe/src/interop/cpp.rs @@ -0,0 +1,50 @@ +use crate::prelude::safer; +use sb::TraitObject; +use skia_bindings as sb; +use std::{marker::PhantomData, mem}; + +/// A sink / receiver for array data that is copied from C++ to a Rust [`Vec`]. +#[derive(Debug)] +pub struct VecSink<'a, T> { + sink: sb::VecSink, + pd: PhantomData<&'a mut Vec>, +} + +impl VecSink<'_, T> { + /// Create a new sink that calls back into the closure given. + pub fn new(v: &mut dyn FnMut(&[T])) -> VecSink { + VecSink { + sink: sb::VecSink { + fn_trait: unsafe { mem::transmute(v) }, + set_fn: Some(Self::set_fn), + _phantom_0: PhantomData, + }, + pd: PhantomData, + } + } + + pub fn new_mut(v: &mut dyn FnMut(&mut [T])) -> VecSink { + VecSink { + sink: sb::VecSink { + fn_trait: unsafe { mem::transmute(v) }, + set_fn: Some(Self::set_fn_mut), + _phantom_0: PhantomData, + }, + pd: PhantomData, + } + } + + pub fn native_mut(&mut self) -> &mut sb::VecSink { + &mut self.sink + } + + unsafe extern "C" fn set_fn(ptr: *mut T, len: usize, rust_fn: TraitObject) { + let rust_fn: &mut dyn FnMut(&[T]) = mem::transmute(rust_fn); + (rust_fn)(safer::from_raw_parts(ptr, len)); + } + + unsafe extern "C" fn set_fn_mut(ptr: *mut T, len: usize, rust_fn: TraitObject) { + let rust_fn: &mut dyn FnMut(&mut [T]) = mem::transmute(rust_fn); + (rust_fn)(safer::from_raw_parts_mut(ptr, len)); + } +} diff --git a/skia-safe/src/modules/paragraph/font_collection.rs b/skia-safe/src/modules/paragraph/font_collection.rs index a76ad4565..4199d64bb 100644 --- a/skia-safe/src/modules/paragraph/font_collection.rs +++ b/skia-safe/src/modules/paragraph/font_collection.rs @@ -1,11 +1,11 @@ use crate::{ - interop::{self, FromStrs}, + interop::{self, FromStrs, VecSink}, prelude::*, textlayout::ParagraphCache, FontMgr, FontStyle, Typeface, Unichar, }; use skia_bindings::{self as sb, skia_textlayout_FontCollection}; -use std::{ffi, fmt}; +use std::{ffi, fmt, ptr}; pub type FontCollection = RCHandle; @@ -110,16 +110,28 @@ impl FontCollection { font_style: FontStyle, ) -> Vec { let family_names = interop::Strings::from_strs(family_names); - let mut typefaces = Typefaces::new(); + + let mut typefaces: Vec = Vec::new(); + let mut set_typefaces = |tfs: &mut [sb::sk_sp]| { + typefaces = tfs + .iter_mut() + .filter_map(|sp| { + let ptr = sp.fPtr; + sp.fPtr = ptr::null_mut(); + Typeface::from_ptr(ptr) + }) + .collect() + }; + unsafe { sb::C_FontCollection_findTypefaces( self.native_mut(), family_names.native(), font_style.into_native(), - typefaces.native_mut(), + VecSink::new_mut(&mut set_typefaces).native_mut(), ) }; - typefaces.into_vec() + typefaces } pub fn default_fallback_char( @@ -172,30 +184,6 @@ impl FontCollection { } } -type Typefaces = Handle; - -impl NativeDrop for sb::Typefaces { - fn drop(&mut self) { - unsafe { sb::C_Typefaces_destruct(self) } - } -} - -impl Typefaces { - pub fn new() -> Self { - Typefaces::construct(|tf| unsafe { sb::C_Typefaces_construct(tf) }) - } - - pub fn into_vec(mut self) -> Vec { - let count = unsafe { sb::C_Typefaces_count(self.native()) }; - (0..count) - .map(|i| { - Typeface::from_ptr(unsafe { sb::C_Typefaces_release(self.native_mut(), i) }) - .unwrap() - }) - .collect() - } -} - #[cfg(test)] mod tests { use crate::prelude::*; diff --git a/skia-safe/src/modules/paragraph/metrics.rs b/skia-safe/src/modules/paragraph/metrics.rs index 906c0f314..a0a47eca2 100644 --- a/skia-safe/src/modules/paragraph/metrics.rs +++ b/skia-safe/src/modules/paragraph/metrics.rs @@ -3,7 +3,7 @@ use skia_bindings::{self as sb, skia_textlayout_LineMetrics, skia_textlayout_Sty use std::{marker, mem, ops::Range, ptr}; #[repr(C)] -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct StyleMetrics<'a> { pub text_style: &'a TextStyle, pub font_metrics: FontMetrics, @@ -26,7 +26,7 @@ impl<'a> StyleMetrics<'a> { } #[repr(C)] -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct LineMetrics<'a> { pub start_index: usize, pub end_index: usize, @@ -46,8 +46,10 @@ pub struct LineMetrics<'a> { pd: marker::PhantomData<&'a StyleMetrics<'a>>, } +impl NativeTransmutable for LineMetrics<'_> {} + // Internal Line Metrics mirror to compute what the map takes up space. -// In case this computation is incorrect, the NativeTransmutable test below will fail. +// If the size of the structure does not match, the NativeTransmutable test below will fail. #[repr(C)] struct LMInternal { start_end: [usize; 4], @@ -56,8 +58,6 @@ struct LMInternal { line_number: usize, } -impl NativeTransmutable for LineMetrics<'_> {} - #[test] fn test_line_metrics_layout() { LineMetrics::test_layout(); diff --git a/skia-safe/src/modules/paragraph/paragraph.rs b/skia-safe/src/modules/paragraph/paragraph.rs index eb49fbaeb..ce15e093a 100644 --- a/skia-safe/src/modules/paragraph/paragraph.rs +++ b/skia-safe/src/modules/paragraph/paragraph.rs @@ -1,10 +1,7 @@ use super::{PositionWithAffinity, RectHeightStyle, RectWidthStyle, TextBox}; -use crate::{prelude::*, scalar, textlayout::LineMetrics, Canvas, Point}; +use crate::{interop::VecSink, prelude::*, scalar, textlayout::LineMetrics, Canvas, Point}; use skia_bindings as sb; -use std::{ - fmt, - ops::{Index, Range}, -}; +use std::{fmt, ops::Range}; pub type Paragraph = RefHandle; unsafe impl Send for Paragraph {} @@ -79,23 +76,48 @@ impl Paragraph { range: Range, rect_height_style: RectHeightStyle, rect_width_style: RectWidthStyle, - ) -> TextBoxes { - TextBoxes::construct(|tb| unsafe { + ) -> Vec { + let mut result: Vec = Vec::new(); + + let mut set_tb = |tbs: &[sb::skia_textlayout_TextBox]| { + result = tbs + .iter() + .map(|tb| TextBox::from_native_ref(tb)) + .cloned() + .collect(); + }; + + unsafe { sb::C_Paragraph_getRectsForRange( self.native_mut_force(), range.start.try_into().unwrap(), range.end.try_into().unwrap(), rect_height_style, rect_width_style, - tb, - ) - }) + VecSink::new(&mut set_tb).native_mut(), + ); + } + result } - pub fn get_rects_for_placeholders(&self) -> TextBoxes { - TextBoxes::construct(|tb| unsafe { - sb::C_Paragraph_getRectsForPlaceholders(self.native_mut_force(), tb) - }) + pub fn get_rects_for_placeholders(&self) -> Vec { + let mut result: Vec = Vec::new(); + + let mut set_tb = |tbs: &[sb::skia_textlayout_TextBox]| { + result = tbs + .iter() + .map(|tb| TextBox::from_native_ref(tb)) + .cloned() + .collect(); + }; + + unsafe { + sb::C_Paragraph_getRectsForPlaceholders( + self.native_mut_force(), + VecSink::new(&mut set_tb).native_mut(), + ) + } + result } pub fn get_glyph_position_at_coordinate(&self, p: impl Into) -> PositionWithAffinity { @@ -115,105 +137,39 @@ impl Paragraph { range[0]..range[1] } - pub fn get_line_metrics(&self) -> LineMetricsVector { - Handle::::construct(|lmv| unsafe { - sb::C_Paragraph_getLineMetrics(self.native_mut_force(), lmv) - }) - .borrows(self) - } - - pub fn line_number(&self) -> usize { - unsafe { sb::C_Paragraph_lineNumber(self.native_mut_force()) } - } - - pub fn mark_dirty(&mut self) { - unsafe { sb::C_Paragraph_markDirty(self.native_mut()) } - } -} - -pub type TextBoxes = Handle; - -impl NativeDrop for sb::TextBoxes { - fn drop(&mut self) { - unsafe { sb::C_TextBoxes_destruct(self) } - } -} - -impl Index for TextBoxes { - type Output = TextBox; - fn index(&self, index: usize) -> &Self::Output { - &self.as_slice()[index] - } -} - -impl AsRef<[TextBox]> for TextBoxes { - fn as_ref(&self) -> &[TextBox] { - self.as_slice() - } -} - -impl fmt::Debug for TextBoxes { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("TextBoxes").field(&self.as_slice()).finish() - } -} - -impl TextBoxes { - pub fn iter(&self) -> impl Iterator { - self.as_slice().iter() - } + pub fn get_line_metrics(&self) -> Vec { + let mut result: Vec = Vec::new(); + let mut set_lm = |lms: &[sb::skia_textlayout_LineMetrics]| { + result = lms + .iter() + .map(|lm| LineMetrics::from_native_ref(lm).clone()) + .collect(); + }; - pub fn as_slice(&self) -> &[TextBox] { unsafe { - let mut count = 0; - let ptr = sb::C_TextBoxes_ptr_count(self.native(), &mut count); - safer::from_raw_parts(ptr as *const TextBox, count) + sb::C_Paragraph_getLineMetrics( + self.native_mut_force(), + VecSink::new(&mut set_lm).native_mut(), + ) } - } -} - -pub type LineMetricsVector<'a> = Borrows<'a, Handle>; - -impl NativeDrop for sb::LineMetricsVector { - fn drop(&mut self) { - unsafe { sb::C_LineMetricsVector_destruct(self) } - } -} -impl<'a> Index for LineMetricsVector<'a> { - type Output = LineMetrics<'a>; - fn index(&self, index: usize) -> &Self::Output { - &self.as_slice()[index] + result } -} -impl<'a> AsRef<[LineMetrics<'a>]> for LineMetricsVector<'a> { - fn as_ref(&self) -> &[LineMetrics<'a>] { - self.as_slice() + pub fn line_number(&self) -> usize { + unsafe { sb::C_Paragraph_lineNumber(self.native_mut_force()) } } -} -impl fmt::Debug for LineMetricsVector<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("LineMetricsVector") - .field(&self.as_slice()) - .finish() + pub fn mark_dirty(&mut self) { + unsafe { sb::C_Paragraph_markDirty(self.native_mut()) } } } -impl<'a> LineMetricsVector<'a> { - pub fn iter(&self) -> impl Iterator> { - self.as_slice().iter() - } +#[deprecated(since = "0.0.0", note = "Use Vec")] +pub type TextBoxes = Vec; - pub fn as_slice(&self) -> &'a [LineMetrics<'a>] { - unsafe { - let mut count = 0; - let ptr = sb::C_LineMetricsVector_ptr_count(self.native(), &mut count); - safer::from_raw_parts(ptr as *const LineMetrics, count) - } - } -} +#[deprecated(since = "0.0.0", note = "Use Vec")] +pub type LineMetricsVector<'a> = Vec>; #[test] #[serial_test::serial] diff --git a/skia-safe/src/modules/paragraph/text_style.rs b/skia-safe/src/modules/paragraph/text_style.rs index 43cdeb607..379a4ed4f 100644 --- a/skia-safe/src/modules/paragraph/text_style.rs +++ b/skia-safe/src/modules/paragraph/text_style.rs @@ -177,7 +177,7 @@ impl NativePartialEq for sb::skia_textlayout_TextStyle { } } -impl Default for Handle { +impl Default for TextStyle { fn default() -> Self { Self::new() } @@ -207,7 +207,7 @@ impl fmt::Debug for TextStyle { } } -impl Handle { +impl TextStyle { pub fn new() -> Self { TextStyle::construct(|ts| unsafe { sb::C_TextStyle_Construct(ts) }) } @@ -286,10 +286,9 @@ impl Handle { pub fn shadows(&self) -> &[TextShadow] { unsafe { - let ts: &sb::TextShadows = transmute_ref(&self.native().fTextShadows); - let mut cnt = 0; - let ptr = TextShadow::from_native_ptr(sb::C_TextShadows_ptr_count(ts, &mut cnt)); - safer::from_raw_parts(ptr, cnt) + let mut count = 0; + let ptr = sb::C_TextStyle_getShadows(&self.native().fTextShadows, &mut count); + safer::from_raw_parts(TextShadow::from_native_ptr(ptr), count) } } @@ -305,10 +304,9 @@ impl Handle { pub fn font_features(&self) -> &[FontFeature] { unsafe { - let ff: &sb::FontFeatures = transmute_ref(&self.native().fFontFeatures); - let mut cnt = 0; - let ptr = FontFeature::from_native_ptr(sb::C_FontFeatures_ptr_count(ff, &mut cnt)); - safer::from_raw_parts(ptr, cnt) + let mut count = 0; + let ptr = sb::C_TextStyle_getFontFeatures(&self.native().fFontFeatures, &mut count); + safer::from_raw_parts(FontFeature::from_native_ptr(ptr), count) } } diff --git a/skia-safe/src/modules/shaper.rs b/skia-safe/src/modules/shaper.rs index 72dab5681..952b5f768 100644 --- a/skia-safe/src/modules/shaper.rs +++ b/skia-safe/src/modules/shaper.rs @@ -457,7 +457,7 @@ impl<'a, T: RunHandler> AsRunHandler<'a> for T { where 'b: 'a, { - let param = rust_run_handler::new_param(self); + let param = unsafe { rust_run_handler::new_param(self) }; rust_run_handler::from_param(¶m) } } @@ -568,9 +568,9 @@ mod rust_run_handler { } } - pub fn new_param(run_handler: &mut dyn RunHandler) -> RustRunHandler_Param { + pub unsafe fn new_param(run_handler: &mut dyn RunHandler) -> RustRunHandler_Param { RustRunHandler_Param { - trait_: unsafe { mem::transmute(run_handler) }, + trait_: mem::transmute(run_handler), beginLine: Some(begin_line), runInfo: Some(run_info), commitRunInfo: Some(commit_run_info), diff --git a/skia-safe/src/prelude.rs b/skia-safe/src/prelude.rs index 691dddb18..98a187e93 100644 --- a/skia-safe/src/prelude.rs +++ b/skia-safe/src/prelude.rs @@ -509,17 +509,22 @@ impl AsRef> for RCHandle { } impl RCHandle { - /// Creates an RCHandle from a pointer. - /// Returns None if the pointer is null. - /// Does not increase the reference count. + /// Creates an reference counted handle from a native pointer. + /// + /// Takes ownership of the object the pointer points to, does not increase the reference count. + /// + /// Returns `None` if the pointer is `null`. #[inline] pub(crate) fn from_ptr(ptr: *mut N) -> Option { ptr::NonNull::new(ptr).map(Self) } - /// Creates an RCHandle from a pointer. - /// Returns None if the pointer is null. - /// Increases the reference count. + /// Creates an reference counted handle from a pointer. + /// + /// Returns `None` if the pointer is `null`. + /// + /// Shares ownership with the object referenced to by the pointer, therefore increases the + /// reference count. #[inline] pub(crate) fn from_unshared_ptr(ptr: *mut N) -> Option { ptr::NonNull::new(ptr).map(|ptr| { From f78efdc3cced257e369a1112635c354be2b5fb08 Mon Sep 17 00:00:00 2001 From: Armin Sander Date: Thu, 3 Jun 2021 14:31:58 +0200 Subject: [PATCH 08/14] Fix potential bug in which self->data() may have been used when the vector was empty --- skia-bindings/src/paragraph.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/skia-bindings/src/paragraph.cpp b/skia-bindings/src/paragraph.cpp index f7ec23d71..7414a4ae8 100644 --- a/skia-bindings/src/paragraph.cpp +++ b/skia-bindings/src/paragraph.cpp @@ -307,9 +307,10 @@ extern "C" { self->~TextStyle(); } - const TextShadow* C_TextStyle_getShadows(const std::vector* self, size_t* len) { - *len = self->size(); - return len != 0 ? self->data() : nullptr; + const TextShadow* C_TextStyle_getShadows(const std::vector* self, size_t* len_ref) { + auto len = self->size(); + *len_ref = len; + return len ? self->data() : nullptr; } void C_TextStyle_addShadow(TextStyle* self, const TextShadow* shadow) { @@ -320,9 +321,10 @@ extern "C" { self->resetShadows(); } - const FontFeature* C_TextStyle_getFontFeatures(const std::vector* self, size_t* len) { - *len = self->size(); - return len != 0 ? self->data() : nullptr; + const FontFeature* C_TextStyle_getFontFeatures(const std::vector* self, size_t* len_ref) { + auto size = self->size(); + *len_ref = size; + return size ? self->data() : nullptr; } void C_TextStyle_addFontFeature(TextStyle* self, const SkString* fontFeature, int value) { From e0aead072512c9d14e64cb1108977d4b4a0a47c2 Mon Sep 17 00:00:00 2001 From: Armin Sander Date: Thu, 3 Jun 2021 14:59:41 +0200 Subject: [PATCH 09/14] m92: Update core/m44.rs --- skia-bindings/src/bindings.cpp | 4 ++++ skia-safe/src/core/m44.rs | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/skia-bindings/src/bindings.cpp b/skia-bindings/src/bindings.cpp index aa6cbdb28..260b20a90 100644 --- a/skia-bindings/src/bindings.cpp +++ b/skia-bindings/src/bindings.cpp @@ -830,6 +830,10 @@ extern "C" bool C_SkM44_equals(const SkM44 *self, const SkM44 *other) { return *self == *other; } +extern "C" void C_SkM44_RectToRect(const SkRect* src, const SkRect* dst, SkM44* uninitialized) { + new(uninitialized) SkM44(SkM44::RectToRect(*src, *dst)); +} + extern "C" void C_SkM44_LookAt(const SkV3* eye, const SkV3* center, const SkV3* up, SkM44* uninitialized) { new(uninitialized) SkM44(SkM44::LookAt(*eye, *center, *up)); } diff --git a/skia-safe/src/core/m44.rs b/skia-safe/src/core/m44.rs index bf7783e5e..b8e2b41b0 100644 --- a/skia-safe/src/core/m44.rs +++ b/skia-safe/src/core/m44.rs @@ -1,4 +1,4 @@ -use crate::prelude::*; +use crate::{prelude::*, Rect}; #[allow(deprecated)] use crate::{scalar, Matrix, Matrix44, Scalars}; use bitflags::_core::ops::{AddAssign, MulAssign}; @@ -520,6 +520,11 @@ impl M44 { m } + pub fn rect_to_rect(src: impl AsRef, dst: impl AsRef) -> Self { + let (src, dst) = (src.as_ref(), dst.as_ref()); + Self::construct(|m| unsafe { sb::C_SkM44_RectToRect(src.native(), dst.native(), m) }) + } + pub fn look_at(eye: &V3, center: &V3, up: &V3) -> Self { Self::construct(|m| unsafe { sb::C_SkM44_LookAt(eye.native(), center.native(), up.native(), m) @@ -767,6 +772,11 @@ impl M44 { self } + pub fn pre_scale_xyz(&mut self, x: scalar, y: scalar, z: scalar) -> &mut Self { + unsafe { self.native_mut().preScale1(x, y, z) }; + self + } + // helper #[allow(deprecated)] From ed23a42497063785279ba56dc36e1e14962acf1a Mon Sep 17 00:00:00 2001 From: Armin Sander Date: Thu, 3 Jun 2021 15:10:38 +0200 Subject: [PATCH 10/14] m92: Update core/ and /svg --- skia-safe/src/core/milestone.rs | 2 +- skia-safe/src/core/path_effect.rs | 9 --- skia-safe/src/core/rect.rs | 8 ++ skia-safe/src/core/surface_props.rs | 4 + skia-safe/src/core/vertices.rs | 111 +--------------------------- skia-safe/src/svg/canvas.rs | 54 +++++++------- 6 files changed, 44 insertions(+), 144 deletions(-) diff --git a/skia-safe/src/core/milestone.rs b/skia-safe/src/core/milestone.rs index 207ed9555..5d126a0a6 100644 --- a/skia-safe/src/core/milestone.rs +++ b/skia-safe/src/core/milestone.rs @@ -1 +1 @@ -pub const MILESTONE: usize = 91; +pub const MILESTONE: usize = 92; diff --git a/skia-safe/src/core/path_effect.rs b/skia-safe/src/core/path_effect.rs index 6bd03e760..1e765ee54 100644 --- a/skia-safe/src/core/path_effect.rs +++ b/skia-safe/src/core/path_effect.rs @@ -148,15 +148,6 @@ impl PathEffect { } } - // pub fn compute_fast_bounds(&self, src: impl AsRef) -> Rect { - // let mut r: Rect = Rect::default(); - // unsafe { - // self.native() - // .computeFastBounds(r.native_mut(), src.as_ref().native()) - // }; - // r - // } - // TODO: rename to to_points()? pub fn as_points( &self, diff --git a/skia-safe/src/core/rect.rs b/skia-safe/src/core/rect.rs index 166b3465a..986feb635 100644 --- a/skia-safe/src/core/rect.rs +++ b/skia-safe/src/core/rect.rs @@ -147,6 +147,14 @@ impl IRect { self.bottom = height; } + pub fn set_size(&mut self, size: impl Into) { + let size = size.into(); + self.left = 0; + self.top = 0; + self.right = size.width; + self.bottom = size.height; + } + #[must_use] pub fn with_offset(&self, delta: impl Into) -> Self { let mut copied = *self; diff --git a/skia-safe/src/core/surface_props.rs b/skia-safe/src/core/surface_props.rs index 0ca88cf33..361241d00 100644 --- a/skia-safe/src/core/surface_props.rs +++ b/skia-safe/src/core/surface_props.rs @@ -107,6 +107,10 @@ impl SurfaceProps { SurfacePropsFlags::from_bits_truncate(self.native().fFlags) } + pub fn clone_with_pixel_geometry(&self, new_pixel_geometry: PixelGeometry) -> Self { + Self::new(self.flags(), new_pixel_geometry) + } + pub fn pixel_geometry(self) -> PixelGeometry { PixelGeometry::from_native_c(self.native().fPixelGeometry) } diff --git a/skia-safe/src/core/vertices.rs b/skia-safe/src/core/vertices.rs index c2fcef1d1..20c43286d 100644 --- a/skia-safe/src/core/vertices.rs +++ b/skia-safe/src/core/vertices.rs @@ -1,9 +1,6 @@ use crate::{prelude::*, Color, Point, Rect}; -use skia_bindings::{ - self as sb, SkPoint, SkVertices, /* SkVertices_Attribute, SkVertices_Attribute_Type, */ - SkVertices_Builder, -}; -use std::{/* ffi::CStr, */ fmt, /* marker::PhantomData, os::raw::c_char, */ ptr, slice}; +use skia_bindings::{self as sb, SkPoint, SkVertices, SkVertices_Builder}; +use std::{fmt, ptr, slice}; #[deprecated(since = "0.29.0", note = "removed without replacement")] pub type BoneIndices = [u32; 4]; @@ -24,108 +21,6 @@ fn test_vertices_vertex_mode_naming() { let _ = VertexMode::Triangles; } -/* - -#[repr(u8)] -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub enum AttributeType { - Float = sb::SkVertices_Attribute_Type::Float as _, - Float2 = sb::SkVertices_Attribute_Type::Float2 as _, - Float3 = sb::SkVertices_Attribute_Type::Float3 as _, - Float4 = sb::SkVertices_Attribute_Type::Float4 as _, - Byte4UNorm = sb::SkVertices_Attribute_Type::Byte4_unorm as _, -} - -impl NativeTransmutable for AttributeType {} -#[test] -fn test_attribute_type_layout() { - AttributeType::test_layout() -} - -pub use skia_bindings::SkVertices_Attribute_Usage as AttributeUsage; -#[test] -fn test_attribute_usage_naming() { - let _ = AttributeUsage::Vector; -} - -*/ - -/* -#[repr(C)] -#[derive(Copy, Clone, Eq, Debug)] -pub struct Attribute<'a> { - pub ty: AttributeType, - pub usage: AttributeUsage, - pub marker_id: u32, - marker_name: *const c_char, - pd: PhantomData<&'a CStr>, -} - -impl NativeTransmutable for Attribute<'_> {} -#[test] -fn test_attribute_layout() { - Attribute::test_layout() -} - -impl PartialEq for Attribute<'_> { - fn eq(&self, other: &Self) -> bool { - self.ty == other.ty && self.usage == other.usage && self.marker_id == other.marker_id - } -} - -impl Default for Attribute<'_> { - fn default() -> Self { - Attribute::new(AttributeType::Float) - } -} - -impl Attribute<'_> { - pub fn new(ty: AttributeType) -> Self { - Self::new_with_usage_and_marker(ty, None, None) - } - - pub fn new_with_usage_and_marker<'a>( - ty: AttributeType, - usage: impl Into>, - marker_name: impl Into>, - ) -> Attribute<'a> { - let marker_name = marker_name - .into() - .map(|m| m.as_ptr()) - .unwrap_or(ptr::null()); - - Attribute::from_native_c(unsafe { - SkVertices_Attribute::new( - ty.into_native(), - usage.into().unwrap_or(AttributeUsage::Raw), - marker_name, - ) - }) - } - - pub fn marker_name(&self) -> Option<&CStr> { - if !self.marker_name.is_null() { - unsafe { CStr::from_ptr(self.marker_name) }.into() - } else { - None - } - } - - pub fn channel_count(self) -> usize { - unsafe { self.native().channelCount() }.try_into().unwrap() - } - - pub fn bytes_per_vertex(self) -> usize { - unsafe { self.native().bytesPerVertex() } - } - - pub fn is_valid(self) -> bool { - unsafe { self.native().isValid() } - } -} - -*/ - pub type Vertices = RCHandle; unsafe impl Send for Vertices {} unsafe impl Sync for Vertices {} @@ -361,8 +256,6 @@ impl Builder { } } - // TODO: customData() - pub fn tex_coords(&mut self) -> Option<&mut [Point]> { unsafe { let vertices = &*self.native().fVertices.fPtr; diff --git a/skia-safe/src/svg/canvas.rs b/skia-safe/src/svg/canvas.rs index 34393e2f9..e05d7ba0e 100644 --- a/skia-safe/src/svg/canvas.rs +++ b/skia-safe/src/svg/canvas.rs @@ -1,13 +1,10 @@ -use crate::interop::DynamicMemoryWStream; -use crate::prelude::*; -use crate::{Data, Rect}; -use skia_bindings as sb; -use skia_bindings::SkCanvas; -use std::pin::Pin; -use std::ptr; +use crate::{interop::DynamicMemoryWStream, prelude::*, Data, Rect}; +use skia_bindings::{self as sb, SkCanvas}; use std::{ fmt, ops::{Deref, DerefMut}, + pin::Pin, + ptr, }; pub struct Canvas { @@ -42,6 +39,7 @@ bitflags! { pub struct Flags : u32 { const CONVERT_TEXT_TO_PATHS = sb::SkSVGCanvas_kConvertTextToPaths_Flag as _; const NO_PRETTY_XML = sb::SkSVGCanvas_kNoPrettyXML_Flag as _; + const RELATIVE_PATH_ENCODING = sb::SkSVGCanvas_kRelativePathEncoding_Flag as _; } } @@ -87,24 +85,30 @@ impl Canvas { } } -#[test] -fn test_svg() { - use crate::Paint; +#[cfg(test)] +mod tests { + use super::Canvas; + use crate::Rect; - let mut canvas = Canvas::new(&Rect::from_size((20, 20)), None); - let paint = Paint::default(); - canvas.draw_circle((10, 10), 10.0, &paint); - let data = canvas.end(); - let contents = String::from_utf8_lossy(data.as_bytes()); - dbg!(&contents); - assert!(contents.contains(r#""#)); - assert!(contents.contains(r#""#)); -} + #[test] + fn test_svg() { + use crate::Paint; + + let mut canvas = Canvas::new(&Rect::from_size((20, 20)), None); + let paint = Paint::default(); + canvas.draw_circle((10, 10), 10.0, &paint); + let data = canvas.end(); + let contents = String::from_utf8_lossy(data.as_bytes()); + dbg!(&contents); + assert!(contents.contains(r#""#)); + assert!(contents.contains(r#""#)); + } -#[test] -fn test_svg_without_ending() { - use crate::Paint; - let mut canvas = Canvas::new(&Rect::from_size((20, 20)), None); - let paint = Paint::default(); - canvas.draw_circle((10, 10), 10.0, &paint); + #[test] + fn test_svg_without_ending() { + use crate::Paint; + let mut canvas = Canvas::new(&Rect::from_size((20, 20)), None); + let paint = Paint::default(); + canvas.draw_circle((10, 10), 10.0, &paint); + } } From 5e4fc85377ab1e96a0b96f7329d74a3c66b62685 Mon Sep 17 00:00:00 2001 From: Armin Sander Date: Thu, 3 Jun 2021 16:41:17 +0200 Subject: [PATCH 11/14] m92: Update utils/ --- skia-bindings/src/bindings.cpp | 23 +-- skia-bindings/src/defaults.rs | 8 +- skia-safe/src/core/bitmap.rs | 8 +- skia-safe/src/core/font_mgr.rs | 7 +- .../paragraph/typeface_font_provider.rs | 3 +- skia-safe/src/prelude.rs | 18 +- skia-safe/src/utils.rs | 15 +- skia-safe/src/utils/interpolator.rs | 175 ------------------ skia-safe/src/utils/ordered_font_mgr.rs | 75 ++++++++ skia-safe/src/utils/parse_path.rs | 39 +++- 10 files changed, 147 insertions(+), 224 deletions(-) delete mode 100644 skia-safe/src/utils/interpolator.rs create mode 100644 skia-safe/src/utils/ordered_font_mgr.rs diff --git a/skia-bindings/src/bindings.cpp b/skia-bindings/src/bindings.cpp index 260b20a90..3b3d19243 100644 --- a/skia-bindings/src/bindings.cpp +++ b/skia-bindings/src/bindings.cpp @@ -89,6 +89,7 @@ #include "include/utils/SkCamera.h" #include "include/utils/SkCustomTypeface.h" #include "include/utils/SkNullCanvas.h" +#include "include/utils/SkOrderedFontMgr.h" #include "include/utils/SkParsePath.h" #include "include/utils/SkShadowUtils.h" #include "include/utils/SkTextUtils.h" @@ -2719,24 +2720,14 @@ C_SkCustomTypefaceBuilder_setGlyph3(SkCustomTypefaceBuilder *self, SkGlyphID gly } */ -/* -extern "C" void C_SkInterpolator_destruct(SkInterpolator* self) { - self->~SkInterpolator(); -} - -extern "C" void C_SkInterpolator_setRepeatCount(SkInterpolator* self, SkScalar repeatCount) { - self->setRepeatCount(repeatCount); -} - -extern "C" void C_SkInterpolator_setReset(SkInterpolator* self, bool reset) { - self->setReset(reset); +extern "C" SkCanvas* C_SkMakeNullCanvas() { + return SkMakeNullCanvas().release(); } -extern "C" void C_SkInterpolator_setMirror(SkInterpolator* self, bool mirror) { - self->setMirror(mirror); +extern "C" SkOrderedFontMgr* C_SkOrderedFontMgr_new() { + return new SkOrderedFontMgr(); } -*/ -extern "C" SkCanvas* C_SkMakeNullCanvas() { - return SkMakeNullCanvas().release(); +extern "C" void C_SkOrderedFontMgr_append(SkOrderedFontMgr* self, SkFontMgr* fontMgr) { + self->append(sp(fontMgr)); } diff --git a/skia-bindings/src/defaults.rs b/skia-bindings/src/defaults.rs index c9f65e8d4..777e24669 100644 --- a/skia-bindings/src/defaults.rs +++ b/skia-bindings/src/defaults.rs @@ -3,7 +3,7 @@ use crate::{ SkBlendMode, SkBlurStyle, SkCanvas_Lattice_RectType, SkClipOp, SkPaint_Cap, SkPaint_Join, - SkPathDirection, SkTileMode, SkYUVColorSpace, + SkParsePath_PathEncoding, SkPathDirection, SkTileMode, SkYUVColorSpace, }; impl Default for SkBlendMode { @@ -61,6 +61,12 @@ impl Default for SkTileMode { } } +impl Default for SkParsePath_PathEncoding { + fn default() -> Self { + SkParsePath_PathEncoding::Absolute + } +} + #[cfg(feature = "textlayout")] pub mod textlayout { impl Default for crate::skia_textlayout_Affinity { diff --git a/skia-safe/src/core/bitmap.rs b/skia-safe/src/core/bitmap.rs index e4d39d361..ae80e8421 100644 --- a/skia-safe/src/core/bitmap.rs +++ b/skia-safe/src/core/bitmap.rs @@ -1,10 +1,8 @@ -use crate::{prelude::*, Image, SamplingOptions}; use crate::{ - AlphaType, Color, ColorSpace, ColorType, IPoint, IRect, ISize, ImageInfo, Matrix, Paint, - PixelRef, Pixmap, Shader, TileMode, + prelude::*, AlphaType, Color, ColorSpace, ColorType, IPoint, IRect, ISize, Image, ImageInfo, + Matrix, Paint, PixelRef, Pixmap, SamplingOptions, Shader, TileMode, }; -use skia_bindings as sb; -use skia_bindings::SkBitmap; +use skia_bindings::{self as sb, SkBitmap}; use std::{ffi, fmt, ptr}; /// [Bitmap] describes a two-dimensional raster pixel array. [Bitmap] is built on [ImageInfo], diff --git a/skia-safe/src/core/font_mgr.rs b/skia-safe/src/core/font_mgr.rs index 528f1b25b..9ba4c2ae7 100644 --- a/skia-safe/src/core/font_mgr.rs +++ b/skia-safe/src/core/font_mgr.rs @@ -128,7 +128,12 @@ impl FontMgr { (0..self.count_families()).map(move |i| self.family_name(i)) } + #[deprecated(since = "0.0.0", note = "Use new_style_set")] pub fn new_styleset(&self, index: usize) -> FontStyleSet { + self.new_style_set(index) + } + + pub fn new_style_set(&self, index: usize) -> FontStyleSet { assert!(index < self.count_families()); FontStyleSet::from_ptr(unsafe { self.native().createStyleSet(index.try_into().unwrap()) }) .unwrap() @@ -219,7 +224,7 @@ mod tests { for i in 0..families { let name = font_mgr.family_name(i); println!("font_family: {}", name); - let mut style_set = font_mgr.new_styleset(i); + let mut style_set = font_mgr.new_style_set(i); for style_index in 0..style_set.count() { let (_, style_name) = style_set.style(style_index); if let Some(style_name) = style_name { diff --git a/skia-safe/src/modules/paragraph/typeface_font_provider.rs b/skia-safe/src/modules/paragraph/typeface_font_provider.rs index 062dc944d..a71cae5e2 100644 --- a/skia-safe/src/modules/paragraph/typeface_font_provider.rs +++ b/skia-safe/src/modules/paragraph/typeface_font_provider.rs @@ -6,6 +6,7 @@ use crate::{ use skia_bindings as sb; use std::{ fmt, + mem::transmute, ops::{Deref, DerefMut}, ptr, }; @@ -86,7 +87,7 @@ impl Default for TypefaceFontProvider { impl From for FontMgr { fn from(provider: TypefaceFontProvider) -> Self { - provider.deref().clone() + unsafe { transmute(provider) } } } diff --git a/skia-safe/src/prelude.rs b/skia-safe/src/prelude.rs index 98a187e93..b7d9d96ef 100644 --- a/skia-safe/src/prelude.rs +++ b/skia-safe/src/prelude.rs @@ -2,13 +2,16 @@ use skia_bindings::{ C_SkRefCntBase_ref, C_SkRefCntBase_unique, C_SkRefCntBase_unref, SkNVRefCnt, SkRefCnt, SkRefCntBase, }; -use std::hash::{Hash, Hasher}; -use std::mem::MaybeUninit; -use std::ops::{Deref, DerefMut, Index, IndexMut}; -use std::{mem, ptr, slice}; +use std::{ + hash::{Hash, Hasher}, + marker::PhantomData, + mem::{self, MaybeUninit}, + ops::{Deref, DerefMut, Index, IndexMut}, + ptr, slice, +}; + // Re-export TryFrom / TryInto to make them available in all modules that use prelude::*. pub use std::convert::{TryFrom, TryInto}; -use std::marker::PhantomData; /// Swiss army knife to convert any reference into any other. pub(crate) unsafe fn transmute_ref(from: &FromT) -> &ToT { @@ -658,7 +661,10 @@ where /// Trait to use native types that as a rust type /// _inplace_ with the same size and field layout. -pub trait NativeTransmutable: Sized { +pub trait NativeTransmutable: Sized +where + Self: Sized, +{ /// Provides access to the native value through a /// transmuted reference to the Rust value. fn native(&self) -> &NT { diff --git a/skia-safe/src/utils.rs b/skia-safe/src/utils.rs index 9fdefcce8..30232d814 100644 --- a/skia-safe/src/utils.rs +++ b/skia-safe/src/utils.rs @@ -1,15 +1,12 @@ mod camera; -pub use camera::*; - mod custom_typeface; -pub use custom_typeface::*; - -pub mod interpolator; -// pub use interpolator::Interpolator; - mod null_canvas; -pub use null_canvas::*; - +mod ordered_font_mgr; pub mod parse_path; pub mod shadow_utils; pub mod text_utils; + +pub use camera::*; +pub use custom_typeface::*; +pub use null_canvas::*; +pub use ordered_font_mgr::*; diff --git a/skia-safe/src/utils/interpolator.rs b/skia-safe/src/utils/interpolator.rs deleted file mode 100644 index d32ffea66..000000000 --- a/skia-safe/src/utils/interpolator.rs +++ /dev/null @@ -1,175 +0,0 @@ -//! This wrapper combines SkInterpolatorBase and SkInterpolator into the type Interpolator. - -/* -use crate::{prelude::*, scalar, Point}; -use skia_bindings::{self as sb, SkInterpolator, SkUnitCubicInterp}; -use std::{fmt, time::Duration}; - -pub use skia_bindings::SkInterpolatorBase_Result as Result; -#[test] -fn test_interpolator_result_naming() { - let _ = Result::FreezeEnd_Result; -} - -pub type Interpolator = Handle; -unsafe impl Send for Interpolator {} -unsafe impl Sync for Interpolator {} - -impl NativeDrop for SkInterpolator { - fn drop(&mut self) { - unsafe { - sb::C_SkInterpolator_destruct(self); - } - } -} - -impl Default for Interpolator { - fn default() -> Self { - Handle::from_native_c(unsafe { SkInterpolator::new() }) - } -} - -impl fmt::Debug for Interpolator { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Interpolator") - .field("duration", &self.duration()) - .field("elem_count", &self.elem_count()) - .finish() - } -} - -/// Wrapper for functions that are implemented in SkInterpolatorBase -impl Interpolator { - pub fn duration(&self) -> Option<(Duration, Duration)> { - let mut start_time = 0; - let mut end_time = 0; - unsafe { - self.native() - ._base - .getDuration(&mut start_time, &mut end_time) - } - .if_true_then_some(|| { - ( - Duration::from_millis(start_time.try_into().unwrap()), - Duration::from_millis(end_time.try_into().unwrap()), - ) - }) - } - - pub fn set_mirror(&mut self, mirror: bool) -> &mut Self { - unsafe { sb::C_SkInterpolator_setMirror(self.native_mut(), mirror) } - self - } - - pub fn set_repeat_count(&mut self, repeat_count: scalar) -> &mut Self { - unsafe { sb::C_SkInterpolator_setRepeatCount(self.native_mut(), repeat_count) } - self - } - - pub fn set_reset(&mut self, reset: bool) -> &mut Self { - unsafe { sb::C_SkInterpolator_setReset(self.native_mut(), reset) } - self - } - - pub fn time_to_t(&self, time: Duration) -> (Result, TimeToT) { - let mut t = 0.0; - let mut index = 0; - let mut exact = false; - let r = unsafe { - self.native()._base.timeToT( - time.as_millis().try_into().unwrap(), - &mut t, - &mut index, - &mut exact, - ) - }; - ( - r, - TimeToT { - t, - index: index.try_into().unwrap(), - exact, - }, - ) - } -} - -/// Wrapper for SkInterpolator functions. -impl Interpolator { - pub fn new(elem_count: usize, frame_count: usize) -> Self { - Handle::from_native_c(unsafe { - SkInterpolator::new1( - elem_count.try_into().unwrap(), - frame_count.try_into().unwrap(), - ) - }) - } - - pub fn reset(&mut self, elem_count: usize, frame_count: usize) -> &mut Self { - unsafe { - self.native_mut().reset( - elem_count.try_into().unwrap(), - frame_count.try_into().unwrap(), - ) - } - self - } - - pub fn set_key_frame<'a>( - &mut self, - index: usize, - time: Duration, - values: &[scalar], - blend: impl Into>, - ) -> bool { - assert_eq!(values.len(), self.elem_count()); - unsafe { - self.native_mut().setKeyFrame( - index.try_into().unwrap(), - time.as_millis().try_into().unwrap(), - values.as_ptr(), - blend.into().as_ptr_or_null() as _, - ) - } - } - - // TODO: may provide a variant that returns a Vec. - pub fn time_to_values<'a>( - &self, - time: Duration, - values: impl Into>, - ) -> Result { - let mut values = values.into(); - if let Some(ref values) = values { - assert_eq!(values.len(), self.elem_count()); - }; - unsafe { - self.native().timeToValues( - time.as_millis().try_into().unwrap(), - values.as_ptr_or_null_mut(), - ) - } - } -} - -/// Additional functions that seem useful. -impl Interpolator { - pub fn elem_count(&self) -> usize { - self.native()._base.fElemCount.try_into().unwrap() - } -} - -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct TimeToT { - pub t: scalar, - pub index: usize, - pub exact: bool, -} - -pub fn unit_cubic_interp(value: scalar, b: impl Into, c: impl Into) -> scalar { - let b = b.into(); - let c = c.into(); - unsafe { SkUnitCubicInterp(value, b.x, b.y, c.x, c.y) } -} - -*/ diff --git a/skia-safe/src/utils/ordered_font_mgr.rs b/skia-safe/src/utils/ordered_font_mgr.rs new file mode 100644 index 000000000..774587ac7 --- /dev/null +++ b/skia-safe/src/utils/ordered_font_mgr.rs @@ -0,0 +1,75 @@ +use crate::{prelude::*, FontMgr}; +use skia_bindings::{self as sb, SkOrderedFontMgr, SkRefCntBase}; +use std::{ + fmt, + mem::transmute, + ops::{Deref, DerefMut}, +}; + +pub type OrderedFontMgr = RCHandle; + +impl NativeRefCountedBase for SkOrderedFontMgr { + type Base = SkRefCntBase; +} + +impl Deref for OrderedFontMgr { + type Target = FontMgr; + fn deref(&self) -> &Self::Target { + unsafe { transmute_ref(self) } + } +} + +impl DerefMut for OrderedFontMgr { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { transmute_ref_mut(self) } + } +} + +impl Default for OrderedFontMgr { + fn default() -> Self { + Self::new() + } +} + +impl From for FontMgr { + fn from(font_mgr: OrderedFontMgr) -> Self { + unsafe { transmute(font_mgr) } + } +} + +impl fmt::Debug for OrderedFontMgr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("OrderedFontMgr") + .field("base", self as &FontMgr) + .finish() + } +} + +impl OrderedFontMgr { + pub fn new() -> Self { + Self::from_ptr(unsafe { sb::C_SkOrderedFontMgr_new() }).unwrap() + } + + pub fn append(&mut self, font_mgr: impl Into) { + let font_mgr = font_mgr.into(); + unsafe { sb::C_SkOrderedFontMgr_append(self.native_mut(), font_mgr.into_ptr()) } + } +} + +#[cfg(test)] +mod tests { + use super::OrderedFontMgr; + + #[test] + fn can_use_font_mgr_functions() { + let ordered = OrderedFontMgr::default(); + let _families = ordered.count_families(); + } + + #[test] + fn can_pass_ordered_font_mgr_where_a_font_mgr_is_expected() { + let mut ordered = OrderedFontMgr::default(); + let another = OrderedFontMgr::default(); + ordered.append(another); + } +} diff --git a/skia-safe/src/utils/parse_path.rs b/skia-safe/src/utils/parse_path.rs index 527b6d25d..c725258f0 100644 --- a/skia-safe/src/utils/parse_path.rs +++ b/skia-safe/src/utils/parse_path.rs @@ -1,5 +1,5 @@ use crate::{ - // interop, + interop, prelude::{IfBoolSome, NativeAccess}, Path, }; @@ -12,19 +12,38 @@ pub fn from_svg(svg: impl AsRef) -> Option { unsafe { sb::SkParsePath_FromSVGString(str.as_ptr(), path.native_mut()) }.if_true_some(path) } -// pub fn to_svg(path: &Path) -> String { -// let mut svg = interop::String::default(); -// unsafe { sb::SkParsePath_ToSVGString(path.native(), svg.native_mut()) }; - -// svg.as_str().into() -// } +pub use skia_bindings::SkParsePath_PathEncoding as PathEncoding; impl Path { pub fn from_svg(svg: impl AsRef) -> Option { from_svg(svg) } - // pub fn to_svg(&self) -> String { - // to_svg(self) - // } + pub fn to_svg(&self) -> String { + to_svg(self) + } + + pub fn to_svg_with_encoding(&self, encoding: PathEncoding) -> String { + to_svg_with_encoding(self, encoding) + } +} + +pub fn to_svg(path: &Path) -> String { + to_svg_with_encoding(path, PathEncoding::Absolute) +} + +pub fn to_svg_with_encoding(path: &Path, encoding: PathEncoding) -> String { + let mut svg = interop::String::default(); + unsafe { sb::SkParsePath_ToSVGString(path.native(), svg.native_mut(), encoding) }; + svg.as_str().into() +} + +#[cfg(test)] +mod tests { + use super::PathEncoding; + + #[test] + fn test_path_encoding_naming() { + let _ = PathEncoding::Absolute; + } } From e9558a0ed444e3ea90bb81b116fb263caea8e797 Mon Sep 17 00:00:00 2001 From: Armin Sander Date: Thu, 3 Jun 2021 17:05:18 +0200 Subject: [PATCH 12/14] m92: Update modules/paragraph/ --- skia-bindings/src/paragraph.cpp | 4 ++ skia-safe/src/modules/paragraph/paragraph.rs | 60 +++++++++++-------- .../src/modules/paragraph/paragraph_style.rs | 20 +++++++ .../src/modules/paragraph/text_shadow.rs | 6 +- skia-safe/src/modules/paragraph/text_style.rs | 10 ++++ 5 files changed, 73 insertions(+), 27 deletions(-) diff --git a/skia-bindings/src/paragraph.cpp b/skia-bindings/src/paragraph.cpp index 7414a4ae8..ee10f5443 100644 --- a/skia-bindings/src/paragraph.cpp +++ b/skia-bindings/src/paragraph.cpp @@ -236,6 +236,10 @@ extern "C" { void C_Paragraph_markDirty(Paragraph* self) { self->markDirty(); } + + int32_t C_Paragraph_unresolvedGlyphs(Paragraph* self) { + return self->unresolvedGlyphs(); + } } // diff --git a/skia-safe/src/modules/paragraph/paragraph.rs b/skia-safe/src/modules/paragraph/paragraph.rs index ce15e093a..05cdefbd6 100644 --- a/skia-safe/src/modules/paragraph/paragraph.rs +++ b/skia-safe/src/modules/paragraph/paragraph.rs @@ -163,6 +163,14 @@ impl Paragraph { pub fn mark_dirty(&mut self) { unsafe { sb::C_Paragraph_markDirty(self.native_mut()) } } + + pub fn unresolved_glyphs(&mut self) -> Option { + unsafe { sb::C_Paragraph_unresolvedGlyphs(self.native_mut()) } + .try_into() + .ok() + } + + // TODO: wrap visit() } #[deprecated(since = "0.0.0", note = "Use Vec")] @@ -171,30 +179,34 @@ pub type TextBoxes = Vec; #[deprecated(since = "0.0.0", note = "Use Vec")] pub type LineMetricsVector<'a> = Vec>; -#[test] -#[serial_test::serial] -fn test_line_metrics() { - // note: some of the following code is copied from the skparagraph skia-org example. - use crate::icu; - use crate::textlayout::{FontCollection, ParagraphBuilder, ParagraphStyle, TextStyle}; - use crate::FontMgr; - - icu::init(); - - let mut font_collection = FontCollection::new(); - font_collection.set_default_font_manager(FontMgr::new(), None); - let paragraph_style = ParagraphStyle::new(); - let mut paragraph_builder = ParagraphBuilder::new(¶graph_style, font_collection); - let ts = TextStyle::new(); - paragraph_builder.push_style(&ts); - paragraph_builder.add_text(LOREM_IPSUM); - let mut paragraph = paragraph_builder.build(); - paragraph.layout(256.0); +#[cfg(test)] +mod tests { + use crate::{ + icu, + textlayout::{FontCollection, ParagraphBuilder, ParagraphStyle, TextStyle}, + FontMgr, + }; + + #[test] + #[serial_test::serial] + fn test_line_metrics() { + icu::init(); + + let mut font_collection = FontCollection::new(); + font_collection.set_default_font_manager(FontMgr::new(), None); + let paragraph_style = ParagraphStyle::new(); + let mut paragraph_builder = ParagraphBuilder::new(¶graph_style, font_collection); + let ts = TextStyle::new(); + paragraph_builder.push_style(&ts); + paragraph_builder.add_text(LOREM_IPSUM); + let mut paragraph = paragraph_builder.build(); + paragraph.layout(256.0); + + let line_metrics = paragraph.get_line_metrics(); + for (line, lm) in line_metrics.iter().enumerate() { + println!("line {}: width: {}", line + 1, lm.width) + } - let line_metrics = paragraph.get_line_metrics(); - for (line, lm) in line_metrics.iter().enumerate() { - println!("line {}: width: {}", line + 1, lm.width) + static LOREM_IPSUM: &str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur at leo at nulla tincidunt placerat. Proin eget purus augue. Quisque et est ullamcorper, pellentesque felis nec, pulvinar massa. Aliquam imperdiet, nulla ut dictum euismod, purus dui pulvinar risus, eu suscipit elit neque ac est. Nullam eleifend justo quis placerat ultricies. Vestibulum ut elementum velit. Praesent et dolor sit amet purus bibendum mattis. Aliquam erat volutpat."; } - - static LOREM_IPSUM: &str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur at leo at nulla tincidunt placerat. Proin eget purus augue. Quisque et est ullamcorper, pellentesque felis nec, pulvinar massa. Aliquam imperdiet, nulla ut dictum euismod, purus dui pulvinar risus, eu suscipit elit neque ac est. Nullam eleifend justo quis placerat ultricies. Vestibulum ut elementum velit. Praesent et dolor sit amet purus bibendum mattis. Aliquam erat volutpat."; } diff --git a/skia-safe/src/modules/paragraph/paragraph_style.rs b/skia-safe/src/modules/paragraph/paragraph_style.rs index 9d89d03a2..904945ccd 100644 --- a/skia-safe/src/modules/paragraph/paragraph_style.rs +++ b/skia-safe/src/modules/paragraph/paragraph_style.rs @@ -47,6 +47,8 @@ impl fmt::Debug for StrutStyle { .field("leading", &self.leading()) .field("strut_enabled", &self.strut_enabled()) .field("force_strut_height", &self.force_strut_height()) + .field("height_override", &self.height_override()) + .field("half_leading", &self.half_leading()) .finish() } } @@ -126,6 +128,24 @@ impl StrutStyle { self.native_mut().fForceHeight = force_height; self } + + pub fn height_override(&self) -> bool { + self.native().fHeightOverride + } + + pub fn set_height_override(&mut self, height_override: bool) -> &mut Self { + self.native_mut().fHeightOverride = height_override; + self + } + + pub fn half_leading(&self) -> bool { + self.native().fHalfLeading + } + + pub fn set_half_leading(&mut self, half_leading: bool) -> &mut Self { + self.native_mut().fHalfLeading = half_leading; + self + } } // Can't use Handle<> here, std::u16string maintains an interior pointer. diff --git a/skia-safe/src/modules/paragraph/text_shadow.rs b/skia-safe/src/modules/paragraph/text_shadow.rs index 8b2ed8710..e919abce5 100644 --- a/skia-safe/src/modules/paragraph/text_shadow.rs +++ b/skia-safe/src/modules/paragraph/text_shadow.rs @@ -6,7 +6,7 @@ use skia_bindings as sb; pub struct TextShadow { pub color: Color, pub offset: Point, - pub blur_radius: f64, + pub blur_sigma: f64, } impl NativeTransmutable for TextShadow {} @@ -29,12 +29,12 @@ impl PartialEq for TextShadow { } impl TextShadow { - pub fn new(color: impl Into, offset: impl Into, blur_radius: f64) -> Self { + pub fn new(color: impl Into, offset: impl Into, blur_sigma: f64) -> Self { TextShadow::from_native_c(unsafe { sb::skia_textlayout_TextShadow::new1( color.into().into_native(), offset.into().into_native(), - blur_radius, + blur_sigma, ) }) } diff --git a/skia-safe/src/modules/paragraph/text_style.rs b/skia-safe/src/modules/paragraph/text_style.rs index 379a4ed4f..4e164e954 100644 --- a/skia-safe/src/modules/paragraph/text_style.rs +++ b/skia-safe/src/modules/paragraph/text_style.rs @@ -197,6 +197,7 @@ impl fmt::Debug for TextStyle { .field("font_families", &self.font_families()) .field("height", &self.height()) .field("height_override", &self.height_override()) + .field("half_leading", &self.half_leading()) .field("letter_spacing", &self.letter_spacing()) .field("word_spacing", &self.word_spacing()) .field("typeface", &self.typeface()) @@ -368,6 +369,15 @@ impl TextStyle { self.native().fHeightOverride } + pub fn set_half_leading(&mut self, half_leading: bool) -> &mut Self { + self.native_mut().fHalfLeading = half_leading; + self + } + + pub fn half_leading(&self) -> bool { + self.native().fHalfLeading + } + pub fn set_letter_spacing(&mut self, letter_spacing: scalar) -> &mut Self { self.native_mut().fLetterSpacing = letter_spacing; self From 77ef923f3122506eb3e25a6aa51d5edbbe882fff Mon Sep 17 00:00:00 2001 From: Armin Sander Date: Thu, 3 Jun 2021 17:15:01 +0200 Subject: [PATCH 13/14] m92: Update gpu/ --- skia-safe/src/gpu/backend_surface.rs | 8 ++++++-- skia-safe/src/gpu/d3d/types.rs | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/skia-safe/src/gpu/backend_surface.rs b/skia-safe/src/gpu/backend_surface.rs index 0b38706fe..b71f2b678 100644 --- a/skia-safe/src/gpu/backend_surface.rs +++ b/skia-safe/src/gpu/backend_surface.rs @@ -6,7 +6,7 @@ use super::gl; use super::mtl; #[cfg(feature = "vulkan")] use super::vk; -use super::{BackendAPI, BackendSurfaceMutableState}; +use super::{BackendAPI, BackendSurfaceMutableState, Mipmapped}; use crate::{prelude::*, ISize}; use skia_bindings::{ self as sb, GrBackendFormat, GrBackendRenderTarget, GrBackendTexture, GrMipmapped, @@ -175,7 +175,7 @@ impl fmt::Debug for BackendTexture { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut d = f.debug_struct("BackendTexture"); d.field("dimensions", &self.dimensions()); - d.field("has_mipmaps", &self.has_mipmaps()); + d.field("mipmapped", &self.mipmapped()); d.field("backend", &self.backend()); #[cfg(feature = "gl")] d.field("gl_texture_info", &self.gl_texture_info()); @@ -269,6 +269,10 @@ impl BackendTexture { self.native().fHeight } + pub fn mipmapped(&self) -> Mipmapped { + self.native().fMipmapped + } + #[deprecated(since = "0.35.0", note = "Use has_mipmaps()")] pub fn has_mip_maps(&self) -> bool { self.has_mipmaps() diff --git a/skia-safe/src/gpu/d3d/types.rs b/skia-safe/src/gpu/d3d/types.rs index 19ca6be2e..2c2be3bbc 100644 --- a/skia-safe/src/gpu/d3d/types.rs +++ b/skia-safe/src/gpu/d3d/types.rs @@ -46,7 +46,7 @@ impl fmt::Debug for Alloc { } // TODO: support the implementation of custom D3D memory allocator's -// virtual createResource() function. +// virtual createResource() and createAliasingResource() functions. pub type MemoryAllocator = RCHandle; unsafe impl Send for MemoryAllocator {} unsafe impl Sync for MemoryAllocator {} From e51541506771d989944b669b6a508474041bcca8 Mon Sep 17 00:00:00 2001 From: Armin Sander Date: Fri, 4 Jun 2021 00:12:26 +0200 Subject: [PATCH 14/14] Experimental: Cherry pick Skia types instead of excluding the ones we don't need. --- skia-bindings/build_support/skia.rs | 273 ++++++++++++++++++++++++---- 1 file changed, 237 insertions(+), 36 deletions(-) diff --git a/skia-bindings/build_support/skia.rs b/skia-bindings/build_support/skia.rs index f7fa9c468..34c306348 100644 --- a/skia-bindings/build_support/skia.rs +++ b/skia-bindings/build_support/skia.rs @@ -744,6 +744,7 @@ fn generate_bindings(build: &FinalBuildConfiguration, output_directory: &Path) { .raw_line("#![allow(clippy::all)]") // GrVkBackendContext contains u128 fields on macOS .raw_line("#![allow(improper_ctypes)]") + .allowlist_recursively(false) .allowlist_function("C_.*") .constified_enum(".*Mask") .constified_enum(".*Flags") @@ -752,39 +753,39 @@ fn generate_bindings(build: &FinalBuildConfiguration, output_directory: &Path) { .constified_enum("GrVkAlloc_Flag") .constified_enum("GrGLBackendState") // not used: - .blocklist_type("SkPathRef_Editor") - .blocklist_function("SkPathRef_Editor_Editor") + // .blocklist_type("SkPathRef_Editor") + // .blocklist_function("SkPathRef_Editor_Editor") // private types that pull in inline functions that cannot be linked: // https://github.com/rust-skia/rust-skia/issues/318 - .raw_line("pub enum GrContext_Base {}") - .blocklist_type("GrContext_Base") - .blocklist_function("GrContext_Base_.*") - .raw_line("pub enum GrImageContext {}") - .blocklist_type("GrImageContext") - .raw_line("pub enum GrImageContextPriv {}") - .blocklist_type("GrImageContextPriv") - .raw_line("pub enum GrContextThreadSafeProxy {}") - .blocklist_type("GrContextThreadSafeProxy") - .blocklist_type("GrContextThreadSafeProxyPriv") - .raw_line("pub enum GrContextThreadSafeProxyPriv {}") - .blocklist_type("GrRecordingContextPriv") - .raw_line("pub enum GrRecordingContextPriv {}") - .blocklist_function("GrRecordingContext_priv.*") - .blocklist_function("GrDirectContext_priv.*") - .blocklist_type("GrContextPriv") - .raw_line("pub enum GrContextPriv {}") - .blocklist_function("GrContext_priv.*") - .blocklist_function("SkDeferredDisplayList_priv.*") - .raw_line("pub enum SkVerticesPriv {}") - .blocklist_type("SkVerticesPriv") - .blocklist_function("SkVertices_priv.*") - .blocklist_function("std::bitset_flip.*") + // .raw_line("pub enum GrContext_Base {}") + // .blocklist_type("GrContext_Base") + // .blocklist_function("GrContext_Base_.*") + // .raw_line("pub enum GrImageContext {}") + // .blocklist_type("GrImageContext") + // .raw_line("pub enum GrImageContextPriv {}") + // .blocklist_type("GrImageContextPriv") + // .raw_line("pub enum GrContextThreadSafeProxy {}") + // .blocklist_type("GrContextThreadSafeProxy") + // .blocklist_type("GrContextThreadSafeProxyPriv") + // .raw_line("pub enum GrContextThreadSafeProxyPriv {}") + // .blocklist_type("GrRecordingContextPriv") + // .raw_line("pub enum GrRecordingContextPriv {}") + // .blocklist_function("GrRecordingContext_priv.*") + // .blocklist_function("GrDirectContext_priv.*") + // .blocklist_type("GrContextPriv") + // .raw_line("pub enum GrContextPriv {}") + // .blocklist_function("GrContext_priv.*") + // .blocklist_function("SkDeferredDisplayList_priv.*") + // .raw_line("pub enum SkVerticesPriv {}") + // .blocklist_type("SkVerticesPriv") + // .blocklist_function("SkVertices_priv.*") + // .blocklist_function("std::bitset_flip.*") // Vulkan reexports that got swallowed by making them opaque. // (these can not be allowlisted by a extern "C" function) - .allowlist_type("VkPhysicalDeviceFeatures") - .allowlist_type("VkPhysicalDeviceFeatures2"). + // .allowlist_type("VkPhysicalDeviceFeatures") + // .allowlist_type("VkPhysicalDeviceFeatures2"). // m91: These functions are not actually implemented. - blocklist_function("SkCustomTypefaceBuilder_setGlyph[123].*") + .blocklist_function("SkCustomTypefaceBuilder_setGlyph[123].*") // misc .allowlist_var("SK_Color.*") .allowlist_var("kAll_GrBackendState") @@ -804,13 +805,27 @@ fn generate_bindings(build: &FinalBuildConfiguration, output_directory: &Path) { builder }; + for ty in ALLOWLISTED_TYPES { + builder = builder.allowlist_type(ty) + } + + for ty in ALLOWED_OPAQUE_TYPES { + builder = builder.allowlist_type(ty).opaque_type(ty) + } + + for ty in PRIVATE_TYPES { + builder = builder.raw_line(format!("pub enum {} {{}}", ty)); + } + for function in ALLOWLISTED_FUNCTIONS { builder = builder.allowlist_function(function) } - for opaque_type in OPAQUE_TYPES { - builder = builder.opaque_type(opaque_type) - } + /* + for opaque_type in OPAQUE_TYPES { + builder = builder.opaque_type(opaque_type) + } + */ for t in BLOCKLISTED_TYPES { builder = builder.blocklist_type(t); @@ -938,6 +953,193 @@ fn generate_bindings(build: &FinalBuildConfiguration, output_directory: &Path) { .expect("Couldn't write bindings!"); } +const ALLOWLISTED_TYPES: &[&str] = &[]; + +const ALLOWED_OPAQUE_TYPES: &[&str] = &[ + "DXGI_FORMAT", + "FILE", + "GrBackendFormat", + "GrBackendSurfaceMutableState", + "GrBackendTexture", + "GrColorFormatDesc", + "GrColorType", + "GrContextOptions", + "GrD3DBackendSurfaceInfo", + "GrD3DResourceStateEnum", + "GrDirectContext", + "GrFlushInfo", + "GrGLBackendTextureInfo", + "GrGLEnum", + "GrGLExtensions", + "GrGLFormat", + "GrGLFrameBufferInfo", + "GrGLInterface", + "GrGLTextureInfo", + "GrMipmapped", + "GrMockTextureInfo", + "GrProtected", + "GrRecordingContext", + "GrSemaphoresSubmitted", + "GrSurfaceOrigin", + "GrVkImageInfo", + "GrVkYcbcrConversionInfo", + "sk_sp", + "Sk3DView", + "SkAlphaType", + "SkApplyPerspectiveClip", + "SkBitmap", + "SkBlendMode", + "SkBlendModeCoeff", + "SkBlurStyle", + "SkBudgeted", + "SkCanvas", + "SkClipOp", + "skcms_.*", + "SkCodec_Options", + "SkCodec_Result", + "SkCodec_SkScanlineOrder", + "SkCodec", + "SkCodecAnimation_.*", + "SkCodecAnimation_Blend", + "SkCodecAnimation_DisposalMethod", + "SkColor", + "SkColor4f", + "SkColorChannelFlag", + "SkColorFilter", + "SkColorInfo", + "SkColorMatrix", + "SkColorSpace", + "SkColorType", + "SkCoverageMode", + "SkCubicMap", + "SkCubicResampler", + "SkCustomTypefaceBuilder", + "SkData", + "SkDataTable", + "SkDeferredDisplayList", + "SkDeferredDisplayListRecorder", + "SkDrawable", + "SkDrawShadowRec", + "SkDynamicMemoryWStream", + "SkEncodedImageFormat", + "SkEncodedInfo", + "SkEncodedOrigin", + "SkFilterMode", + "SkFilterQuality", + "SkFlattenable", + "SkFont", + "SkGlyphID", + "SkGradientShader", + "SkGraphics", + "SkHighContrastConfig", + "SkImage", + "SkImageFilter", + "SkImageFilters_CropRect", + "SkImageGenerator", + "SkImageInfo", + "SkIPoint", + "SkIRect", + "SkISize", + "SkM44", + "SkMask", + "SkMaskFilter", + "SkMatrix", + "SkMemoryStream", + "SkOnce", + "SkOpBuilder", + "SkOrderedFontMgr", + "SkPaint", + "SkParsePath", + "SkPath", + "SkPath1DPathEffect_Style", + "SkPathDirection", + "SkPathEffect", + "SkPathFillType", + "SkPathOp", + "SkPDF_Metadata", + "SkPDF_StructureElementNode", + "SkPicture", + "SkPixelGeometry", + "SkPixmap", + "SkPMColor", + "SkPngChunkReader", + "SkPoint", + "SkPoint3", + "SkRasterHandleAllocator_Handle", + "SkRect", + "SkRefCnt", + "SkRegion", + "SkRRect", + "SkRSXform", + "SkRuntimeEffect", + "SkSamplingOptions", + "SkScalar", + "SkShader_GradientInfo", + "SkShader_GradientType", + "SkShader", + "SkShadowFlags", + "SkSize", + "SkStream", + "SkStreamMemory", + "SkString", + "SkStrings", + "SkStrokeRec", + "SkSurface", + "SkSurfaceCharacterization", + "SkSurfaceProps", + "SkTableMaskFilter", + "SkTextBlob", + "SkTextEncoding", + "SkTextUtils", + "SkTileMode", + "SkUnichar", + "SkV3", + "SkV4", + "SkVector", + "SkVertices", + "SkWStream", + "SkYUVAInfo_PlaneConfig", + "SkYUVAInfo_Subsampling", + "SkYUVAInfo", + "SkYUVAPixmapInfo_SupportedDataTypes", + "SkYUVAPixmapInfo", + "SkYUVAPixmaps", + "SkYUVColorSpace", + "std::atomic", + "std::function", + "std::string", + "std::unique_ptr", + "std::vector", + "U8CPU", + "va_list", + "VkBool32", + "VkFormat", + "VkStructureType", + "SkCodecAnimation::DisposalMethod", + "SkCodecAnimation::Blend", + "GrBackendSurfaceMutableState_.*", + "GrYUVABackendTextures", + "GrMipMapped", + "GrYUVABackendTextureInfo", +]; + +const PRIVATE_TYPES: &[&str] = &[ + "GrVkBackendSurfaceInfo", + "SkReadBuffer", + "SkSerialProcs", + "SkDeserialProcs", + "GrImageContext", +]; + +const BLOCKLISTED_TYPES: &[&str] = &[ + "sk_sp_.*", + "std::atomic_.*", + "std::vector_.*", + "std::unique_ptr_.*", + "std::string_.*", + "std::function_.*", +]; + const ALLOWLISTED_FUNCTIONS: &[&str] = &[ "SkAnnotateRectWithURL", "SkAnnotateNamedDestination", @@ -961,11 +1163,6 @@ const ALLOWLISTED_FUNCTIONS: &[&str] = &[ "Simplify", "TightBounds", "AsWinding", - // utils/ - "Sk3LookAt", - "Sk3Perspective", - "Sk3MapPts", - "SkUnitCubicInterp", ]; const OPAQUE_TYPES: &[&str] = &[ @@ -1081,8 +1278,11 @@ const OPAQUE_TYPES: &[&str] = &[ "GrD3DMemoryAllocator", // m87, yuva_pixmaps "std::tuple", + // m92: referred, but yet unused + "SkFontDescriptor", ]; +/* const BLOCKLISTED_TYPES: &[&str] = &[ // modules/skparagraph // pulls in a std::map<>, which we treat as opaque, but bindgen creates wrong bindings for @@ -1102,6 +1302,7 @@ const BLOCKLISTED_TYPES: &[&str] = &[ "std::__cxx.*", "std::array.*", ]; +*/ #[derive(Debug)] struct ParseCallbacks;