Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite more enums in the binding generator and re-export them from skia-safe #3

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
165 changes: 141 additions & 24 deletions skia-bindings/build_support/skia.rs
Expand Up @@ -914,31 +914,129 @@ impl bindgen::callbacks::ParseCallbacks for ParseCallbacks {
type EnumEntry = (&'static str, fn(&str, &str) -> String);

const ENUM_TABLE: &[EnumEntry] = &[
("SkBlendMode", replace::k_xxx),
("SkBlendModeCoeff", replace::k_xxx),
//
// core/ effects/
//
("SkBlendMode", rewrite::k_xxx),
("SkBlendModeCoeff", rewrite::k_xxx),
("SkBlurStyle", rewrite::k_xxx_name),
("SkClipOp", rewrite::k_xxx),
("SkColorChannel", rewrite::k_xxx),
("SkCoverageMode", rewrite::k_xxx),
("SkEncodedImageFormat", rewrite::k_xxx),
("SkEncodedOrigin", rewrite::k_xxx_name),
("SkFilterQuality", rewrite::k_xxx_name),
("SkFontHinting", rewrite::k_xxx),
("SkAlphaType", rewrite::k_xxx_name),
("SkYUVColorSpace", rewrite::k_xxx_name),
("SkPathFillType", rewrite::k_xxx),
("SkPathConvexityType", rewrite::k_xxx),
("SkPathDirection", rewrite::k_xxx),
("SkPathVerb", rewrite::k_xxx),
("SkPathOp", rewrite::k_xxx_name),
("SkTileMode", rewrite::k_xxx),
// SkPaint_Style
// SkStrokeRec_Style
// SkPath1DPathEffect_Style
("Style", rewrite::k_xxx_name_opt),
// SkPaint_Cap
("Cap", rewrite::k_xxx_name),
// SkPaint_Join
("Join", rewrite::k_xxx_name),
// SkStrokeRec_InitStyle
("InitStyle", rewrite::k_xxx_name),
// SkBlurImageFilter_TileMode
// SkMatrixConvulutionImageFilter_TileMode
("TileMode", rewrite::k_xxx_name),
// SkCanvas_*
("PointMode", rewrite::k_xxx_name),
("SrcRectConstraint", rewrite::k_xxx_name),
// SkCanvas_Lattice_RectType
("RectType", rewrite::k_xxx),
// SkDisplacementMapEffect_ChannelSelectorType
("ChannelSelectorType", rewrite::k_xxx_name),
// SkDropShadowImageFilter_ShadowMode
("ShadowMode", rewrite::k_xxx_name),
// SkFont_Edging
("Edging", rewrite::k_xxx),
// SkFont_Slant
("Slant", rewrite::k_xxx_name),
// SkHighContrastConfig_InvertStyle
("InvertStyle", rewrite::k_xxx),
// SkImage_*
("BitDepth", rewrite::k_xxx),
("CachingHint", rewrite::k_xxx_name),
("CompressionType", rewrite::k_xxx_name),
// SkImageFilter_MapDirection
("MapDirection", rewrite::k_xxx_name),
// SkInterpolatorBase_Result
("Result", rewrite::k_xxx),
// SkMatrix_ScaleToFit
("ScaleToFit", rewrite::k_xxx_name),
// SkPath_*
("ArcSize", rewrite::k_xxx_name),
("AddPathMode", rewrite::k_xxx_name),
// SkRegion_Op
// TODO: remove kLastOp?
("Op", rewrite::k_xxx_name_opt),
// SkRRect_*
// TODO: remove kLastType?
("Type", rewrite::k_xxx_name_opt),
("Corner", rewrite::k_xxx_name),
// SkShader_GradientType
("GradientType", rewrite::k_xxx_name),
// SkSurface_*
("ContentChangeMode", rewrite::k_xxx_name),
("BackendHandleAccess", rewrite::k_xxx_name),
// SkTextUtils_Align
("Align", rewrite::k_xxx_name),
// SkTrimPathEffect_Mode
("Mode", rewrite::k_xxx),
// SkTypeface_SerializeBehavior
("SerializeBehavior", rewrite::k_xxx),
// SkVertices_VertexMode
("VertexMode", rewrite::k_xxx_name),
// SkYUVAIndex_Index
("Index", rewrite::k_xxx_name),
//
// gpu/
//
("GrGLStandard", rewrite::k_xxx_name),
("GrGLFormat", rewrite::k_xxx),
("GrSurfaceOrigin", rewrite::k_xxx_name),
("GrBackendApi", rewrite::k_xxx),
("GrMipMapped", rewrite::k_xxx),
("GrRenderable", rewrite::k_xxx),
("GrProtected", rewrite::k_xxx),
//
// DartTypes.h
("Affinity", replace::k_xxx),
("RectHeightStyle", replace::k_xxx),
("RectWidthStyle", replace::k_xxx),
("TextAlign", replace::k_xxx),
("TextDirection", replace::k_xxx_uppercase),
("TextBaseline", replace::k_xxx),
//
("Affinity", rewrite::k_xxx),
("RectHeightStyle", rewrite::k_xxx),
("RectWidthStyle", rewrite::k_xxx),
("TextAlign", rewrite::k_xxx),
("TextDirection", rewrite::k_xxx_uppercase),
("TextBaseline", rewrite::k_xxx),
//
// TextStyle.h
("TextDecorationStyle", replace::k_xxx),
("StyleType", replace::k_xxx),
("PlaceholderAlignment", replace::k_xxx),
//
("TextDecorationStyle", rewrite::k_xxx),
("StyleType", rewrite::k_xxx),
("PlaceholderAlignment", rewrite::k_xxx),
//
// Vk*
("VkChromaLocation", replace::vk),
("VkFilter", replace::vk),
("VkFormat", replace::vk),
("VkImageLayout", replace::vk),
("VkImageTiling", replace::vk),
("VkSamplerYcbcrModelConversion", replace::vk),
("VkSamplerYcbcrRange", replace::vk),
("VkStructureType", replace::vk),
//
("VkChromaLocation", rewrite::vk),
("VkFilter", rewrite::vk),
("VkFormat", rewrite::vk),
("VkImageLayout", rewrite::vk),
("VkImageTiling", rewrite::vk),
("VkSamplerYcbcrModelConversion", rewrite::vk),
("VkSamplerYcbcrRange", rewrite::vk),
("VkStructureType", rewrite::vk),
];

pub(crate) mod replace {
pub(crate) mod rewrite {
use heck::ShoutySnakeCase;
use regex::Regex;

Expand All @@ -958,17 +1056,36 @@ pub(crate) mod replace {
}

pub fn _k_xxx_enum(name: &str, variant: &str) -> String {
capture(variant, &format!("k(.*)_{}", name))
capture(name, variant, &format!("k(.*)_{}", name))
}

pub fn k_xxx_name_opt(name: &str, variant: &str) -> String {
let suffix = &format!("_{}", name);
if variant.ends_with(suffix) {
capture(name, variant, &format!("k(.*){}", suffix))
} else {
capture(name, variant, "k(.*)")
}
}

pub fn k_xxx_name(name: &str, variant: &str) -> String {
capture(name, variant, &format!("k(.*)_{}", name))
}

pub fn vk(name: &str, variant: &str) -> String {
let prefix = name.to_shouty_snake_case();
capture(variant, &format!("{}_(.*)", prefix))
capture(name, variant, &format!("{}_(.*)", prefix))
}

fn capture(variant: &str, pattern: &str) -> String {
fn capture(name: &str, variant: &str, pattern: &str) -> String {
let re = Regex::new(pattern).unwrap();
re.captures(variant).unwrap()[1].into()
re.captures(variant).unwrap_or_else(|| {
panic!(
"failed to match '{}' on enum variant '{}' of enum '{}'",
pattern, variant, name
)
})[1]
.into()
}
}

Expand Down
68 changes: 50 additions & 18 deletions skia-bindings/src/defaults.rs
@@ -1,31 +1,63 @@
//! This file contains Default trait implementations and functions for types that are
//! used without a handle in skia-safe and get reexported from there.
//! This file contains Default trait implementations for types that are
//! re-exported from skia-safe.

use crate::{SkBlendMode, SkBlendModeCoeff};
use std::ffi::CStr;
use crate::{
SkBlendMode, SkBlurStyle, SkCanvas_Lattice_RectType, SkClipOp, SkPaint_Cap, SkPaint_Join,
SkPathDirection, SkTileMode, SkYUVColorSpace,
};

impl Default for SkBlendMode {
fn default() -> Self {
SkBlendMode::SrcOver
}
}

impl SkBlendMode {
pub fn as_coeff(self) -> Option<(SkBlendModeCoeff, SkBlendModeCoeff)> {
let mut src = SkBlendModeCoeff::Zero;
let mut dst = SkBlendModeCoeff::Zero;
if unsafe { crate::SkBlendMode_AsCoeff(self, &mut src, &mut dst) } {
Some((src, dst))
} else {
None
}
impl Default for SkPaint_Cap {
fn default() -> Self {
SkPaint_Cap::Default
}
}

pub fn name(self) -> &'static str {
unsafe {
let name_ptr = crate::SkBlendMode_Name(self);
CStr::from_ptr(name_ptr).to_str().unwrap()
}
impl Default for SkPaint_Join {
fn default() -> Self {
SkPaint_Join::Default
}
}

impl Default for SkBlurStyle {
fn default() -> Self {
SkBlurStyle::Normal
}
}

impl Default for SkCanvas_Lattice_RectType {
fn default() -> Self {
SkCanvas_Lattice_RectType::Default
}
}

// This is the default for the canvas's clip functions.
impl Default for SkClipOp {
fn default() -> Self {
SkClipOp::Intersect
}
}

impl Default for SkYUVColorSpace {
fn default() -> Self {
SkYUVColorSpace::Identity
}
}

impl Default for SkPathDirection {
fn default() -> Self {
SkPathDirection::CW
}
}

impl Default for SkTileMode {
fn default() -> Self {
SkTileMode::Clamp
}
}

Expand Down
71 changes: 71 additions & 0 deletions skia-bindings/src/impls.rs
@@ -0,0 +1,71 @@
//! This file contains implementations for types that are
//! re-exported in skia-safe.
//!
//! We could provide trait implementations in skia-safe, but then users of the library would have to
//! import the implementation type _and_ the trait.
//!
//! See also: https://github.com/rust-lang/rfcs/issues/1880

use crate::{SkAlphaType, SkBlendMode, SkBlendModeCoeff, SkPathFillType, SkPathVerb};
use std::ffi::CStr;

impl SkBlendMode {
pub fn as_coeff(self) -> Option<(SkBlendModeCoeff, SkBlendModeCoeff)> {
let mut src = SkBlendModeCoeff::Zero;
let mut dst = SkBlendModeCoeff::Zero;
if unsafe { crate::SkBlendMode_AsCoeff(self, &mut src, &mut dst) } {
Some((src, dst))
} else {
None
}
}

pub fn name(self) -> &'static str {
unsafe {
let name_ptr = crate::SkBlendMode_Name(self);
CStr::from_ptr(name_ptr).to_str().unwrap()
}
}
}

impl SkPathVerb {
/// The maximum number of points an iterator will return for the verb.
pub const MAX_POINTS: usize = 4;
/// The number of points an iterator will return for the verb.
pub fn points(self) -> usize {
match self {
SkPathVerb::Move => 1,
SkPathVerb::Line => 2,
SkPathVerb::Quad => 3,
SkPathVerb::Conic => 4,
SkPathVerb::Cubic => 4,
SkPathVerb::Close => 0,
SkPathVerb::Done => 0,
}
}
}

impl SkPathFillType {
pub fn is_even_odd(self) -> bool {
(self as i32 & 1) != 0
}

pub fn is_inverse(self) -> bool {
(self as i32 & 2) != 0
}

pub fn to_non_inverse(self) -> Self {
match self {
SkPathFillType::Winding => self,
SkPathFillType::EvenOdd => self,
SkPathFillType::InverseWinding => SkPathFillType::Winding,
SkPathFillType::InverseEvenOdd => SkPathFillType::EvenOdd,
}
}
}

impl SkAlphaType {
pub fn is_opaque(self) -> bool {
self == SkAlphaType::Opaque
}
}
3 changes: 3 additions & 0 deletions skia-bindings/src/lib.rs
Expand Up @@ -8,5 +8,8 @@ pub use bindings::*;
mod defaults;
pub use defaults::*;

mod impls;
pub use impls::*;

#[cfg(feature = "shaper")]
pub mod icu;