Sign in

    skia_mbt

    MoonBit bindings for the Skia Graphics Library

    skia
    graphics
    bindings
    Download zip
    Author
    Version
    0.1.1
    License
    Apache-2.0
    Last updated
    4 months ago
    Downloads
    46

    #wzzc-dev/skia_mbt

    MoonBit bindings for the Skia Graphics Library, structured after rust-skia/rust-skia.

    The current package exposes the first value-layer API surface:

    • geometry: Point, IPoint, Size, ISize, Rect, IRect, RRect
    • color: Color, Color4f
    • image metadata and pixel layout: ColorInfo, ImageInfo
    • copied pixel snapshots: Pixmap
    • transforms: Matrix
    • paint state: Paint, PaintStyle, StrokeCap, StrokeJoin, BlendMode
    • canvas point drawing modes: PointMode
    • image sampling: SamplingOptions, FilterMode, MipmapMode, CubicResampler
    • portable paths: Path, PathLine, PathRect, PathVerb, PathFillType, PathDirection, PathSegmentMask, including verb/point counts, contour closed queries, rectangle, oval, circle, rounded-rectangle contours, control-point and tight bounds, reset, and rewind

    Native Skia object handles are intentionally staged behind a separate FFI plan so ownership, ref-counting, and linker configuration can be validated package by package.

    The native subpackage contains the first opt-in native boundary:

    • @native.skia_available() reports whether the stub was compiled with real Skia headers and libraries;
    • @native.Surface::raster_n32_premul(size) is the first raster surface entry;
    • @native.Surface::image_snapshot() returns an immutable @native.Image handle when a surface is available;
    • @native.Surface::image_snapshot_with_bounds(bounds) snapshots a bounded surface rectangle;
    • @native.Surface::read_pixels(bounds) reads N32 premultiplied surface pixels into an owned @skia_mbt.Pixmap;
    • @native.Image::encode_to_data(format, quality) returns immutable @native.Data bytes for encoded image output;
    • @native.Image::from_bitmap(bitmap) snapshots a native bitmap into an immutable image;
    • @native.Data::from_bytes(bytes) and @native.Image::from_encoded_bytes(bytes) provide the first in-memory image decode path;
    • @native.Codec::from_data(data) and @native.Codec::from_bytes(bytes) expose encoded image metadata and decode to an N32 premultiplied Bitmap;
    • @native.Bitmap::alloc_n32_premul(size) owns raster pixel storage and can export a copied @skia_mbt.Pixmap;
    • @native.FontMgr::default() enumerates native font families and matches a family to a typeface; @native.Typeface::default() / from_name(family) and @native.Font::default(size) / from_typeface(typeface, size) create the first native text handles for drawing and measurement;
    • @native.Shader::color(color), linear_gradient(start, end, colors...), and radial_gradient(center, radius, colors...) create the first native shader handles for shader-backed paint calls;
    • @native.Path supports the first path construction calls: new, reset, rewind, set_fill_type, fill_type, move_to, line_to, quad_to, cubic_to, conic_to, close, count_points, count_verbs, segment_masks, is_finite, is_inverse_fill_type, is_last_contour_closed, last_point, is_line, is_rect, is_oval, contains, bounds, compute_tight_bounds, add_rect, add_oval, add_circle, add_round_rect, add_rrect, transform, offset, and is_empty;
    • @native.Path::from_value(path) replays a portable @skia_mbt.Path into a native path when Skia is linked;
    • @native.Canvas supports clear, draw_color, draw_paint, draw_point, draw_line, draw_points, draw_rect, draw_oval, draw_circle, draw_arc, draw_round_rect, draw_rrect, draw_drrect, draw_path, draw_image, and draw_image_rect with explicit SamplingOptions, plus portable path drawing through draw_path_value, UTF-8 text through draw_text_utf8, font measurement through Font::measure_text_utf8, glyph IDs through Font::count_text_utf8 / Font::text_to_glyphs_utf8, glyph advances through Font::glyph_width / Font::glyph_widths, glyph positions through Font::glyph_positions / Font::glyph_x_positions and Font::text_glyph_positions_utf8 / Font::text_glyph_x_positions_utf8, glyph bounds through Font::glyph_bounds / Font::glyph_bounds_many, text bounds through Font::measure_text_bounds_utf8, font metrics through Font::metrics, and color-shader paint through draw_paint_shader / draw_rect_shader;
    • @native.Canvas also exposes the first state and transform calls: save, save_layer, restore, restore_to_count, save_count, translate, scale, rotate, skew, concat, reset_matrix, and discard;
    • @native.Canvas exposes clipping with clip_rect, clip_rrect, and clip_path using ClipOp, local/device clip bound queries, and rect/path quick rejection;
    • without Skia link flags it compiles as a safe fallback and returns None.

    #Native smoke test

    The regular test suite keeps the no-Skia fallback build green by skipping the real-backend-only assertions. A real native Skia build should additionally pass the dedicated smoke test:

    cd scripts/native_smoke moon run --target native .

    The smoke module is intentionally separate from the default test suite. Without real Skia link flags it fails fast instead of silently exercising the fallback.

    For the fallback-only validation gate, run:

    .\scripts\check-fallback.ps1

    That script formats/checks the root module, runs moon info, runs the default tests, and builds the native smoke module without real Skia link flags so the smoke entry stays compileable while remaining opt-in at runtime.

    The GitHub Actions fallback workflow mirrors this gate on Windows and Linux. Real Skia smoke tests are intentionally separate until the repository owns a repeatable Skia binary/build source for CI.

    The default real-Skia binary provider is now JetBrains/skia, locked by skia-provider-lock.json to tag m148-8967a2e80c and commit 8967a2e80c71be363146da2395f503cab5f5fb9c. The fetch helpers cache packages under .skia-cache/jetbrains and print the include/lib/flag values consumed by the existing native package configurators:

    bash scripts/fetch-jetbrains-skia.sh --platform auto --arch auto --print-env

    .\scripts\fetch-jetbrains-skia.ps1 -Platform auto -Arch auto -PrintEnv

    Use REAL_SKIA_SMOKE.md as the acceptance checklist for real-backend artifacts. A passing fallback build, dry-run, or syntax check is not enough to claim real Skia acceptance.

    The smoke test requires @native.skia_available() to be true. It creates a 32x32 raster N32 premul surface, clears it to white, draws red, green, and blue rectangles, exercises draw_points in point, line, and polygon modes, checks canvas save/restore state, clip bounds, quick rejection, and clipped drawing, reads pixels back, checks representative BGRA N32 pixels, snapshots the surface, encodes the snapshot as PNG, verifies the encoded PNG signature, decodes those bytes back into an image, and decodes an N32 bitmap whose pixels still match the drawn scene and N32 channel layout.

    On Windows with a MinGW-compatible Skia build, use the acceptance wrapper to temporarily inject the native link flags, run the smoke test, save logs, and verify native/moon.pkg was restored afterwards:

    .\scripts\windows-accept-real-skia-smoke.ps1 -LogDir logs ` -SkiaInclude C:\path\to\skia ` -SkiaLibDir C:\path\to\skia\out\Static

    Pass -ExtraCcFlags or -ExtraLinkFlags if your Skia build needs additional defines or dependent libraries. The helper checks that the Skia headers and a MinGW-compatible libskia.a or skia.lib are present before rewriting package configuration. The Windows Real Skia Smoke workflow exposes the same helper as a manual job for runners that already have such a Skia build available.

    On Linux, use the acceptance wrapper. With an existing Skia build visible to the system compiler, pass its include and library paths:

    bash scripts/linux-accept-real-skia-smoke.sh --log-dir logs \ --skia-provider existing \ --skia-include /path/to/skia \ --skia-lib-dir /path/to/skia/out/Static

    Pass --extra-cc-flags or --extra-link-flags for Skia builds that need additional defines, rpaths, or dependent libraries. Add --dry-run-config to print the selected mode and effective build/smoke arguments without fetching or building Skia or rewriting native/moon.pkg; in source-build mode it prints the resolved checkout/build paths and GN args, and with existing Skia paths it also checks for the Skia header and library files and prints the exact native flags that would be injected. When libskia.so is used, the Linux smoke helper adds the supplied library directory to LD_LIBRARY_PATH before running the smoke executable. Pass --smoke-log logs/linux-native-smoke-output.log to keep the native smoke executable's stdout/stderr separate from the wrapper log.

    On macOS with an existing Skia build, use the acceptance wrapper:

    bash scripts/macos-accept-real-skia-smoke.sh --log-dir logs \ --skia-provider existing \ --skia-include /path/to/skia \ --skia-lib-dir /path/to/skia/out/Static

    The macOS helper adds common CoreFoundation/CoreGraphics/CoreText/ImageIO frameworks by default; pass --extra-link-flags for additional Skia build dependencies.

    To build a small CPU-only Skia from source for the macOS smoke test, run:

    bash scripts/macos-accept-real-skia-smoke.sh --log-dir logs \ --skia-provider source \ --work-dir .skia-cache/macos

    The macOS Real Skia Smoke workflow exposes the same path as a manual GitHub Actions job.

    To build a small CPU-only Skia from source and run the Linux smoke test in one locally with acceptance checks, run:

    bash scripts/install-linux-smoke-deps.sh bash scripts/linux-accept-real-skia-smoke.sh --work-dir .skia-cache/linux

    On an already prepared Ubuntu runner, bash scripts/install-linux-smoke-deps.sh --check verifies the same apt package set that the workflow installs before spending time on Skia checkout and build. The Linux source-build defaults install clang and pass cc="clang" / cxx="clang++" to Skia GN so the smoke build does not depend on the runner's default C++ compiler.

    When --skia-rev is omitted, the Linux source-build helpers read skia-revision.txt. Keep that file on a known-good Skia commit after the first successful real runner, or override it with --skia-rev while testing a new Skia revision. The acceptance summary log records the resolved skia_commit; use the guarded pin helpers below to write that value after a passing source-built run. Do not write JetBrains fork commits into skia-revision.txt; they are tracked in skia-provider-lock.json.

    For the first source-built Linux acceptance, the guarded pinning wrapper runs the smoke, verifies the artifact bundle with a required full commit hash, pins skia-revision.txt, and verifies the pin:

    bash scripts/linux-accept-and-pin-skia.sh --work-dir .skia-cache/linux

    It rejects dry runs and existing-build Skia paths so only a real source-built Linux acceptance can establish the initial repository pin. It checks Ubuntu smoke dependencies before starting the expensive build; pass --install-deps to install them first, or --skip-deps-check for a runner managed elsewhere.

    Without --skia-include / --skia-lib-dir, the acceptance wrapper checks out and builds Skia through scripts/linux-real-skia-smoke.sh, captures wrapper and native executable logs, verifies native/moon.pkg was restored, and checks that the executable prints skia_mbt native smoke test passed, proving the real smoke reached its final assertion. The Linux Real Skia Smoke workflow uses the same acceptance wrapper for real runs; its optional inputs can either build Skia from skia_rev or reuse an existing skia_include / skia_lib_dir pair with extra compile/link flags. It also runs weekly as an expensive real-backend canary. The workflow runs a dry-run preflight before installing build dependencies or compiling Skia, then uploads the preflight log, logs/linux-skia-build.log for source-built runs, wrapper log, and dedicated native executable log, plus the acceptance summary log, as a linux-real-skia-smoke-log artifact on success or failure. On real runs, it also greps logs/linux-native-smoke-output.log for skia_mbt native smoke test passed and records the marker check in the workflow summary. The same artifact check can be rerun manually with scripts/verify-native-smoke-log.sh logs/linux-native-smoke-output.log. The summary records the selected mode, dry-run setting, artifact name, key Skia inputs, expected log paths, the marker check, plus whether native/moon.pkg was restored after the run. Set the workflow's dry_run_config input to print the resolved build/smoke arguments without installing MoonBit/build dependencies, building Skia, restoring the Skia cache, or rewriting native/moon.pkg; with existing Skia paths it also checks for the Skia header and library files. The workflow only restores the Skia source-build cache when it is building Skia from source; extra_gn_args is ignored for existing builds.

    ///|
    test {
    let info = @skia_mbt.ImageInfo::n32_premul(@skia_mbt.ISize::new(1, 1))
    let pixmap = @skia_mbt.Pixmap::new(info, 4, b"\xff\x00\x00\xff")

    assert_true(pixmap is Some(_))
    assert_eq(info.shift_per_pixel(), 2)
    assert_eq(info.compute_min_byte_size64(), 4L)
    }

    ///|
    test {
    let paint = @skia_mbt.Paint::new(
    color=@skia_mbt.Color::from_rgb(0xff, 0, 0),
    anti_alias=true,
    )
    .set_stroke(true)
    .set_stroke_width(4)
    let path = @skia_mbt.Path::new().add_rect(
    @skia_mbt.Rect::from_xywh(0, 0, 8, 8),
    )

    assert_true(paint.style == @skia_mbt.Stroke)
    assert_true(paint.color == @skia_mbt.Color::red())
    assert_true(
    path.stroke_bounds(paint) == Some(@skia_mbt.Rect::new(-2, -2, 10, 10)),
    )
    }

    ///|
    test {
    let sampling = @skia_mbt.SamplingOptions::new(
    filter=@skia_mbt.FilterMode::Linear,
    mipmap=@skia_mbt.MipmapMode::Linear,
    )

    assert_eq(sampling.filter_ordinal(), 1)
    assert_eq(sampling.mipmap_ordinal(), 2)
    assert_true(!sampling.uses_cubic())
    }

    ///|
    test {
    let matrix = @skia_mbt.Matrix::translate(10, 20).concat(
    @skia_mbt.Matrix::scale(2, 3),
    )
    let rect = matrix.map_rect(@skia_mbt.Rect::from_xywh(0, 0, 4, 5))

    assert_true(matrix.is_invertible())
    assert_true(rect == @skia_mbt.Rect::from_xywh(10, 20, 8, 15))
    }

    ///|
    test {
    let path = @skia_mbt.Path::new(fill_type=@skia_mbt.EvenOdd).add_circle(
    @skia_mbt.Point::new(5, 5),
    5,
    direction=@skia_mbt.CCW,
    )

    let shifted = path.offset(10, 20)

    assert_eq(path.verb_count(), 6)
    assert_true(path.fill_type == @skia_mbt.EvenOdd)
    assert_true(
    shifted.bounds() == Some(@skia_mbt.Rect::from_xywh(10, 20, 10, 10)),
    )
    }

    ///|
    test {
    let rrect = @skia_mbt.RRect::new(
    @skia_mbt.Rect::from_xywh(0, 0, 10, 8),
    @skia_mbt.Size::new(2, 2),
    @skia_mbt.Size::new(3, 1),
    @skia_mbt.Size::new(1, 2),
    @skia_mbt.Size::empty(),
    )
    let path = @skia_mbt.Path::new().add_rrect(rrect)

    assert_true(!rrect.is_rect())
    assert_eq(path.verb_count(), 10)
    assert_true(path.bounds() == Some(rrect.bounds()))
    }

    Scalar

    type Scalar = Float

    Skia uses single-precision scalar values for most geometry.

    AlphaType

    pub(all) enum AlphaType {
    Unknown
    Opaque
    Premul
    Unpremul
    } derive(Eq,
    Debug
    )

    Interpretation of alpha in pixel data.

    AlphaType::is_opaque

    fn AlphaType::is_opaque(self : AlphaType) -> Bool

    BlendMode

    pub(all) enum BlendMode {
    Clear
    Src
    Dst
    SrcOver
    DstOver
    SrcIn
    DstIn
    SrcOut
    DstOut
    SrcATop
    DstATop
    Xor
    Plus
    Modulate
    Screen
    Overlay
    Darken
    Lighten
    ColorDodge
    ColorBurn
    HardLight
    SoftLight
    Difference
    Exclusion
    Multiply
    Hue
    Saturation
    Color
    Luminosity
    } derive(Eq,
    Debug
    )

    Porter-Duff and extended blend modes mirrored from Skia.

    BlendMode::to_skia_ordinal

    fn BlendMode::to_skia_ordinal(self : BlendMode) -> Int

    ClipOp

    pub(all) enum ClipOp {
    Difference
    Intersect
    } derive(Eq,
    Debug
    )

    How a new clip geometry combines with the current canvas clip.
    impl Default for ClipOp

    ClipOp::to_skia_ordinal

    fn ClipOp::to_skia_ordinal(self : ClipOp) -> Int

    Color

    pub(all) struct Color(UInt) derive(Eq,
    Debug
    )

    Packed Skia ARGB color in 0xAARRGGBB order.
    impl Default for Color

    Color::a

    fn Color::a(self : Color) -> Byte

    Color::argb

    fn Color::argb(self : Color) -> UInt

    Color::b

    fn Color::b(self : Color) -> Byte

    Color::black

    fn Color::black() -> Color

    Color::blue

    fn Color::blue() -> Color

    Color::cyan

    fn Color::cyan() -> Color

    Color::dark_gray

    fn Color::dark_gray() -> Color

    Color::from_argb

    fn Color::from_argb(a : Byte, r : Byte, g : Byte, b : Byte) -> Color

    Color::from_rgb

    fn Color::from_rgb(r : Byte, g : Byte, b : Byte) -> Color

    Color::g

    fn Color::g(self : Color) -> Byte

    Color::gray

    fn Color::gray() -> Color

    Color::green

    fn Color::green() -> Color

    Color::light_gray

    fn Color::light_gray() -> Color

    Color::magenta

    fn Color::magenta() -> Color

    Color::new

    fn Color::new(argb : UInt) -> Color

    Color::r

    fn Color::r(self : Color) -> Byte

    Color::red

    fn Color::red() -> Color

    Color::to_color4f

    fn Color::to_color4f(self : Color) -> Color4f

    Color::transparent

    fn Color::transparent() -> Color

    Color::white

    fn Color::white() -> Color

    Color::with_alpha

    fn Color::with_alpha(self : Color, alpha : Byte) -> Color

    Color::yellow

    fn Color::yellow() -> Color

    Color4f

    pub(all) struct Color4f {
    r : Float
    g : Float
    b : Float
    a : Float
    } derive(Eq,
    Debug
    )

    Floating-point RGBA color in linear component order.
    impl Default for Color4f

    Color4f::from_color

    fn Color4f::from_color(color : Color) -> Color4f

    Color4f::from_opaque

    fn Color4f::from_opaque(r : Float, g : Float, b : Float) -> Color4f

    Color4f::new

    fn Color4f::new(r : Float, g : Float, b : Float, a : Float) -> Color4f

    Color4f::scale

    fn Color4f::scale(self : Color4f, scale : Float) -> Color4f

    Color4f::transparent

    fn Color4f::transparent() -> Color4f

    Color4f::with_alpha

    fn Color4f::with_alpha(self : Color4f, alpha : Float) -> Color4f

    ColorInfo

    pub(all) struct ColorInfo {
    color_type : ColorType
    alpha_type : AlphaType
    } derive(Eq,
    Debug
    )

    Color storage metadata without a concrete color space handle.

    The native layer will attach real Skia ColorSpace handles; this value layer keeps the stable pieces needed by surfaces, pixmaps, and images.

    ColorInfo::bytes_per_pixel

    fn ColorInfo::bytes_per_pixel(self : ColorInfo) -> Int

    ColorInfo::is_opaque

    fn ColorInfo::is_opaque(self : ColorInfo) -> Bool

    ColorInfo::new

    fn ColorInfo::new(color_type? : ColorType, alpha_type? : AlphaType) -> ColorInfo

    ColorInfo::shift_per_pixel

    fn ColorInfo::shift_per_pixel(self : ColorInfo) -> Int

    ColorInfo::with_alpha_type

    fn ColorInfo::with_alpha_type(self : ColorInfo, alpha_type : AlphaType) -> ColorInfo

    ColorInfo::with_color_type

    fn ColorInfo::with_color_type(self : ColorInfo, color_type : ColorType) -> ColorInfo

    ColorType

    pub(all) enum ColorType {
    Unknown
    Alpha8
    RGB565
    ARGB4444
    RGBA8888
    RGB888x
    BGRA8888
    RGBA1010102
    RGB101010x
    Gray8
    RGBAF16
    RGBAF32
    } derive(Eq,
    Debug
    )

    Pixel storage formats common in Skia surfaces and images.

    ColorType::bytes_per_pixel

    fn ColorType::bytes_per_pixel(self : ColorType) -> Int

    ColorType::is_always_opaque

    fn ColorType::is_always_opaque(self : ColorType) -> Bool

    ColorType::shift_per_pixel

    fn ColorType::shift_per_pixel(self : ColorType) -> Int

    CubicResampler

    pub(all) struct CubicResampler {
    b : Float
    c : Float
    } derive(Eq,
    Debug
    )

    Cubic resampler coefficients for high-quality image scaling.

    CubicResampler::catmull_rom

    fn CubicResampler::catmull_rom() -> CubicResampler

    Catmull-Rom cubic resampler.

    CubicResampler::mitchell

    fn CubicResampler::mitchell() -> CubicResampler

    Mitchell-Netravali cubic resampler.

    CubicResampler::new

    fn CubicResampler::new(b : Float, c : Float) -> CubicResampler

    EncodedImageFormat

    pub(all) enum EncodedImageFormat {
    BMP
    GIF
    ICO
    JPEG
    PNG
    WBMP
    WEBP
    PKM
    KTX
    ASTC
    DNG
    HEIF
    AVIF
    JPEGXL
    } derive(Eq,
    Debug
    )

    Encoded image container formats accepted by Skia encoders.

    EncodedImageFormat::from_skia_ordinal

    fn EncodedImageFormat::from_skia_ordinal(ordinal : Int) -> EncodedImageFormat?

    EncodedImageFormat::to_skia_ordinal

    fn EncodedImageFormat::to_skia_ordinal(self : EncodedImageFormat) -> Int

    FilterMode

    pub(all) enum FilterMode {
    Nearest
    Linear
    } derive(Eq,
    Debug
    )

    Pixel reconstruction filter used when images are sampled.

    FilterMode::to_skia_ordinal

    fn FilterMode::to_skia_ordinal(self : FilterMode) -> Int

    IPoint

    pub(all) struct IPoint {
    x : Int
    y : Int
    } derive(Eq,
    Debug
    )

    Integer point or vector.
    impl Default for IPoint

    IPoint::equals

    fn IPoint::equals(self : IPoint, x : Int, y : Int) -> Bool

    IPoint::is_zero

    fn IPoint::is_zero(self : IPoint) -> Bool

    IPoint::new

    fn IPoint::new(x : Int, y : Int) -> IPoint

    IPoint::offset

    fn IPoint::offset(self : IPoint, dx : Int, dy : Int) -> IPoint

    IPoint::to_point

    fn IPoint::to_point(self : IPoint) -> Point

    IPoint::zero

    fn IPoint::zero() -> IPoint

    IRect

    pub(all) struct IRect {
    left : Int
    top : Int
    right : Int
    bottom : Int
    } derive(Eq,
    Debug
    )

    Integer rectangle stored as left/top/right/bottom bounds.
    impl Default for IRect

    IRect::contains_point

    fn IRect::contains_point(self : IRect, point : IPoint) -> Bool

    IRect::contains_rect

    fn IRect::contains_rect(self : IRect, other : IRect) -> Bool

    IRect::empty

    fn IRect::empty() -> IRect

    IRect::from_size

    fn IRect::from_size(size : ISize) -> IRect

    IRect::from_xywh

    fn IRect::from_xywh(x : Int, y : Int, width : Int, height : Int) -> IRect

    IRect::height

    fn IRect::height(self : IRect) -> Int

    IRect::inset

    fn IRect::inset(self : IRect, dx : Int, dy : Int) -> IRect

    IRect::intersect

    fn IRect::intersect(self : IRect, other : IRect) -> IRect?

    IRect::is_empty

    fn IRect::is_empty(self : IRect) -> Bool

    IRect::join

    fn IRect::join(self : IRect, other : IRect) -> IRect

    IRect::new

    fn IRect::new(left : Int, top : Int, right : Int, bottom : Int) -> IRect

    IRect::offset

    fn IRect::offset(self : IRect, dx : Int, dy : Int) -> IRect

    IRect::outset

    fn IRect::outset(self : IRect, dx : Int, dy : Int) -> IRect

    IRect::size

    fn IRect::size(self : IRect) -> ISize

    IRect::sorted

    fn IRect::sorted(self : IRect) -> IRect

    IRect::to_rect

    fn IRect::to_rect(self : IRect) -> Rect

    IRect::width

    fn IRect::width(self : IRect) -> Int

    ISize

    pub(all) struct ISize {
    width : Int
    height : Int
    } derive(Eq,
    Debug
    )

    Integer width and height.
    impl Default for ISize

    ISize::area

    fn ISize::area(self : ISize) -> Int64

    ISize::empty

    fn ISize::empty() -> ISize

    ISize::is_empty

    fn ISize::is_empty(self : ISize) -> Bool

    ISize::is_zero

    fn ISize::is_zero(self : ISize) -> Bool

    ISize::new

    fn ISize::new(width : Int, height : Int) -> ISize

    ISize::to_size

    fn ISize::to_size(self : ISize) -> Size

    ImageInfo

    pub(all) struct ImageInfo {
    dimensions : ISize
    color_info : ColorInfo
    } derive(Eq,
    Debug
    )

    Dimensions plus color metadata for images, bitmaps, pixmaps, and surfaces.

    ImageInfo::a8

    fn ImageInfo::a8(dimensions : ISize) -> ImageInfo

    ImageInfo::alpha_type

    fn ImageInfo::alpha_type(self : ImageInfo) -> AlphaType

    ImageInfo::bounds

    fn ImageInfo::bounds(self : ImageInfo) -> IRect

    ImageInfo::bytes_per_pixel

    fn ImageInfo::bytes_per_pixel(self : ImageInfo) -> Int

    ImageInfo::color_type

    fn ImageInfo::color_type(self : ImageInfo) -> ColorType

    ImageInfo::compute_byte_size

    fn ImageInfo::compute_byte_size(self : ImageInfo, row_bytes : Int) -> Int

    ImageInfo::compute_byte_size64

    fn ImageInfo::compute_byte_size64(self : ImageInfo, row_bytes : Int) -> Int64

    ImageInfo::compute_min_byte_size

    fn ImageInfo::compute_min_byte_size(self : ImageInfo) -> Int

    ImageInfo::compute_min_byte_size64

    fn ImageInfo::compute_min_byte_size64(self : ImageInfo) -> Int64

    ImageInfo::compute_offset

    fn ImageInfo::compute_offset(self : ImageInfo, point : IPoint, row_bytes : Int) -> Int

    ImageInfo::from_color_info

    fn ImageInfo::from_color_info(dimensions : ISize, color_info : ColorInfo) -> ImageInfo

    ImageInfo::height

    fn ImageInfo::height(self : ImageInfo) -> Int

    ImageInfo::is_empty

    fn ImageInfo::is_empty(self : ImageInfo) -> Bool

    ImageInfo::is_opaque

    fn ImageInfo::is_opaque(self : ImageInfo) -> Bool

    ImageInfo::min_row_bytes

    fn ImageInfo::min_row_bytes(self : ImageInfo) -> Int

    ImageInfo::min_row_bytes64

    fn ImageInfo::min_row_bytes64(self : ImageInfo) -> Int64

    ImageInfo::n32_premul

    fn ImageInfo::n32_premul(dimensions : ISize) -> ImageInfo

    ImageInfo::new

    fn ImageInfo::new(dimensions : ISize, color_type? : ColorType, alpha_type? : AlphaType) -> ImageInfo

    ImageInfo::shift_per_pixel

    fn ImageInfo::shift_per_pixel(self : ImageInfo) -> Int

    ImageInfo::unknown

    fn ImageInfo::unknown(dimensions? : ISize) -> ImageInfo

    ImageInfo::valid_pixels

    fn ImageInfo::valid_pixels(self : ImageInfo, row_bytes : Int) -> Bool

    ImageInfo::valid_row_bytes

    fn ImageInfo::valid_row_bytes(self : ImageInfo, row_bytes : Int) -> Bool

    ImageInfo::width

    fn ImageInfo::width(self : ImageInfo) -> Int

    ImageInfo::with_alpha_type

    fn ImageInfo::with_alpha_type(self : ImageInfo, alpha_type : AlphaType) -> ImageInfo

    ImageInfo::with_color_type

    fn ImageInfo::with_color_type(self : ImageInfo, color_type : ColorType) -> ImageInfo

    ImageInfo::with_dimensions

    fn ImageInfo::with_dimensions(self : ImageInfo, dimensions : ISize) -> ImageInfo

    Matrix

    pub(all) struct Matrix {
    scale_x : Float
    skew_x : Float
    trans_x : Float
    skew_y : Float
    scale_y : Float
    trans_y : Float
    persp_0 : Float
    persp_1 : Float
    persp_2 : Float
    } derive(Eq,
    Debug
    )

    Row-major 3x3 transform matrix matching Skia's public member layout.
    impl Default for Matrix

    Matrix::concat

    fn Matrix::concat(self : Matrix, other : Matrix) -> Matrix

    Matrix::determinant

    fn Matrix::determinant(self : Matrix) -> Float

    Matrix::get

    fn Matrix::get(self : Matrix, field : MatrixMember) -> Float

    Matrix::has_perspective

    fn Matrix::has_perspective(self : Matrix) -> Bool

    Matrix::identity

    fn Matrix::identity() -> Matrix

    Matrix::invert

    fn Matrix::invert(self : Matrix) -> Matrix?

    Matrix::is_identity

    fn Matrix::is_identity(self : Matrix) -> Bool

    Matrix::is_invertible

    fn Matrix::is_invertible(self : Matrix) -> Bool

    Matrix::is_scale_translate

    fn Matrix::is_scale_translate(self : Matrix) -> Bool

    Matrix::is_translate

    fn Matrix::is_translate(self : Matrix) -> Bool

    Matrix::map_point

    fn Matrix::map_point(self : Matrix, point : Point) -> Point

    Matrix::map_rect

    fn Matrix::map_rect(self : Matrix, rect : Rect) -> Rect

    Matrix::new_all

    fn Matrix::new_all(scale_x : Float, skew_x : Float, trans_x : Float, skew_y : Float, scale_y : Float, trans_y : Float, persp_0 : Float, persp_1 : Float, persp_2 : Float) -> Matrix

    Matrix::post_concat

    fn Matrix::post_concat(self : Matrix, other : Matrix) -> Matrix

    Matrix::pre_concat

    fn Matrix::pre_concat(self : Matrix, other : Matrix) -> Matrix

    Matrix::scale

    fn Matrix::scale(sx : Float, sy : Float) -> Matrix

    Matrix::scale_translate

    fn Matrix::scale_translate(sx : Float, sy : Float, tx : Float, ty : Float) -> Matrix

    Matrix::skew

    fn Matrix::skew(kx : Float, ky : Float) -> Matrix

    Matrix::translate

    fn Matrix::translate(dx : Float, dy : Float) -> Matrix

    MatrixMember

    pub(all) enum MatrixMember {
    ScaleX
    SkewX
    TransX
    SkewY
    ScaleY
    TransY
    Persp0
    Persp1
    Persp2
    } derive(Eq,
    Debug
    )

    Member positions in a 3x3 Skia matrix.

    MipmapMode

    pub(all) enum MipmapMode {
    None
    Nearest
    Linear
    } derive(Eq,
    Debug
    )

    Mipmap sampling mode used together with FilterMode.

    MipmapMode::to_skia_ordinal

    fn MipmapMode::to_skia_ordinal(self : MipmapMode) -> Int

    Paint

    pub(all) struct Paint {
    color : Color
    anti_alias : Bool
    dither : Bool
    style : PaintStyle
    stroke_width : Float
    stroke_miter : Float
    stroke_cap : StrokeCap
    stroke_join : StrokeJoin
    blend_mode : BlendMode
    } derive(Eq,
    Debug
    )

    Value-layer paint state modeled after skia_safe::Paint.

    Native Skia paints will use a separate handle type once the C++ FFI layer is wired to real Skia binaries.
    impl Default for Paint

    Paint::alpha

    fn Paint::alpha(self : Paint) -> Byte

    Paint::blend_mode_ordinal

    fn Paint::blend_mode_ordinal(self : Paint) -> Int

    Paint::color_argb

    fn Paint::color_argb(self : Paint) -> UInt

    Paint::new

    fn Paint::new(color? : Color, anti_alias? : Bool, dither? : Bool, style? : PaintStyle, stroke_width? : Float, stroke_miter? : Float, stroke_cap? : StrokeCap, stroke_join? : StrokeJoin, blend_mode? : BlendMode) -> Paint

    Paint::reset

    fn Paint::reset(self : Paint) -> Paint

    Paint::set_alpha

    fn Paint::set_alpha(self : Paint, alpha : Byte) -> Paint

    Paint::set_anti_alias

    fn Paint::set_anti_alias(self : Paint, anti_alias : Bool) -> Paint

    Paint::set_argb

    fn Paint::set_argb(self : Paint, a : Byte, r : Byte, g : Byte, b : Byte) -> Paint

    Paint::set_blend_mode

    fn Paint::set_blend_mode(self : Paint, blend_mode : BlendMode) -> Paint

    Paint::set_color

    fn Paint::set_color(self : Paint, color : Color) -> Paint

    Paint::set_dither

    fn Paint::set_dither(self : Paint, dither : Bool) -> Paint

    Paint::set_stroke

    fn Paint::set_stroke(self : Paint, stroke : Bool) -> Paint

    Paint::set_stroke_cap

    fn Paint::set_stroke_cap(self : Paint, stroke_cap : StrokeCap) -> Paint

    Paint::set_stroke_join

    fn Paint::set_stroke_join(self : Paint, stroke_join : StrokeJoin) -> Paint

    Paint::set_stroke_miter

    fn Paint::set_stroke_miter(self : Paint, stroke_miter : Float) -> Paint

    Paint::set_stroke_width

    fn Paint::set_stroke_width(self : Paint, stroke_width : Float) -> Paint

    Paint::set_style

    fn Paint::set_style(self : Paint, style : PaintStyle) -> Paint

    Paint::stroke_cap_ordinal

    fn Paint::stroke_cap_ordinal(self : Paint) -> Int

    Paint::stroke_join_ordinal

    fn Paint::stroke_join_ordinal(self : Paint) -> Int

    Paint::style_ordinal

    fn Paint::style_ordinal(self : Paint) -> Int

    PaintStyle

    pub(all) enum PaintStyle {
    Fill
    Stroke
    StrokeAndFill
    } derive(Eq,
    Debug
    )

    How paint geometry is rasterized.

    PaintStyle::to_skia_ordinal

    fn PaintStyle::to_skia_ordinal(self : PaintStyle) -> Int

    Path

    pub(all) struct Path {
    fill_type : PathFillType
    verbs : Array[PathVerb]
    current_point : Point?
    } derive(Eq,
    Debug
    )

    Cross-platform path value.

    The native package owns real SkPath handles. This value layer keeps a portable path command stream that can be built, inspected, and tested on all MoonBit targets before being converted at a native boundary.
    impl Default for Path

    Path::add_circle

    fn Path::add_circle(self : Path, center : Point, radius : Float, direction? : PathDirection) -> Path

    Path::add_oval

    fn Path::add_oval(self : Path, oval : Rect, direction? : PathDirection) -> Path

    Path::add_rect

    fn Path::add_rect(self : Path, rect : Rect, direction? : PathDirection) -> Path

    Path::add_round_rect

    fn Path::add_round_rect(self : Path, rect : Rect, rx : Float, ry : Float, direction? : PathDirection) -> Path

    Path::add_rrect

    fn Path::add_rrect(self : Path, rrect : RRect, direction? : PathDirection) -> Path

    Path::bounds

    fn Path::bounds(self : Path) -> Rect?

    Path::close

    fn Path::close(self : Path) -> Path

    Path::compute_tight_bounds

    fn Path::compute_tight_bounds(self : Path) -> Rect?

    Computes a tighter geometric bound for quadratic, conic, and cubic curves.

    bounds records the path's control-point bounds, matching Skia's cached path bounds. This method mirrors Skia's computeTightBounds distinction by adding only curve extrema that affect the actual drawn curve.

    Path::conic_to

    fn Path::conic_to(self : Path, control : Point, end : Point, weight : Float) -> Path

    Path::contains

    fn Path::contains(self : Path, point : Point) -> Bool

    Returns whether point is inside the portable path approximation.

    This value-layer implementation treats line segments exactly and uses curve endpoints for curved verbs. The native package delegates Path::contains to Skia for full curve-aware containment when Skia is linked.

    Path::count_points

    fn Path::count_points(self : Path) -> Int

    Path::count_verbs

    fn Path::count_verbs(self : Path) -> Int

    Path::cubic_to

    fn Path::cubic_to(self : Path, control0 : Point, control1 : Point, end : Point) -> Path

    Path::is_empty

    fn Path::is_empty(self : Path) -> Bool

    Path::is_finite

    fn Path::is_finite(self : Path) -> Bool

    Path::is_inverse_fill_type

    fn Path::is_inverse_fill_type(self : Path) -> Bool

    Path::is_last_contour_closed

    fn Path::is_last_contour_closed(self : Path) -> Bool

    Path::is_line

    fn Path::is_line(self : Path) -> PathLine?

    Path::is_oval

    fn Path::is_oval(self : Path) -> Rect?

    Path::is_rect

    fn Path::is_rect(self : Path) -> PathRect?

    Path::last_point

    fn Path::last_point(self : Path) -> Point?

    Path::line_to

    fn Path::line_to(self : Path, point : Point) -> Path

    Path::move_to

    fn Path::move_to(self : Path, point : Point) -> Path

    Path::new

    fn Path::new(fill_type? : PathFillType) -> Path

    Path::offset

    fn Path::offset(self : Path, dx : Float, dy : Float) -> Path

    Path::quad_to

    fn Path::quad_to(self : Path, control : Point, end : Point) -> Path

    Path::reset

    fn Path::reset(self : Path) -> Path

    Path::rewind

    fn Path::rewind(self : Path) -> Path

    Path::segment_masks

    fn Path::segment_masks(self : Path) -> PathSegmentMask

    Path::stroke_bounds

    fn Path::stroke_bounds(self : Path, paint : Paint) -> Rect?

    Path::transform

    fn Path::transform(self : Path, matrix : Matrix) -> Path

    Path::verb_count

    fn Path::verb_count(self : Path) -> Int

    Path::with_fill_type

    fn Path::with_fill_type(self : Path, fill_type : PathFillType) -> Path

    PathDirection

    pub(all) enum PathDirection {
    CW
    CCW
    } derive(Eq,
    Debug
    )

    Direction used when adding closed contours.

    PathDirection::to_skia_ordinal

    fn PathDirection::to_skia_ordinal(self : PathDirection) -> Int

    PathFillType

    pub(all) enum PathFillType {
    Winding
    EvenOdd
    InverseWinding
    InverseEvenOdd
    } derive(Eq,
    Debug
    )

    Fill rule used when rasterizing a path.

    PathFillType::is_inverse

    fn PathFillType::is_inverse(self : PathFillType) -> Bool

    PathFillType::to_skia_ordinal

    fn PathFillType::to_skia_ordinal(self : PathFillType) -> Int

    PathLine

    pub(all) struct PathLine {
    start : Point
    end : Point
    } derive(Eq,
    Debug
    )

    A single line segment recognized from a path.

    PathLine::new

    fn PathLine::new(start : Point, end : Point) -> PathLine

    PathRect

    pub(all) struct PathRect {
    rect : Rect
    is_closed : Bool
    direction : PathDirection
    } derive(Eq,
    Debug
    )

    Rectangle recognized from a path, plus Skia's closed and direction metadata.

    PathRect::new

    fn PathRect::new(rect : Rect, is_closed : Bool, direction : PathDirection) -> PathRect

    PathSegmentMask

    pub(all) struct PathSegmentMask(Int) derive(Eq,
    Debug
    )

    Bitmask of path segment kinds, matching Skia's public segment-mask values.

    PathSegmentMask::bits

    fn PathSegmentMask::bits(self : PathSegmentMask) -> Int

    PathSegmentMask::conic

    PathSegmentMask::contains

    fn PathSegmentMask::contains(self : PathSegmentMask, other : PathSegmentMask) -> Bool

    PathSegmentMask::cubic

    PathSegmentMask::empty

    PathSegmentMask::line

    PathSegmentMask::new

    fn PathSegmentMask::new(value : Int) -> PathSegmentMask

    PathSegmentMask::quad

    PathVerb

    pub(all) enum PathVerb {
    MoveTo(Point)
    LineTo(Point)
    QuadTo(Point, Point)
    ConicTo(Point, Point, Float)
    CubicTo(Point, Point, Point)
    Close
    } derive(Eq,
    Debug
    )

    Cross-platform path verb data modeled after Skia path commands.

    Pixmap

    pub(all) struct Pixmap {
    image_info : ImageInfo
    row_bytes : Int
    pixels : Bytes
    } derive(Eq,
    Debug
    )

    Immutable pixel snapshot plus layout metadata.

    This mirrors the lightweight role of Skia's SkPixmap, but owns the copied bytes on the MoonBit side so it is safe across backend boundaries.

    Pixmap::alpha_type

    fn Pixmap::alpha_type(self : Pixmap) -> AlphaType

    Pixmap::bounds

    fn Pixmap::bounds(self : Pixmap) -> IRect

    Pixmap::byte_size

    fn Pixmap::byte_size(self : Pixmap) -> Int

    Pixmap::byte_size64

    fn Pixmap::byte_size64(self : Pixmap) -> Int64

    Pixmap::bytes_per_pixel

    fn Pixmap::bytes_per_pixel(self : Pixmap) -> Int

    Pixmap::color_type

    fn Pixmap::color_type(self : Pixmap) -> ColorType

    Pixmap::contains

    fn Pixmap::contains(self : Pixmap, point : IPoint) -> Bool

    Pixmap::dimensions

    fn Pixmap::dimensions(self : Pixmap) -> ISize

    Pixmap::height

    fn Pixmap::height(self : Pixmap) -> Int

    Pixmap::is_empty

    fn Pixmap::is_empty(self : Pixmap) -> Bool

    Pixmap::new

    fn Pixmap::new(image_info : ImageInfo, row_bytes : Int, pixels : Bytes) -> Pixmap?

    Pixmap::offset

    fn Pixmap::offset(self : Pixmap, point : IPoint) -> Int?

    Pixmap::row_bytes

    fn Pixmap::row_bytes(self : Pixmap) -> Int

    Pixmap::shift_per_pixel

    fn Pixmap::shift_per_pixel(self : Pixmap) -> Int

    Pixmap::width

    fn Pixmap::width(self : Pixmap) -> Int

    Point

    pub(all) struct Point {
    x : Float
    y : Float
    } derive(Eq,
    Debug
    )

    Floating-point point or vector.
    impl Default for Point

    Point::distance_to_origin

    fn Point::distance_to_origin(self : Point) -> Float

    Point::equals

    fn Point::equals(self : Point, x : Float, y : Float) -> Bool

    Point::is_zero

    fn Point::is_zero(self : Point) -> Bool

    Point::length

    fn Point::length(self : Point) -> Float

    Point::new

    fn Point::new(x : Float, y : Float) -> Point

    Point::offset

    fn Point::offset(self : Point, dx : Float, dy : Float) -> Point

    Point::scale

    fn Point::scale(self : Point, scale : Float) -> Point

    Point::to_ipoint_round

    fn Point::to_ipoint_round(self : Point) -> IPoint

    Point::zero

    fn Point::zero() -> Point

    PointMode

    pub(all) enum PointMode {
    Points
    Lines
    Polygon
    } derive(Eq,
    Debug
    )

    How Canvas::draw_points interprets a point array.

    PointMode::to_skia_ordinal

    fn PointMode::to_skia_ordinal(self : PointMode) -> Int

    RRect

    pub(all) struct RRect {
    rect : Rect
    upper_left : Size
    upper_right : Size
    lower_right : Size
    lower_left : Size
    } derive(Eq,
    Debug
    )

    Rounded rectangle bounds plus per-corner x/y radii.

    Corners are stored in Skia order: upper-left, upper-right, lower-right, lower-left.
    impl Default for RRect

    RRect::bounds

    fn RRect::bounds(self : RRect) -> Rect

    RRect::empty

    fn RRect::empty() -> RRect

    RRect::from_oval

    fn RRect::from_oval(oval : Rect) -> RRect

    RRect::from_rect

    fn RRect::from_rect(rect : Rect) -> RRect

    RRect::from_rect_xy

    fn RRect::from_rect_xy(rect : Rect, rx : Float, ry : Float) -> RRect

    RRect::height

    fn RRect::height(self : RRect) -> Float

    RRect::is_empty

    fn RRect::is_empty(self : RRect) -> Bool

    RRect::is_oval

    fn RRect::is_oval(self : RRect) -> Bool

    RRect::is_rect

    fn RRect::is_rect(self : RRect) -> Bool

    RRect::is_simple

    fn RRect::is_simple(self : RRect) -> Bool

    RRect::new

    fn RRect::new(rect : Rect, upper_left : Size, upper_right : Size, lower_right : Size, lower_left : Size) -> RRect

    RRect::offset

    fn RRect::offset(self : RRect, dx : Float, dy : Float) -> RRect

    RRect::width

    fn RRect::width(self : RRect) -> Float

    Rect

    pub(all) struct Rect {
    left : Float
    top : Float
    right : Float
    bottom : Float
    } derive(Eq,
    Debug
    )

    Floating-point rectangle stored as left/top/right/bottom bounds.
    impl Default for Rect

    Rect::contains_point

    fn Rect::contains_point(self : Rect, point : Point) -> Bool

    Rect::contains_rect

    fn Rect::contains_rect(self : Rect, other : Rect) -> Bool

    Rect::empty

    fn Rect::empty() -> Rect

    Rect::from_size

    fn Rect::from_size(size : Size) -> Rect

    Rect::from_xywh

    fn Rect::from_xywh(x : Float, y : Float, width : Float, height : Float) -> Rect

    Rect::height

    fn Rect::height(self : Rect) -> Float

    Rect::inset

    fn Rect::inset(self : Rect, dx : Float, dy : Float) -> Rect

    Rect::intersect

    fn Rect::intersect(self : Rect, other : Rect) -> Rect?

    Rect::is_empty

    fn Rect::is_empty(self : Rect) -> Bool

    Rect::join

    fn Rect::join(self : Rect, other : Rect) -> Rect

    Rect::new

    fn Rect::new(left : Float, top : Float, right : Float, bottom : Float) -> Rect

    Rect::offset

    fn Rect::offset(self : Rect, dx : Float, dy : Float) -> Rect

    Rect::outset

    fn Rect::outset(self : Rect, dx : Float, dy : Float) -> Rect

    Rect::size

    fn Rect::size(self : Rect) -> Size

    Rect::sorted

    fn Rect::sorted(self : Rect) -> Rect

    Rect::to_irect_round

    fn Rect::to_irect_round(self : Rect) -> IRect

    Rect::width

    fn Rect::width(self : Rect) -> Float

    SamplingOptions

    pub(all) struct SamplingOptions {
    filter : FilterMode
    mipmap : MipmapMode
    cubic : CubicResampler?
    } derive(Eq,
    Debug
    )

    Image sampling options modeled after Skia's SkSamplingOptions.

    SamplingOptions::catmull_rom

    fn SamplingOptions::catmull_rom() -> SamplingOptions

    SamplingOptions::cubic_b

    fn SamplingOptions::cubic_b(self : SamplingOptions) -> Float

    SamplingOptions::cubic_c

    fn SamplingOptions::cubic_c(self : SamplingOptions) -> Float

    SamplingOptions::filter_ordinal

    fn SamplingOptions::filter_ordinal(self : SamplingOptions) -> Int

    SamplingOptions::from_cubic

    SamplingOptions::linear

    SamplingOptions::mipmap_ordinal

    fn SamplingOptions::mipmap_ordinal(self : SamplingOptions) -> Int

    SamplingOptions::mitchell

    SamplingOptions::new

    fn SamplingOptions::new(filter? : FilterMode, mipmap? : MipmapMode) -> SamplingOptions

    SamplingOptions::uses_cubic

    fn SamplingOptions::uses_cubic(self : SamplingOptions) -> Bool

    Size

    pub(all) struct Size {
    width : Float
    height : Float
    } derive(Eq,
    Debug
    )

    Floating-point width and height.
    impl Default for Size

    Size::empty

    fn Size::empty() -> Size

    Size::from_isize

    fn Size::from_isize(size : ISize) -> Size

    Size::is_empty

    fn Size::is_empty(self : Size) -> Bool

    Size::is_zero

    fn Size::is_zero(self : Size) -> Bool

    Size::new

    fn Size::new(width : Float, height : Float) -> Size

    Size::scale

    fn Size::scale(self : Size, scale : Float) -> Size

    Size::to_isize_round

    fn Size::to_isize_round(self : Size) -> ISize

    StrokeCap

    pub(all) enum StrokeCap {
    Butt
    Round
    Square
    } derive(Eq,
    Debug
    )

    Shape used at the end of an open stroked contour.

    StrokeCap::to_skia_ordinal

    fn StrokeCap::to_skia_ordinal(self : StrokeCap) -> Int

    StrokeJoin

    pub(all) enum StrokeJoin {
    Miter
    Round
    Bevel
    } derive(Eq,
    Debug
    )

    Shape used when two stroked segments meet.

    StrokeJoin::to_skia_ordinal

    fn StrokeJoin::to_skia_ordinal(self : StrokeJoin) -> Int

    TileMode

    pub(all) enum TileMode {
    Clamp
    Repeat
    Mirror
    Decal
    } derive(Eq,
    Debug
    )

    Sampling behavior when coordinates land outside shader bounds.
    impl Default for TileMode

    TileMode::to_skia_ordinal

    fn TileMode::to_skia_ordinal(self : TileMode) -> Int

    binding_status

    fn binding_status() -> String

    Project status for the current package.

    The value-layer types are usable today. Native Skia object bindings are introduced separately so their ownership and linker requirements stay explicit.