AgentSkillsCN

peniko-api

当您编写使用 peniko 进行 2D 图形样式化——包括颜色、画笔、渐变、混合模式、图像或填充样式——时,可选用此方案。无论是在 peniko 代码库中工作,还是在依赖 peniko 的各类项目中,此方案皆适用。

SKILL.md
--- frontmatter
name: peniko-api
description: Use when writing Rust code that uses peniko for 2D graphics styling - colors, brushes, gradients, blend modes, images, or fill styles. Use when working in the peniko codebase or any project depending on peniko.

Peniko API Reference

Overview

Peniko is a Rust library providing 2D graphics styling primitives: colors, brushes, gradients, blend modes, and image handling. It builds on kurbo (geometry) and color (color types) crates.

Quick Reference

TypePurposeCreate With
ColorSRGB color with alphaAlphaColor<Srgb> (type alias)
BrushPaint source (solid/gradient/image).into(), Brush::Solid()
GradientColor gradientGradient::new_linear(), etc.
BlendModeHow colors combineBlendMode::new(mix, compose)
ImageBrushImage-based brushImageBrush::new(image_data)
FillPath fill ruleFill::NonZero, Fill::EvenOdd

Colors

rust
use peniko::Color;
use color::{AlphaColor, Srgb, palette};

// Color is AlphaColor<Srgb>
let red: Color = palette::css::RED.with_alpha(1.0);
let transparent = Color::default(); // fully transparent

// Any color converts to Brush
let brush: Brush = red.into();

Brushes

rust
use peniko::{Brush, BrushRef};

// Solid color
let solid = Brush::Solid(color);
let solid: Brush = color.into();

// Gradient
let grad_brush: Brush = gradient.into();

// Image
let img_brush: Brush = image_brush.into();

// Alpha manipulation
let faded = brush.with_alpha(0.5);
let dimmed = brush.multiply_alpha(0.5);

// BrushRef avoids allocation - use in function params
fn draw<'a>(brush: impl Into<BrushRef<'a>>) { ... }

Gradients

Linear Gradient

rust
use peniko::{Gradient, ColorStop, Extend};
use color::{palette, DynamicColor};

let gradient = Gradient::new_linear((0.0, 0.0), (100.0, 0.0))
    .with_stops([
        palette::css::RED.with_alpha(1.0),
        palette::css::BLUE.with_alpha(1.0),
    ]);

Radial Gradient

rust
// Simple radial (same center)
let radial = Gradient::new_radial((50.0, 50.0), 50.0)
    .with_stops(stops);

// Two-point radial (different centers/radii)
let radial = Gradient::new_two_point_radial(
    (25.0, 25.0), 10.0,  // start center, radius
    (50.0, 50.0), 50.0,  // end center, radius
).with_stops(stops);

Sweep Gradient

rust
use std::f32::consts::PI;

let sweep = Gradient::new_sweep(
    (50.0, 50.0),  // center
    0.0,           // start angle (radians)
    2.0 * PI,      // end angle
).with_stops(stops);

Gradient Options

rust
use peniko::{Extend, InterpolationAlphaSpace};
use color::{ColorSpaceTag, HueDirection};

let gradient = Gradient::new_linear(start, end)
    .with_extend(Extend::Repeat)           // Pad, Repeat, Reflect
    .with_interpolation_cs(ColorSpaceTag::Oklch)
    .with_hue_direction(HueDirection::Shorter)
    .with_interpolation_alpha_space(InterpolationAlphaSpace::Premultiplied)
    .with_stops(stops)
    .with_alpha(0.8);

Color Stops

rust
use peniko::ColorStop;

// From array of colors (evenly spaced)
let stops = [color1, color2, color3];

// Explicit offsets
let stops = [
    ColorStop { offset: 0.0, color: c1.into() },
    ColorStop { offset: 0.3, color: c2.into() },
    ColorStop { offset: 1.0, color: c3.into() },
];

Blend Modes

rust
use peniko::{BlendMode, Mix, Compose};

// Common blends
let normal = BlendMode::default();  // Normal + SrcOver
let multiply = BlendMode::new(Mix::Multiply, Compose::SrcOver);

// From just Mix or Compose
let screen: BlendMode = Mix::Screen.into();
let src_over: BlendMode = Compose::SrcOver.into();

Mix Modes (Color Blending)

Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity

Compose Modes (Layer Composition)

Clear, Copy, Dest, SrcOver, DestOver, SrcIn, DestIn, SrcOut, DestOut, SrcAtop, DestAtop, Xor, Plus, PlusLighter

Images

rust
use peniko::{ImageBrush, ImageData, ImageFormat, ImageAlphaType, ImageQuality, Extend};
use peniko::Blob;

// Create image data
let image_data = ImageData {
    data: Blob::new(Arc::new(pixels)),
    format: ImageFormat::Rgba8,  // or Bgra8
    alpha_type: ImageAlphaType::AlphaPremultiplied,
    width: 256,
    height: 256,
};

// Create image brush
let brush = ImageBrush::new(image_data)
    .with_extend(Extend::Repeat)
    .with_quality(ImageQuality::High)  // Low, Medium, High
    .with_alpha(0.9);

// Separate X/Y extend modes
let brush = ImageBrush::new(data)
    .with_x_extend(Extend::Repeat)
    .with_y_extend(Extend::Pad);

Fill and Style

rust
use peniko::{Fill, Style, StyleRef};
use kurbo::Stroke;

// Fill rules
let fill = Fill::NonZero;  // default, more correct
let fill = Fill::EvenOdd;  // for non-self-intersecting paths

// Style enum
let fill_style: Style = Fill::NonZero.into();
let stroke_style: Style = Stroke::new(2.0).into();

// StyleRef avoids cloning Stroke
fn render<'a>(style: impl Into<StyleRef<'a>>) { ... }

Extend Modes

Controls how brushes extend beyond their defined area:

ModeBehavior
Extend::PadRepeat edge color (default)
Extend::RepeatTile the pattern
Extend::ReflectMirror at boundaries

Feature Flags

toml
[dependencies]
peniko = { version = "0.6", features = ["serde"] }
FeaturePurpose
std (default)Standard library support
serdeSerialization for all types
bytemuckZero-cost type casting for GPU
libmno_std float math
mintmint math types (via kurbo)

Re-exports

rust
use peniko::color;  // color crate
use peniko::kurbo;  // kurbo crate
use peniko::{Blob, FontData, WeakBlob};  // resource handles

Common Patterns

Reference Types for APIs

rust
// Accept borrowed versions to avoid allocation
pub fn fill_rect<'a>(&mut self, brush: impl Into<BrushRef<'a>>, rect: Rect) { ... }
pub fn stroke<'a>(&mut self, style: impl Into<StyleRef<'a>>, brush: impl Into<BrushRef<'a>>) { ... }

Builder Pattern

All complex types use fluent builders:

rust
let gradient = Gradient::new_linear(p1, p2)
    .with_extend(Extend::Repeat)
    .with_stops(colors)
    .with_alpha(0.5);

Alpha Manipulation

Available on Brush, Gradient, ColorStop, ImageBrush, ImageSampler:

rust
.with_alpha(0.5)      // set absolute alpha
.multiply_alpha(0.5)  // multiply existing alpha