### Applying Visual Effects with Impellers Source: https://context7.com/coderedart/impellers/llms.txt Demonstrates how to apply blur, color filters, and image filters to shapes using the Impellers library. It includes examples for setting paint properties and drawing basic shapes with these effects. ```rust use impellers::* fn apply_effects() -> DisplayList { let mut builder = DisplayListBuilder::new(None); let mut paint = Paint::default(); // Clear background paint.set_color(Color::new_srgb(0.1, 0.1, 0.15)); builder.draw_paint(&paint); // Rectangle with blur mask filter let blur_mask = MaskFilter::new_blur(BlurStyle::Normal, 8.0); paint.set_color(Color::new_srgb(0.0, 0.8, 0.4)); paint.set_mask_filter(&blur_mask); builder.draw_rect( &Rect::new(Point::new(50.0, 50.0), Size::new(200.0, 150.0)), &paint, ); // Rectangle with color filter (tint effect) let color_filter = ColorFilter::new_blend( Color::new_srgba(1.0, 0.5, 0.0, 0.5), BlendMode::SrcOver, ); paint = Paint::default(); paint.set_color(Color::new_srgb(0.8, 0.8, 0.8)); paint.set_color_filter(&color_filter); builder.draw_oval( &Rect::new(Point::new(300.0, 50.0), Size::new(200.0, 150.0)), &paint, ); // Rectangle with image filter blur let image_blur = ImageFilter::new_blur(5.0, 5.0, TileMode::Clamp); paint = Paint::default(); paint.set_color(Color::new_srgb(1.0, 0.2, 0.4)); paint.set_image_filter(&image_blur); builder.draw_rect( &Rect::new(Point::new(50.0, 250.0), Size::new(200.0, 150.0)), &paint, ); builder.build().expect("Failed to build display list") } ``` -------------------------------- ### General API Conventions Source: https://github.com/coderedart/impellers/blob/master/CONTRIBUTING.md Outlines general conventions and guidelines for using the Impeller API based on the `impeller_api.json` structure. ```APIDOC ## General API Conventions When working with the Impeller API as defined in `impeller_api.json`: * **Naming Convention**: All identifiers (enums, functions, types) typically start with the prefix `Impeller`. * **Methods on Handles**: Most functions operate as "methods" on opaque struct handles. These function names usually start with the name of the handle they operate on. For example, a function to release an `ImpellerContext` handle would likely be named `ImpellerContextRelease`. * **Struct Functionality**: While basic structs like `rect` and `matrix` may be defined, their associated complex functionality (e.g., matrix multiplication, rectangle translation) is *not* included in the API JSON. You are expected to implement these operations yourself. * **Thread Safety**: The `impeller_api.json` file does not explicitly specify which structs or functions are thread-safe. Consult the separate documentation for `impeller.h` to determine thread safety. * **Default Values**: Certain fields, particularly boolean flags like `nonnull`, may be omitted if they have a default value. For example, if `nonnull` is not specified for a pointer type, you can generally assume it defaults to `false`. ``` -------------------------------- ### Impeller API JSON Structure Source: https://github.com/coderedart/impellers/blob/master/CONTRIBUTING.md Explains the structure of the `impeller_api.json` file, detailing how enums, handles, functions, and plain old data (POD) structs are represented. ```APIDOC ## Impeller API JSON Structure The `impeller_api.json` file provides a structured representation of the Impeller C API. ### Root Object Structure The root of the JSON object contains the following top-level keys: * **`enums`**: An object where keys are enum names and values are arrays of variant names. Used for generating C enums. * **`handles`**: An object where keys are names of opaque C struct handles, and values are their corresponding docstrings. * **`functions`**: An object where keys are C function names. Each value is an object detailing the function's documentation, return type, and arguments. * **`doc`**: The docstring for the function. * **`return_ty`**: An object describing the return type, including `nodiscard`, `ty` (the C type string), and `nonnull` (if the return value must not be null). * **`args`**: An array of objects, where each object describes a function argument (or a field for POD structs). Arguments include `name`, `ty` (the C type string), `nonnull` (if the argument must not be null), and `array_size` (if the argument is an array). * **`pod_structs`**: An object where keys are names of Plain Old Data (POD) C structs. Each value describes the struct, including its `doc`string and an array of `fields` (which have the same structure as function arguments). * **`types`**: An object listing auxiliary types used in the API (e.g., `bool`, `const uint8_t*`), excluding handles, enums, and POD structs which are implicitly defined. ``` -------------------------------- ### Complete Rendering Loop with Vsync and Event Handling (Rust) Source: https://context7.com/coderedart/impellers/llms.txt This Rust code snippet demonstrates a full rendering loop using the Impeller graphics library with GLFW for window management and event handling. It initializes GLFW, creates a window, sets up the Impeller OpenGL context, defines a display list with a background and a rectangle, and enters a loop to handle events, draw the display list to a surface, and swap buffers with vsync enabled. It requires the `impellers` and `glfw` crates. ```Rust use impellers::*; use glfw::*; fn main() { // Initialize GLFW and create window let mut glfw = init(fail_on_errors).expect("Failed to init GLFW"); glfw.window_hint(WindowHint::ContextVersionMajor(4)); glfw.window_hint(WindowHint::OpenGlProfile(OpenGlProfileHint::Core)); glfw.window_hint(WindowHint::SRgbCapable(true)); let (mut window, events) = glfw .create_window(800, 600, "Impeller Demo", WindowMode::Windowed) .expect("Failed to create window"); window.make_current(); window.set_all_polling(true); glfw.set_swap_interval(SwapInterval::Sync(1)); // Enable vsync // Create Impeller context let mut impeller_ctx = unsafe { Context::new_opengl_es(|name| window.get_proc_address(name) as _) } .expect("Failed to create Impeller context"); // Create reusable display list let display_list = { let mut builder = DisplayListBuilder::new(None); let mut paint = Paint::default(); // Black background paint.set_color(Color::new_srgb(0.0, 0.0, 0.0)); builder.draw_paint(&paint); // Animated rectangle paint.set_color(Color::new_srgb(0.5, 0.7, 1.0)); builder.draw_rect( &Rect::new(Point::new(300.0, 250.0), Size::new(200.0, 100.0)), &paint, ); builder.build().expect("Failed to build display list") }; // Event loop while !window.should_close() { glfw.poll_events(); for (_, event) in flush_messages(&events) { match event { WindowEvent::Close => window.set_should_close(true), WindowEvent::Key(Key::Escape, _, Action::Press, _) => { window.set_should_close(true) } _ => {} } } // Create surface for current frame let (width, height) = window.get_framebuffer_size(); let mut surface = unsafe { impeller_ctx.wrap_fbo( 0, PixelFormat::RGBA8888, ISize::new(width.into(), height.into()), ) } .expect("Failed to wrap framebuffer"); // Draw display list to surface surface .draw_display_list(&display_list) .expect("Failed to draw"); // Present frame window.swap_buffers(); } } ``` -------------------------------- ### Return Type Specification Source: https://github.com/coderedart/impellers/blob/master/CONTRIBUTING.md Describes the structure of the `return_ty` object used in function specifications, detailing the return type and its properties. ```APIDOC ## Return Type Specification The `return_ty` object within a function specification describes the function's return value: ### Fields * **`nodiscard`** (boolean) - Optional. If `true`, indicates that the return value should not be discarded by the compiler. Defaults to `false`. * **`ty`** (string) - The C type of the return value (e.g., `void`, `bool`, `const char*`, `ImpellerHandle*`). * **`nonnull`** (boolean) - Optional. If `true` and `ty` is a pointer or handle type, indicates that the returned pointer/handle must not be null. Defaults to `false`. ``` -------------------------------- ### Function Argument and POD Field Specification Source: https://github.com/coderedart/impellers/blob/master/CONTRIBUTING.md Details the structure of objects representing function arguments and fields within POD structs, including type, nullability, and array size. ```APIDOC ## Function Argument and POD Field Specification Objects within the `args` array (for functions) and the `fields` array (for `pod_structs`) share a common structure: ### Fields * **`name`** (string) - The name of the argument or field. * **`ty`** (string) - The C type of the argument or field (e.g., `const char*`, `uint32_t`, `ImpellerHandle*`). This is often a direct copy from the C header. * **`nonnull`** (boolean) - Optional. If `true`, indicates that a pointer or handle type must not be null. Defaults to `false`. * **`array_size`** (integer) - Optional. If the argument/field is an array (represented as a pointer in C), this specifies the required size of the array. Defaults to `0`. ``` -------------------------------- ### Draw Custom Star Path with Gradient Fill in Rust Source: https://context7.com/coderedart/impellers/llms.txt This Rust code demonstrates how to create a custom star path using PathBuilder and then draw it with a linear gradient fill. It involves defining points for the star's vertices and applying a gradient defined by start/end points and colors. Dependencies include the 'impellers' crate. ```rust use impellers::* fn create_custom_path() -> DisplayList { let mut builder = DisplayListBuilder::new(None); let mut paint = Paint::default(); // Clear background paint.set_color(Color::new_srgb(0.1, 0.1, 0.1)); builder.draw_paint(&paint); // Create a star path let mut path_builder = PathBuilder::default(); let center = Point::new(400.0, 300.0); let outer_radius = 100.0; let inner_radius = 40.0; let num_points = 5; for i in 0..(num_points * 2) { let angle = std::f32::consts::PI * i as f32 / num_points as f32 - std::f32::consts::PI / 2.0; let radius = if i % 2 == 0 { outer_radius } else { inner_radius }; let point = Point::new( center.x + radius * angle.cos(), center.y + radius * angle.sin(), ); if i == 0 { path_builder.move_to(point); } else { path_builder.line_to(point); } } path_builder.close(); let star_path = path_builder.take_path_new(FillType::EvenOdd); // Draw the star with a gradient fill let gradient = ColorSource::new_linear_gradient( Point::new(300.0, 200.0), Point::new(500.0, 400.0), &[ Color::new_srgb(1.0, 0.8, 0.0), Color::new_srgb(1.0, 0.4, 0.0), ], &[0.0, 1.0], TileMode::Clamp, None, ); paint.set_color_source(&gradient); builder.draw_path(&star_path, &paint); builder.build().expect("Failed to build display list") } ``` -------------------------------- ### Create OpenGL ES Context with Impeller Source: https://context7.com/coderedart/impellers/llms.txt Initializes an Impeller rendering context by wrapping OpenGL function pointers obtained from a windowing library like GLFW. This allows Impeller to utilize the existing OpenGL ES context for rendering. The context must be dropped before the window it is associated with. ```rust use impellers::* use glfw::* fn main() { // Initialize GLFW let mut glfw = init(fail_on_errors).unwrap(); glfw.window_hint(WindowHint::OpenGlProfile(OpenGlProfileHint::Core)); glfw.window_hint(WindowHint::ContextVersionMajor(4)); let (mut window, _events) = glfw .create_window(800, 600, "Impeller Demo", WindowMode::Windowed) .expect("Failed to create window"); window.make_current(); // Create Impeller context using OpenGL function pointers // Safety: Context must be dropped before the window let mut ctx = unsafe { Context::new_opengl_es(|name| window.get_proc_address(name) as _) } .expect("Failed to create Impeller context"); // Wrap the default framebuffer as a surface let (width, height) = window.get_framebuffer_size(); let mut surface = unsafe { ctx.wrap_fbo( 0, // Default framebuffer PixelFormat::RGBA8888, ISize::new(width.into(), height.into()), ) } .expect("Failed to wrap framebuffer"); // Surface is ready for drawing } ``` -------------------------------- ### Render Styled Text with ParagraphBuilder in Rust Source: https://context7.com/coderedart/impellers/llms.txt This Rust code shows how to render text with different styles, fonts, and colors using ParagraphBuilder and TypographyContext. It demonstrates creating multiple text segments with distinct ParagraphStyle objects and drawing the resulting paragraph onto a display list. The 'impellers' crate is a dependency. ```rust use impellers::* fn render_text() -> DisplayList { // Create typography context for font management let mut typo_ctx = TypographyContext::default(); // Optionally register custom fonts // let font_data = std::fs::read("CustomFont.ttf").unwrap(); // typo_ctx.register_font(std::borrow::Cow::Owned(font_data), Some("CustomFont")) // .expect("Failed to register font"); // Build a styled paragraph let mut para_builder = ParagraphBuilder::new(&typo_ctx) .expect("Failed to create paragraph builder"); // First text segment - large bold text let mut style1 = ParagraphStyle::default(); style1.set_font_size(48.0); style1.set_font_weight(FontWeight::Bold); let mut paint1 = Paint::default(); paint1.set_color(Color::new_srgb(0.2, 0.6, 1.0)); style1.set_foreground(&paint1); para_builder.push_style(&style1); para_builder.add_text("Hello, "); // Second text segment - different style let mut style2 = ParagraphStyle::default(); style2.set_font_size(36.0); style2.set_font_style(FontStyle::Italic); let mut paint2 = Paint::default(); paint2.set_color(Color::new_srgb(1.0, 0.5, 0.0)); style2.set_foreground(&paint2); para_builder.push_style(&style2); para_builder.add_text("World!"); para_builder.pop_style(); // Layout the paragraph with max width let paragraph = para_builder.build(600.0) .expect("Failed to build paragraph"); // Get paragraph metrics let height = paragraph.get_height(); let width = paragraph.get_longest_line_width(); println!("Paragraph: {}x{}", width, height); // Create display list let mut builder = DisplayListBuilder::new(None); let mut bg_paint = Paint::default(); bg_paint.set_color(Color::new_srgb(0.95, 0.95, 0.95)); builder.draw_paint(&bg_paint); // Draw paragraph at position builder.draw_paragraph(¶graph, Point::new(50.0, 100.0)); builder.build().expect("Failed to build display list") } ``` -------------------------------- ### Drawing Gradients with Impellers Source: https://context7.com/coderedart/impellers/llms.txt Illustrates how to create and draw linear, radial, and sweep gradients using the ColorSource API in Impellers. It shows different color stops and tile modes for gradient generation. ```rust use impellers::* fn gradient_examples() -> DisplayList { let mut builder = DisplayListBuilder::new(None); let mut paint = Paint::default(); // Clear background paint.set_color(Color::new_srgb(0.05, 0.05, 0.05)); builder.draw_paint(&paint); // Linear gradient let linear = ColorSource::new_linear_gradient( Point::new(50.0, 50.0), Point::new(250.0, 50.0), &[ Color::new_srgb(1.0, 0.0, 0.0), Color::new_srgb(0.0, 0.0, 1.0), ], &[0.0, 1.0], TileMode::Clamp, None, ); paint.set_color_source(&linear); builder.draw_rect( &Rect::new(Point::new(50.0, 50.0), Size::new(200.0, 100.0)), &paint, ); // Radial gradient let radial = ColorSource::new_radial_gradient( Point::new(450.0, 100.0), 80.0, &[ Color::new_srgb(1.0, 1.0, 0.0), Color::new_srgb(1.0, 0.5, 0.0), Color::new_srgb(0.8, 0.0, 0.0), ], &[0.0, 0.5, 1.0], TileMode::Clamp, None, ); paint = Paint::default(); paint.set_color_source(&radial); builder.draw_oval( &Rect::new(Point::new(370.0, 20.0), Size::new(160.0, 160.0)), &paint, ); // Sweep gradient (angular) let sweep = ColorSource::new_sweep_gradient( Point::new(150.0, 300.0), 0.0, 360.0, &[ Color::new_srgb(1.0, 0.0, 0.0), Color::new_srgb(0.0, 1.0, 0.0), Color::new_srgb(0.0, 0.0, 1.0), Color::new_srgb(1.0, 0.0, 0.0), ], &[0.0, 0.33, 0.66, 1.0], TileMode::Clamp, None, ); paint = Paint::default(); paint.set_color_source(&sweep); builder.draw_oval( &Rect::new(Point::new(70.0, 220.0), Size::new(160.0, 160.0)), &paint, ); builder.build().expect("Failed to build display list") } ``` -------------------------------- ### Apply Transformations and Clipping (Rust) Source: https://context7.com/coderedart/impellers/llms.txt Demonstrates applying translation, rotation, and clipping operations within Impellers. Transformations are cumulative, and clipping restricts rendering to specified regions. Uses save/restore to manage transformation states. ```rust use impellers::* fn transformations_demo() -> DisplayList { let mut builder = DisplayListBuilder::new(None); let mut paint = Paint::default(); // Clear background paint.set_color(Color::new_srgb(0.95, 0.95, 0.95)); builder.draw_paint(&paint); // Draw without transformation paint.set_color(Color::new_srgb(0.8, 0.2, 0.2)); builder.draw_rect( &Rect::new(Point::new(50.0, 50.0), Size::new(100.0, 100.0)), &paint, ); // Save transformation state builder.save(); // Apply translation builder.translate(200.0, 0.0); paint.set_color(Color::new_srgb(0.2, 0.8, 0.2)); builder.draw_rect( &Rect::new(Point::new(50.0, 50.0), Size::new(100.0, 100.0)), &paint, ); // Apply rotation (cumulative with translation) builder.rotate(45.0); paint.set_color(Color::new_srgb(0.2, 0.2, 0.8)); builder.draw_rect( &Rect::new(Point::new(50.0, 50.0), Size::new(100.0, 100.0)), &paint, ); // Restore transformation builder.restore(); // Clipping example builder.save(); builder.translate(50.0, 200.0); // Set circular clip region let clip_oval = Rect::new(Point::new(0.0, 0.0), Size::new(150.0, 150.0)); builder.clip_oval(&clip_oval, ClipOperation::Intersect); // Draw multiple rectangles - only visible parts will render for i in 0..5 { paint.set_color(Color::new_srgb( i as f32 / 5.0, 0.5, 1.0 - i as f32 / 5.0, )); builder.draw_rect( &Rect::new( Point::new(i as f32 * 30.0, 0.0), Size::new(40.0, 200.0), ), &paint, ); } builder.restore(); builder.build().expect("Failed to build display list") } ``` -------------------------------- ### Draw Basic Shapes with Impeller Display Lists Source: https://context7.com/coderedart/impellers/llms.txt Constructs a display list containing various basic shapes such as rectangles, ovals, and rounded rectangles. Each shape can be styled using the Paint object, allowing customization of color, drawing style (fill or stroke), stroke width, and stroke cap. The display list is built using a builder pattern. ```rust use impellers::* fn draw_shapes() -> DisplayList { // Create display list builder let mut builder = DisplayListBuilder::new(None); let mut paint = Paint::default(); // Clear background to black paint.set_color(Color::new_srgb(0.0, 0.0, 0.0)); builder.draw_paint(&paint); // Draw a filled blue rectangle paint.set_color(Color::new_srgb(0.2, 0.4, 0.8)); builder.draw_rect( &Rect::new(Point::new(100.0, 100.0), Size::new(200.0, 150.0)), &paint, ); // Draw a stroked green oval paint.set_color(Color::new_srgb(0.0, 0.8, 0.2)); paint.set_draw_style(DrawStyle::Stroke); paint.set_stroke_width(5.0); paint.set_stroke_cap(StrokeCap::Round); builder.draw_oval( &Rect::new(Point::new(350.0, 100.0), Size::new(200.0, 150.0)), &paint, ); // Draw a rounded rectangle paint.set_color(Color::new_srgba(0.8, 0.2, 0.2, 0.7)); paint.set_draw_style(DrawStyle::Fill); let radii = RoundingRadii { top_left: Point::new(20.0, 20.0), top_right: Point::new(20.0, 20.0), bottom_left: Point::new(20.0, 20.0), bottom_right: Point::new(20.0, 20.0), }; builder.draw_rounded_rect( &Rect::new(Point::new(100.0, 300.0), Size::new(200.0, 100.0)), &radii, &paint, ); builder.build().expect("Failed to build display list") } ``` -------------------------------- ### Draw Texture from Image Data with Transformations (Rust) Source: https://context7.com/coderedart/impellers/llms.txt Loads image data into a texture and renders it using Impellers. Supports drawing at original size, scaled via transformations, and drawing specific portions using source and destination rectangles. Requires the 'image' crate for decoding. ```rust use impellers::* fn draw_texture(ctx: &Context, image_bytes: &[u8]) -> DisplayList { // Decode image (using image crate) let img = image::load_from_memory(image_bytes) .expect("Failed to decode image") .to_rgba8(); let (width, height) = img.dimensions(); let pixels = img.into_raw(); // Create texture from RGBA8 data // Safety: Texture must be dropped before context let texture = unsafe { ctx.create_texture_with_rgba8( std::borrow::Cow::Owned(pixels), width, height, ) } .expect("Failed to create texture"); // Create display list let mut builder = DisplayListBuilder::new(None); let mut paint = Paint::default(); // Clear background paint.set_color(Color::new_srgb(0.2, 0.2, 0.2)); builder.draw_paint(&paint); // Draw texture at original size paint = Paint::default(); builder.draw_texture( &texture, Point::new(50.0, 50.0), TextureSampling::Linear, &paint, ); // Draw texture scaled using transformation builder.save(); builder.translate(300.0, 50.0); builder.scale(0.5, 0.5); builder.draw_texture( &texture, Point::new(0.0, 0.0), TextureSampling::Linear, &paint, ); builder.restore(); // Draw texture portion using src/dst rects let src_rect = Rect::new( Point::new(0.0, 0.0), Size::new(width as f32 / 2.0, height as f32 / 2.0), ); let dst_rect = Rect::new( Point::new(50.0, 300.0), Size::new(200.0, 200.0), ); builder.draw_texture_rect( &texture, &src_rect, &dst_rect, TextureSampling::Nearest, Some(&paint), ); builder.build().expect("Failed to build display list") } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.