### Install Rust Nightly Toolchain Source: https://github.com/linebender/tiny-skia/blob/main/benches/README.md Installs the nightly version of the Rust toolchain, which is required for running benchmarks. ```sh rustup toolchain install nightly ``` -------------------------------- ### Run Benchmarks with Additional Features Source: https://github.com/linebender/tiny-skia/blob/main/benches/README.md Runs benchmarks for tiny-skia, enabling support for external libraries like skia-rs, raqote, and cairo-rs. Ensure these libraries are installed and Skia is built from source. ```sh # those are skia-rs specific exports export SKIA_DIR="/path/to/skia" export SKIA_LIB_DIR="/path/to/skia/out/Shared" export LD_LIBRARY_PATH="/path/to/skia/out/Shared" rustup run nightly cargo bench --features skia-rs,raqote,cairo-rs ``` -------------------------------- ### Run Tiny-skia Benchmarks Source: https://github.com/linebender/tiny-skia/blob/main/benches/README.md Executes the benchmarks for tiny-skia using the installed nightly Rust toolchain. ```sh rustup run nightly cargo bench ``` -------------------------------- ### Compositing Pixmaps with Blend Modes in Tiny-Skia Source: https://context7.com/linebender/tiny-skia/llms.txt Illustrates drawing pixmaps onto another pixmap using various blend modes for image compositing. Includes examples of different blend modes and applying transformations. ```rust use tiny_skia::* fn main() { // Create source image let source = { let mut pm = Pixmap::new(200, 200).unwrap(); let mut paint = Paint::default(); paint.set_color_rgba8(50, 127, 150, 200); paint.anti_alias = true; let path = PathBuilder::from_circle(100.0, 100.0, 80.0).unwrap(); pm.fill_path(&path, &paint, FillRule::Winding, Transform::identity(), None); pm }; let mut pixmap = Pixmap::new(400, 400).unwrap(); pixmap.fill(Color::from_rgba8(200, 200, 200, 255)); // Configure pixmap paint let mut paint = PixmapPaint::default(); paint.opacity = 1.0; paint.blend_mode = BlendMode::SourceOver; // Default blending paint.quality = FilterQuality::Bicubic; // Draw source pixmap at position (20, 20) pixmap.draw_pixmap( 20, 20, source.as_ref(), &paint, Transform::identity(), None, ); // Draw with different blend modes paint.blend_mode = BlendMode::Multiply; pixmap.draw_pixmap(100, 20, source.as_ref(), &paint, Transform::identity(), None); paint.blend_mode = BlendMode::Screen; pixmap.draw_pixmap(180, 20, source.as_ref(), &paint, Transform::identity(), None); paint.blend_mode = BlendMode::Overlay; pixmap.draw_pixmap(20, 120, source.as_ref(), &paint, Transform::identity(), None); // Draw with transformation paint.blend_mode = BlendMode::SourceOver; let transform = Transform::from_row(1.2, 0.5, 0.5, 1.2, 0.0, 0.0); pixmap.draw_pixmap(200, 200, source.as_ref(), &paint, transform, None); // Available blend modes: Clear, Source, Destination, SourceOver, DestinationOver, // SourceIn, DestinationIn, SourceOut, DestinationOut, SourceAtop, DestinationAtop, // Xor, Plus, Modulate, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, // HardLight, SoftLight, Difference, Exclusion, Multiply, Hue, Saturation, Color, Luminosity pixmap.save_png("composited.png").unwrap(); } ``` -------------------------------- ### Create Radial Gradient Paint Source: https://context7.com/linebender/tiny-skia/llms.txt Use RadialGradient to create a paint object for radial color transitions. This can be used for simple circular gradients or two-point conical gradients by specifying different start and end centers and radii. Supports Pad and other spread modes. ```rust use tiny_skia::* fn main() { let mut pixmap = Pixmap::new(500, 500).unwrap(); // Simple radial gradient (start radius = 0) let mut paint = Paint::default(); paint.shader = RadialGradient::new( Point::from_xy(250.0, 250.0), // Start center 0.0, // Start radius Point::from_xy(250.0, 250.0), // End center (same for circular gradient) 200.0, // End radius vec![ GradientStop::new(0.0, Color::from_rgba8(255, 255, 0, 255)), // Yellow center GradientStop::new(0.5, Color::from_rgba8(255, 128, 0, 255)), // Orange middle GradientStop::new(1.0, Color::from_rgba8(255, 0, 0, 255)), // Red edge ], SpreadMode::Pad, Transform::identity(), ).unwrap(); // Fill a rectangle to see the full gradient let rect = Rect::from_xywh(0.0, 0.0, 500.0, 500.0).unwrap(); pixmap.fill_rect(rect, &paint, Transform::identity(), None); // Two-point conical gradient (different centers) let mut conical_paint = Paint::default(); conical_paint.shader = RadialGradient::new( Point::from_xy(150.0, 250.0), // Start center 50.0, // Start radius Point::from_xy(350.0, 250.0), // End center 100.0, // End radius vec![ GradientStop::new(0.0, Color::from_rgba8(0, 100, 200, 255)), GradientStop::new(1.0, Color::from_rgba8(200, 50, 100, 255)), ], SpreadMode::Pad, Transform::identity(), ).unwrap(); pixmap.save_png("radial_gradient.png").unwrap(); } ``` -------------------------------- ### Create and Manage Pixmaps in tiny-skia Source: https://context7.com/linebender/tiny-skia/llms.txt Demonstrates creating a Pixmap, filling it with color, accessing individual pixels, retrieving raw data, cloning regions, and saving to a PNG file. Requires `tiny_skia::*` imports. ```rust use tiny_skia::* fn main() { // Create a new 500x500 pixmap (initialized to transparent black) let mut pixmap = Pixmap::new(500, 500).unwrap(); // Fill entire pixmap with a solid color pixmap.fill(Color::from_rgba8(255, 255, 255, 255)); // Access individual pixel if let Some(pixel) = pixmap.pixel(100, 100) { println!("Pixel at (100,100): r={}, g={}, b={}, a={}", pixel.red(), pixel.green(), pixel.blue(), pixel.alpha()); } // Get pixmap dimensions println!("Size: {}x{}", pixmap.width(), pixmap.height()); // Access raw pixel data let data: &[u8] = pixmap.data(); let pixels: &[PremultipliedColorU8] = pixmap.pixels(); // Clone a rectangular region let rect = IntRect::from_xywh(10, 10, 100, 100).unwrap(); let sub_pixmap = pixmap.clone_rect(rect); // Save to PNG file pixmap.save_png("output.png").unwrap(); } ``` -------------------------------- ### Build and Transform Paths in tiny-skia Source: https://context7.com/linebender/tiny-skia/llms.txt Illustrates creating custom vector paths using `PathBuilder` with various commands like `move_to`, `line_to`, `quad_to`, and `cubic_to`. Also shows creating paths from geometric shapes (rect, circle, oval) and transforming paths. Requires `tiny_skia::*` imports. ```rust use tiny_skia::* fn main() { let mut pixmap = Pixmap::new(500, 500).unwrap(); // Build a custom path let path = { let mut pb = PathBuilder::new(); pb.move_to(100.0, 100.0); // Start point pb.line_to(200.0, 100.0); // Line segment pb.quad_to(250.0, 150.0, 200.0, 200.0); // Quadratic curve pb.cubic_to(150.0, 250.0, 100.0, 250.0, 100.0, 200.0); // Cubic curve pb.close(); // Close the contour pb.finish().unwrap() }; // Create path from rectangle let rect = Rect::from_xywh(50.0, 50.0, 100.0, 80.0).unwrap(); let rect_path = PathBuilder::from_rect(rect); // Create path from circle let circle_path = PathBuilder::from_circle(250.0, 250.0, 50.0).unwrap(); // Create path from oval let oval_rect = Rect::from_xywh(300.0, 100.0, 150.0, 100.0).unwrap(); let oval_path = PathBuilder::from_oval(oval_rect).unwrap(); // Build path with push methods let mut pb = PathBuilder::new(); pb.push_rect(Rect::from_xywh(10.0, 10.0, 50.0, 50.0).unwrap()); pb.push_circle(100.0, 100.0, 30.0); pb.push_oval(Rect::from_xywh(150.0, 50.0, 80.0, 40.0).unwrap()); let combined_path = pb.finish().unwrap(); // Transform a path let transform = Transform::from_rotate(45.0); let rotated_path = path.transform(transform).unwrap(); } ``` -------------------------------- ### Clone and Prepare Skia Repository Source: https://github.com/linebender/tiny-skia/blob/main/benches/README.md Clones the Skia repository, checks out a specific version (m90), and downloads its dependencies. This is a prerequisite for building Skia from source. ```sh git clone https://skia.googlesource.com/skia.git cd skia git fetch --all git checkout -b m90 origin/chrome/m90 python3 tools/git-sync-deps ``` -------------------------------- ### Create and Use Pattern Fills Source: https://context7.com/linebender/tiny-skia/llms.txt Demonstrates creating a pattern tile from a Pixmap and using it to fill a shape. Supports various spread modes and filtering. ```rust use tiny_skia::* fn main() { // Create a small pattern tile let tile = { let mut tile_pixmap = Pixmap::new(20, 20).unwrap(); let mut paint = Paint::default(); paint.set_color_rgba8(50, 127, 150, 200); paint.anti_alias = true; // Draw a triangle on the tile let mut pb = PathBuilder::new(); pb.move_to(0.0, 20.0); pb.line_to(20.0, 20.0); pb.line_to(10.0, 0.0); pb.close(); let triangle = pb.finish().unwrap(); tile_pixmap.fill_path(&triangle, &paint, FillRule::Winding, Transform::identity(), None); tile_pixmap }; let mut pixmap = Pixmap::new(400, 400).unwrap(); // Create pattern paint let mut paint = Paint::default(); paint.anti_alias = true; paint.shader = Pattern::new( tile.as_ref(), SpreadMode::Repeat, // Repeat the pattern FilterQuality::Bicubic, // Bilinear or Bicubic filtering 1.0, // Opacity Transform::identity(), // Pattern transform ); // Fill a circle with the pattern let path = PathBuilder::from_circle(200.0, 200.0, 180.0).unwrap(); pixmap.fill_path(&path, &paint, FillRule::Winding, Transform::identity(), None); // Pattern with transform (scaled and rotated) let pattern_transform = Transform::from_row(1.5, -0.4, 0.0, -0.8, 5.0, 1.0); let mut transformed_paint = Paint::default(); transformed_paint.shader = Pattern::new( tile.as_ref(), SpreadMode::Repeat, FilterQuality::Bicubic, 0.8, // 80% opacity pattern_transform, ); pixmap.save_png("pattern.png").unwrap(); } ``` -------------------------------- ### Load and Decode PNG Images with tiny-skia Source: https://context7.com/linebender/tiny-skia/llms.txt Shows how to load PNG images from file paths or byte arrays, decode them into Pixmaps, and encode Pixmaps back into PNG data. Also covers creating a Pixmap from existing RGBA data and retrieving demultiplied RGBA data. Requires `tiny_skia::*` imports. ```rust use tiny_skia::* fn main() { // Load PNG from file path let pixmap = Pixmap::load_png("input.png").unwrap(); println!("Loaded image: {}x{}", pixmap.width(), pixmap.height()); // Decode PNG from byte array let png_bytes: &[u8] = include_bytes!("image.png"); let pixmap = Pixmap::decode_png(png_bytes).unwrap(); // Create pixmap from existing RGBA data let width = 100u32; let height = 100u32; let rgba_data: Vec = vec![0; (width * height * 4) as usize]; let size = IntSize::from_wh(width, height).unwrap(); let pixmap = Pixmap::from_vec(rgba_data, size).unwrap(); // Encode pixmap to PNG bytes let png_data: Vec = pixmap.encode_png().unwrap(); // Get demultiplied RGBA data (useful for exporting) let demultiplied: Vec = pixmap.take_demultiplied(); } ``` -------------------------------- ### Color Management in Tiny-skia Source: https://context7.com/linebender/tiny-skia/llms.txt Demonstrates creating, manipulating, and converting colors, including RGBA, premultiplied, and different color spaces for gamma correction. Use this for precise color handling in graphics. ```rust use tiny_skia::* fn main() { // Create colors let color_u8 = Color::from_rgba8(255, 128, 64, 200); // From u8 values let color_f32 = Color::from_rgba(1.0, 0.5, 0.25, 0.78).unwrap(); // From f32 (0.0-1.0) // Predefined colors let black = Color::BLACK; let white = Color::WHITE; let transparent = Color::TRANSPARENT; // Access color components println!("Red: {}, Green: {}, Blue: {}, Alpha: {}", color_u8.red(), color_u8.green(), color_u8.blue(), color_u8.alpha()); // Premultiply color (for proper alpha blending) let premultiplied = color_u8.premultiply(); // Convert to u8 color let as_u8 = color_f32.to_color_u8(); // Modify color opacity let mut faded = color_u8; faded.apply_opacity(0.5); // Reduce opacity by 50% // Paint with color space for gamma correction let mut paint = Paint::default(); paint.set_color(color_u8); // Available color spaces: // - Linear: Default, no gamma correction // - Gamma2: Fast gamma correction (gamma factor of 2) // - SimpleSRGB: Approximate sRGB (gamma 2.2) // - FullSRGBGamma: Full sRGB gamma function paint.colorspace = ColorSpace::SimpleSRGB; let mut pixmap = Pixmap::new(200, 200).unwrap(); // Draw with gamma-corrected blending let path = PathBuilder::from_circle(100.0, 100.0, 80.0).unwrap(); pixmap.fill_path(&path, &paint, FillRule::Winding, Transform::identity(), None); pixmap.save_png("colors.png").unwrap(); } ``` -------------------------------- ### Configure and Build Skia with GN Source: https://github.com/linebender/tiny-skia/blob/main/benches/README.md Generates build files using GN (Generate Ninja) and then builds Skia using Ninja. This command configures Skia for a non-official, component, release build with specific compiler flags and feature exclusions. ```sh bin/gn gen out/Shared --args=' is_official_build=false is_component_build=true is_debug=false cc="clang" cxx="clang++" extra_cflags_cc=["-march=haswell", "-DSK_FORCE_RASTER_PIPELINE_BLITTER"] werror=false paragraph_gms_enabled=false paragraph_tests_enabled=false skia_enable_android_utils=false skia_enable_discrete_gpu=false skia_enable_gpu=false skia_enable_nvpr=false skia_enable_pdf=false skia_enable_skottie=false skia_enable_skrive=false skia_enable_skshaper=false skia_enable_tools=false skia_use_expat=false skia_use_gl=false skia_use_harfbuzz=false skia_use_icu=false skia_use_libgifcodec=false skia_use_libheif=false skia_use_libjpeg_turbo_decode=false skia_use_libjpeg_turbo_encode=false skia_use_libwebp_decode=false skia_use_libwebp_encode=false skia_use_lua=false skia_use_piex=false' ninja -C out/Shared ``` -------------------------------- ### Configure Paint Properties in Tiny-skia Source: https://context7.com/linebender/tiny-skia/llms.txt Sets up paint properties such as shaders, blend modes, anti-aliasing, and rendering quality. Configure these to control how shapes are drawn. ```rust use tiny_skia::* fn main() { let mut pixmap = Pixmap::new(500, 500).unwrap(); // Default paint (black solid color, anti-alias enabled, SourceOver blend) let mut paint = Paint::default(); // Set solid color paint.set_color_rgba8(100, 150, 200, 255); // Or: paint.set_color(Color::from_rgba8(100, 150, 200, 255)); // Check if paint uses solid color if paint.is_solid_color() { println!("Using solid color"); } // Anti-aliasing (default: true) paint.anti_alias = true; // Blend mode (default: SourceOver) paint.blend_mode = BlendMode::SourceOver; // Color space for gamma correction (default: Linear) paint.colorspace = ColorSpace::Linear; // Force high-quality pipeline (useful for testing, default: false) paint.force_hq_pipeline = false; // Shader can be: SolidColor, LinearGradient, RadialGradient, SweepGradient, or Pattern paint.shader = Shader::SolidColor(Color::from_rgba8(255, 0, 0, 255)); // Apply opacity to shader paint.shader.apply_opacity(0.5); // Transform shader paint.shader.transform(Transform::from_scale(2.0, 2.0)); let path = PathBuilder::from_circle(250.0, 250.0, 100.0).unwrap(); pixmap.fill_path(&path, &paint, FillRule::Winding, Transform::identity(), None); pixmap.save_png("paint_config.png").unwrap(); } ``` -------------------------------- ### PixmapRef and PixmapMut Operations in Rust Source: https://context7.com/linebender/tiny-skia/llms.txt Demonstrates creating a mutable reference from an external buffer, drawing on it, creating an immutable reference, accessing pixel data, converting to an owned Pixmap, and cloning a region. Ensure the external buffer is premultiplied RGBA. ```rust use tiny_skia::* fn main() { // Create pixmap from external data (must be premultiplied RGBA) let width = 100u32; let height = 100u32; let mut external_buffer: Vec = vec![255; (width * height * 4) as usize]; // Create mutable reference to external buffer let mut pixmap_mut = PixmapMut::from_bytes(&mut external_buffer, width, height).unwrap(); // Draw on the mutable reference let mut paint = Paint::default(); paint.set_color_rgba8(255, 0, 0, 255); let path = PathBuilder::from_circle(50.0, 50.0, 40.0).unwrap(); pixmap_mut.fill_path(&path, &paint, FillRule::Winding, Transform::identity(), None); // Create immutable reference let pixmap_ref = pixmap_mut.as_ref(); println!("Size: {}x{}", pixmap_ref.width(), pixmap_ref.height()); // Access pixel data let pixel = pixmap_ref.pixel(50, 50); let data: &[u8] = pixmap_ref.data(); let pixels: &[PremultipliedColorU8] = pixmap_ref.pixels(); // Convert to owned Pixmap let owned_pixmap = pixmap_ref.to_owned(); // Direct buffer creation from owned Pixmap let pixmap = Pixmap::new(200, 200).unwrap(); let pixmap_ref: PixmapRef = pixmap.as_ref(); // Clone a region let rect = IntRect::from_xywh(10, 10, 50, 50).unwrap(); if let Some(sub) = pixmap_ref.clone_rect(rect) { sub.save_png("subregion.png").unwrap(); } } ``` -------------------------------- ### Clipping with Masks in Tiny-Skia Source: https://context7.com/linebender/tiny-skia/llms.txt Demonstrates creating and applying masks for clipping drawing operations. Supports complex shapes, transformations, and various mask operations like intersection and inversion. Masks can also be generated from pixmaps. ```rust use tiny_skia::* fn main() { let mut pixmap = Pixmap::new(500, 500).unwrap(); // Create a clip path (ring shape) let clip_path = { let mut pb = PathBuilder::new(); pb.push_circle(250.0, 250.0, 200.0); // Outer circle pb.push_circle(250.0, 250.0, 100.0); // Inner circle (hole) pb.finish().unwrap() }; // Transform the clip path let transform = Transform::from_row(1.0, -0.3, 0.0, 1.0, 0.0, 75.0); let clip_path = clip_path.transform(transform).unwrap(); // Create mask and fill with clip path let mut mask = Mask::new(500, 500).unwrap(); mask.fill_path( &clip_path, FillRule::EvenOdd, // Use EvenOdd for donut shape true, // Anti-alias Transform::identity(), ); // Draw with the mask let mut paint = Paint::default(); paint.set_color_rgba8(50, 127, 150, 200); let rect = Rect::from_xywh(0.0, 0.0, 500.0, 500.0).unwrap(); pixmap.fill_rect(rect, &paint, Transform::identity(), Some(&mask)); // Intersect masks let mut combined_mask = Mask::new(500, 500).unwrap(); combined_mask.fill_path( &PathBuilder::from_circle(250.0, 250.0, 200.0).unwrap(), FillRule::Winding, true, Transform::identity(), ); let rect_path = PathBuilder::from_rect(Rect::from_xywh(100.0, 100.0, 300.0, 300.0).unwrap()); combined_mask.intersect_path(&rect_path, FillRule::Winding, true, Transform::identity()); // Invert a mask let mut inverted_mask = Mask::new(500, 500).unwrap(); inverted_mask.fill_path( &PathBuilder::from_circle(250.0, 250.0, 100.0).unwrap(), FillRule::Winding, true, Transform::identity(), ); inverted_mask.invert(); // Create mask from pixmap let source_pixmap = Pixmap::load_png("source.png").unwrap_or_else(|_| Pixmap::new(100, 100).unwrap()); let alpha_mask = Mask::from_pixmap(source_pixmap.as_ref(), MaskType::Alpha); let luminance_mask = Mask::from_pixmap(source_pixmap.as_ref(), MaskType::Luminance); // Apply mask to existing content pixmap.apply_mask(&mask); pixmap.save_png("clipped.png").unwrap(); } ``` -------------------------------- ### Apply Affine Transformations to Shapes Source: https://context7.com/linebender/tiny-skia/llms.txt Shows how to apply various affine transformations including translation, rotation, scaling, and custom matrix transformations to drawing operations. ```rust use tiny_skia::* fn main() { let mut pixmap = Pixmap::new(500, 500).unwrap(); let mut paint = Paint::default(); paint.set_color_rgba8(100, 150, 200, 255); paint.anti_alias = true; let rect_path = PathBuilder::from_rect(Rect::from_xywh(-25.0, -25.0, 50.0, 50.0).unwrap()); // Identity transform (no transformation) let identity = Transform::identity(); // Translation let translate = Transform::from_translate(100.0, 100.0); pixmap.fill_path(&rect_path, &paint, FillRule::Winding, translate, None); // Rotation (degrees around origin, then translate) let rotate = Transform::from_rotate(45.0) .post_translate(200.0, 100.0); pixmap.fill_path(&rect_path, &paint, FillRule::Winding, rotate, None); // Scaling let scale = Transform::from_scale(2.0, 1.5) .post_translate(350.0, 100.0); pixmap.fill_path(&rect_path, &paint, FillRule::Winding, scale, None); // Combined transform from matrix values // [sx kx tx] // [ky sy ty] let custom = Transform::from_row( 1.2, // sx: horizontal scale 0.3, // ky: vertical skew -0.2, // kx: horizontal skew 0.9, // sy: vertical scale 250.0, // tx: horizontal translation 300.0, // ty: vertical translation ); pixmap.fill_path(&rect_path, &paint, FillRule::Winding, custom, None); // Transform a path (not the drawing operation) let original_path = PathBuilder::from_circle(0.0, 0.0, 50.0).unwrap(); let transformed_path = original_path .transform(Transform::from_translate(400.0, 300.0)) .unwrap(); pixmap.fill_path(&transformed_path, &paint, FillRule::Winding, Transform::identity(), None); pixmap.save_png("transforms.png").unwrap(); } ``` -------------------------------- ### Fill Paths with Solid Colors in Rust Source: https://context7.com/linebender/tiny-skia/llms.txt Use the `Paint` struct to define solid colors and fill rules for paths and rectangles. Supports RGBA values or `Color` struct for color definition. Anti-aliasing can be enabled. ```rust use tiny_skia::* fn main() { let mut pixmap = Pixmap::new(500, 500).unwrap(); // Create paint with solid color let mut paint = Paint::default(); paint.set_color_rgba8(50, 127, 150, 200); // RGBA values 0-255 paint.anti_alias = true; // Enable anti-aliasing // Alternative: set color using Color struct paint.set_color(Color::from_rgba(0.2, 0.5, 0.6, 0.8).unwrap()); // Build a path let mut pb = PathBuilder::new(); pb.move_to(60.0, 60.0); pb.line_to(160.0, 440.0); pb.cubic_to(380.0, 340.0, 260.0, 300.0, 440.0, 300.0); pb.cubic_to(340.0, 160.0, 240.0, 60.0, 60.0, 60.0); pb.close(); let path = pb.finish().unwrap(); // Fill path with Winding fill rule pixmap.fill_path( &path, &paint, FillRule::Winding, Transform::identity(), None, // No clipping mask ); // Fill path with EvenOdd fill rule (for complex shapes with holes) let mut donut = PathBuilder::new(); donut.push_circle(250.0, 250.0, 100.0); // Outer circle donut.push_circle(250.0, 250.0, 50.0); // Inner circle (hole) let donut_path = donut.finish().unwrap(); pixmap.fill_path( &donut_path, &paint, FillRule::EvenOdd, Transform::identity(), None, ); // Fill a rectangle directly let rect = Rect::from_xywh(10.0, 10.0, 100.0, 80.0).unwrap(); pixmap.fill_rect(rect, &paint, Transform::identity(), None); pixmap.save_png("filled.png").unwrap(); } ``` -------------------------------- ### Stroke Paths with Custom Configurations in Rust Source: https://context7.com/linebender/tiny-skia/llms.txt Configure stroke properties like width, line cap, line join, and miter limit for drawing path outlines. Supports dashed lines using `StrokeDash`. ```rust use tiny_skia::* fn main() { let mut pixmap = Pixmap::new(500, 500).unwrap(); // Create paint for stroke let mut paint = Paint::default(); paint.set_color_rgba8(0, 127, 0, 200); paint.anti_alias = true; // Build a path (star pattern) let path = { let mut pb = PathBuilder::new(); const RADIUS: f32 = 200.0; const CENTER: f32 = 250.0; pb.move_to(CENTER + RADIUS, CENTER); for i in 1..8 { let angle = 2.6927937 * i as f32; pb.line_to(CENTER + RADIUS * angle.cos(), CENTER + RADIUS * angle.sin()); } pb.finish().unwrap() }; // Configure stroke let mut stroke = Stroke::default(); stroke.width = 6.0; stroke.line_cap = LineCap::Round; // Butt, Round, or Square stroke.line_join = LineJoin::Round; // Miter, Round, Bevel, or MiterClip stroke.miter_limit = 4.0; // Stroke the path pixmap.stroke_path(&path, &paint, &stroke, Transform::identity(), None); // Stroke with dashing let mut dashed_stroke = Stroke::default(); dashed_stroke.width = 4.0; dashed_stroke.line_cap = LineCap::Round; dashed_stroke.dash = StrokeDash::new(vec![20.0, 10.0, 5.0, 10.0], 0.0); let rect_path = PathBuilder::from_rect(Rect::from_xywh(50.0, 50.0, 150.0, 100.0).unwrap()); pixmap.stroke_path(&rect_path, &paint, &dashed_stroke, Transform::identity(), None); pixmap.save_png("stroked.png").unwrap(); } ``` -------------------------------- ### Create Linear Gradient Paint Source: https://context7.com/linebender/tiny-skia/llms.txt Use LinearGradient to create a paint object with a color transition along a line. Supports different spread modes like Pad, Reflect, and Repeat. Transformations can be applied to the gradient. ```rust use tiny_skia::* fn main() { let mut pixmap = Pixmap::new(500, 500).unwrap(); // Create paint with linear gradient let mut paint = Paint::default(); paint.shader = LinearGradient::new( Point::from_xy(50.0, 50.0), // Start point Point::from_xy(450.0, 450.0), // End point vec![ GradientStop::new(0.0, Color::from_rgba8(255, 0, 0, 255)), // Red at start GradientStop::new(0.5, Color::from_rgba8(0, 255, 0, 255)), // Green at middle GradientStop::new(1.0, Color::from_rgba8(0, 0, 255, 255)), // Blue at end ], SpreadMode::Pad, // Pad, Reflect, or Repeat Transform::identity(), ).unwrap(); paint.anti_alias = true; // Fill a shape with the gradient let path = PathBuilder::from_circle(250.0, 250.0, 200.0).unwrap(); pixmap.fill_path(&path, &paint, FillRule::Winding, Transform::identity(), None); // Gradient with Reflect spread mode (mirrors at boundaries) let mut reflect_paint = Paint::default(); reflect_paint.shader = LinearGradient::new( Point::from_xy(100.0, 100.0), Point::from_xy(200.0, 100.0), vec![ GradientStop::new(0.0, Color::from_rgba8(50, 127, 150, 200)), GradientStop::new(1.0, Color::from_rgba8(220, 140, 75, 180)), ], SpreadMode::Reflect, Transform::identity(), ).unwrap(); // Gradient with transform let gradient_transform = Transform::from_rotate(45.0); let mut transformed_paint = Paint::default(); transformed_paint.shader = LinearGradient::new( Point::from_xy(0.0, 0.0), Point::from_xy(100.0, 0.0), vec![ GradientStop::new(0.0, Color::WHITE), GradientStop::new(1.0, Color::BLACK), ], SpreadMode::Repeat, gradient_transform, ).unwrap(); pixmap.save_png("gradient.png").unwrap(); } ``` -------------------------------- ### Create Sweep Gradients in Tiny-skia Source: https://context7.com/linebender/tiny-skia/llms.txt Generates angular gradients sweeping around a center point. Useful for creating color wheel effects or other radial color transitions. ```rust use tiny_skia::* fn main() { let mut pixmap = Pixmap::new(500, 500).unwrap(); // Create sweep gradient paint let mut paint = Paint::default(); paint.shader = SweepGradient::new( Point::from_xy(250.0, 250.0), // Center point 0.0, // Start angle (degrees) 360.0, // End angle (degrees) vec![ GradientStop::new(0.0, Color::from_rgba8(255, 0, 0, 255)), GradientStop::new(0.33, Color::from_rgba8(0, 255, 0, 255)), GradientStop::new(0.66, Color::from_rgba8(0, 0, 255, 255)), GradientStop::new(1.0, Color::from_rgba8(255, 0, 0, 255)), ], SpreadMode::Pad, Transform::identity(), ).unwrap(); paint.anti_alias = true; // Fill a circle with the sweep gradient (color wheel effect) let path = PathBuilder::from_circle(250.0, 250.0, 200.0).unwrap(); pixmap.fill_path(&path, &paint, FillRule::Winding, Transform::identity(), None); pixmap.save_png("sweep_gradient.png").unwrap(); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.