### Install cssbox dependencies Source: https://context7.com/npow/cssbox/llms.txt Add the core engine and optional DOM parsing support to your Cargo.toml file. ```toml [dependencies] cssbox-core = "0.1" cssbox-dom = "0.1" # Optional: for HTML/CSS parsing ``` -------------------------------- ### Run CSSBox Core Layout Tests Source: https://github.com/npow/cssbox/blob/main/README.md Focus on testing the core layout algorithms within the `cssbox-core` crate. ```bash cargo test -p cssbox-core ``` -------------------------------- ### Add Dependency Source: https://github.com/npow/cssbox/blob/main/README.md Include the cssbox-core crate in your Cargo.toml file. ```toml [dependencies] cssbox-core = "0.1" ``` -------------------------------- ### Layout from HTML/CSS Source: https://github.com/npow/cssbox/blob/main/README.md Convert HTML strings into a box tree and compute the layout. ```rust use cssbox_dom::computed::html_to_box_tree; use cssbox_core::geometry::Size; use cssbox_core::layout::{compute_layout, FixedWidthTextMeasure}; let tree = html_to_box_tree(r#"
"#); let result = compute_layout(&tree, &FixedWidthTextMeasure, Size::new(800.0, 600.0)); ``` -------------------------------- ### Define a CSS Grid Layout Source: https://context7.com/npow/cssbox/llms.txt Demonstrates creating a grid container with fractional track sizing, fixed row heights, and gaps. Requires the cssbox_core crate. ```rust use cssbox_core::tree::BoxTreeBuilder; use cssbox_core::style::{ComputedStyle, Display, TrackDefinition, TrackSizingFunction, GridAutoFlow}; use cssbox_core::geometry::Size; use cssbox_core::layout::{compute_layout, FixedWidthTextMeasure}; let mut builder = BoxTreeBuilder::new(); // Create grid container let mut grid_style = ComputedStyle { display: Display::GRID, ..ComputedStyle::block() }; // Define columns: 1fr 2fr (fractional units) grid_style.grid_template_columns = vec![ TrackDefinition::new(TrackSizingFunction::Fr(1.0)), TrackDefinition::new(TrackSizingFunction::Fr(2.0)), ]; // Define rows: 100px 100px (fixed heights) grid_style.grid_template_rows = vec![ TrackDefinition::new(TrackSizingFunction::Length(100.0)), TrackDefinition::new(TrackSizingFunction::Length(100.0)), ]; // Set gaps grid_style.column_gap = 20.0; grid_style.row_gap = 10.0; grid_style.grid_auto_flow = GridAutoFlow::Row; let container = builder.root(grid_style); // Add 4 grid items (auto-placed into 2x2 grid) for _ in 0..4 { builder.element(container, ComputedStyle::block()); } let tree = builder.build(); let result = compute_layout(&tree, &FixedWidthTextMeasure, Size::new(620.0, 400.0)); // With 620px width and 20px gap: (620-20)/3 * 1 = 200px, * 2 = 400px let children = tree.children(tree.root()); let r0 = result.bounding_rect(children[0]).unwrap(); let r1 = result.bounding_rect(children[1]).unwrap(); println!("Cell 0: {}x{} at ({}, {})", r0.width, r0.height, r0.x, r0.y); println!("Cell 1: {}x{} at ({}, {})", r1.width, r1.height, r1.x, r1.y); ``` -------------------------------- ### CSSBox Geometry Primitives in Rust Source: https://context7.com/npow/cssbox/llms.txt Demonstrates the usage of Point, Size, Rect, Edges, and SizeConstraint for geometric calculations in Rust. Ensure cssbox_core::geometry is imported. ```rust use cssbox_core::geometry::{Point, Size, Rect, Edges, AvailableSpace, SizeConstraint}; // Point operations let p = Point::new(10.0, 20.0); let q = p.offset(5.0, -3.0); assert_eq!(q, Point::new(15.0, 17.0)); // Size let size = Size::new(100.0, 50.0); assert_eq!(size.width, 100.0); // Rectangle with boundary checks let rect = Rect::new(10.0, 10.0, 100.0, 50.0); assert!(rect.contains(Point::new(50.0, 30.0))); assert!(!rect.contains(Point::new(5.0, 5.0))); assert_eq!(rect.right(), 110.0); assert_eq!(rect.bottom(), 60.0); // Create rect from point and size let rect2 = Rect::from_point_size(Point::new(0.0, 0.0), Size::new(200.0, 100.0)); // Edges for margin/padding/border let edges = Edges::new(10.0, 20.0, 10.0, 20.0); assert_eq!(edges.horizontal(), 40.0); // left + right assert_eq!(edges.vertical(), 20.0); // top + bottom // Symmetric edges let symmetric = Edges::symmetric(10.0, 20.0); // 10 top/bottom, 20 left/right let uniform = Edges::all(5.0); // 5 on all sides // Size constraints for layout let constraint = SizeConstraint { available: AvailableSpace::Definite(100.0), min: 20.0, max: 80.0, }; assert_eq!(constraint.clamp(50.0), 50.0); assert_eq!(constraint.clamp(10.0), 20.0); // clamped to min assert_eq!(constraint.clamp(100.0), 80.0); // clamped to max ``` -------------------------------- ### Build and Layout a Box Tree Source: https://github.com/npow/cssbox/blob/main/README.md Construct a tree of styled nodes and compute their layout within a specified viewport. ```rust use cssbox_core::tree::BoxTreeBuilder; use cssbox_core::style::ComputedStyle; use cssbox_core::geometry::Size; use cssbox_core::layout::{compute_layout, FixedWidthTextMeasure}; use cssbox_core::values::LengthPercentageAuto; // Build a tree of styled nodes let mut builder = BoxTreeBuilder::new(); let root = builder.root(ComputedStyle::block()); let mut child_style = ComputedStyle::block(); child_style.width = LengthPercentageAuto::px(200.0); child_style.height = LengthPercentageAuto::px(100.0); let child = builder.element(root, child_style); let tree = builder.build(); // Compute layout against an 800x600 viewport let result = compute_layout(&tree, &FixedWidthTextMeasure, Size::new(800.0, 600.0)); // Query the result — just like getBoundingClientRect() let rect = result.bounding_rect(child).unwrap(); assert_eq!(rect.width, 200.0); assert_eq!(rect.height, 100.0); ``` -------------------------------- ### Configure ComputedStyle Properties Source: https://context7.com/npow/cssbox/llms.txt Shows how to set box model, positioning, flexbox, and grid properties on a ComputedStyle instance. Includes usage of convenience constructors for block and inline elements. ```rust use cssbox_core::style::{ ComputedStyle, Display, Position, BoxSizing, Float, Clear, Overflow, TextAlign, FlexDirection, FlexWrap, JustifyContent, AlignItems, AlignContent, GridAutoFlow, TrackDefinition, TrackSizingFunction }; use cssbox_core::values::{LengthPercentageAuto, LengthPercentage, LengthPercentageNone}; use cssbox_core::geometry::Edges; // Create a fully-configured style let mut style = ComputedStyle::default(); // Display and positioning style.display = Display::FLEX; style.position = Position::Relative; style.float = Float::None; style.clear = Clear::None; // Box model style.box_sizing = BoxSizing::BorderBox; style.width = LengthPercentageAuto::px(300.0); style.height = LengthPercentageAuto::Auto; style.min_width = LengthPercentage::px(100.0); style.max_width = LengthPercentageNone::px(500.0); // Margins (support auto for centering) style.margin_top = LengthPercentageAuto::px(10.0); style.margin_right = LengthPercentageAuto::Auto; style.margin_bottom = LengthPercentageAuto::px(10.0); style.margin_left = LengthPercentageAuto::Auto; // Padding style.padding_top = LengthPercentage::px(20.0); style.padding_right = LengthPercentage::percent(5.0); style.padding_bottom = LengthPercentage::px(20.0); style.padding_left = LengthPercentage::percent(5.0); // Borders style.border_top_width = 1.0; style.border_right_width = 1.0; style.border_bottom_width = 1.0; style.border_left_width = 1.0; // Positioning offsets (for relative/absolute/fixed) style.top = LengthPercentageAuto::px(10.0); style.left = LengthPercentageAuto::px(10.0); // Flexbox properties style.flex_direction = FlexDirection::Row; style.flex_wrap = FlexWrap::Wrap; style.justify_content = JustifyContent::SpaceBetween; style.align_items = AlignItems::Center; style.align_content = AlignContent::Stretch; style.flex_grow = 1.0; style.flex_shrink = 1.0; style.flex_basis = LengthPercentageAuto::Auto; // Grid properties style.grid_template_columns = vec![ TrackDefinition::new(TrackSizingFunction::Fr(1.0)), TrackDefinition::new(TrackSizingFunction::MinMax( Box::new(TrackSizingFunction::Length(100.0)), Box::new(TrackSizingFunction::Fr(2.0)) )), ]; style.row_gap = 10.0; style.column_gap = 10.0; // Use convenience constructors let block_style = ComputedStyle::block(); // display: block let inline_style = ComputedStyle::inline(); // display: inline ``` -------------------------------- ### Run All CSSBox Tests Source: https://github.com/npow/cssbox/blob/main/README.md Execute all tests across the entire workspace, including core layout, flexbox, and grid tests. ```bash cargo test --workspace ``` -------------------------------- ### CSSBox Layout Result Inspection in Rust Source: https://context7.com/npow/cssbox/llms.txt Shows how to compute layout and inspect the results using `LayoutResult`, `BoxTreeBuilder`, and fragment details. Requires importing relevant modules from cssbox_core. ```rust use cssbox_core::tree::BoxTreeBuilder; use cssbox_core::style::ComputedStyle; use cssbox_core::geometry::{Size, Edges}; use cssbox_core::layout::{compute_layout, FixedWidthTextMeasure}; use cssbox_core::values::LengthPercentageAuto; let mut builder = BoxTreeBuilder::new(); let root = builder.root(ComputedStyle::block()); let mut child_style = ComputedStyle::block(); child_style.width = LengthPercentageAuto::px(200.0); child_style.height = LengthPercentageAuto::px(100.0); child_style.padding_top = cssbox_core::values::LengthPercentage::px(10.0); child_style.padding_right = cssbox_core::values::LengthPercentage::px(10.0); child_style.padding_bottom = cssbox_core::values::LengthPercentage::px(10.0); child_style.padding_left = cssbox_core::values::LengthPercentage::px(10.0); child_style.border_top_width = 2.0; child_style.border_right_width = 2.0; child_style.border_bottom_width = 2.0; child_style.border_left_width = 2.0; let child = builder.element(root, child_style); let tree = builder.build(); let result = compute_layout(&tree, &FixedWidthTextMeasure, Size::new(800.0, 600.0)); // Get bounding rect (border box in absolute coordinates) let rect = result.bounding_rect(child).unwrap(); println!("Border box: x={}, y={}, width={}, height={}", rect.x, rect.y, rect.width, rect.height); // width = 200 (content) + 20 (padding) + 4 (border) = 224px // Get detailed layout output let layout = result.get_layout(child).unwrap(); println!("Absolute position: ({}, {})", layout.position.x, layout.position.y); println!("Content size: {}x{}", layout.size.width, layout.size.height); println!("Padding: top={} right={} bottom={} left={}", layout.padding.top, layout.padding.right, layout.padding.bottom, layout.padding.left); // Access fragment directly for more details if let Some(fragment) = result.find_fragment(child) { let border_box = fragment.border_box(); let margin_box = fragment.margin_box(); let content_box = fragment.content_box(); println!("Content box: {:?}", content_box); println!("Border box: {:?}", border_box); println!("Margin box: {:?}", margin_box); } ``` -------------------------------- ### Flexbox Layout with CSSBox Source: https://context7.com/npow/cssbox/llms.txt Configure a flex container with properties like `flex_direction`, `flex_wrap`, `justify_content`, and `align_items`. Items can have `flex_grow` and `flex_shrink` properties. ```rust use cssbox_core::tree::BoxTreeBuilder; use cssbox_core::style::{ComputedStyle, Display, FlexDirection, FlexWrap, JustifyContent, AlignItems}; use cssbox_core::geometry::Size; use cssbox_core::layout::{compute_layout, FixedWidthTextMeasure}; use cssbox_core::values::LengthPercentageAuto; let mut builder = BoxTreeBuilder::new(); // Create flex container let mut flex_style = ComputedStyle { display: Display::FLEX, flex_direction: FlexDirection::Row, flex_wrap: FlexWrap::Wrap, justify_content: JustifyContent::SpaceBetween, align_items: AlignItems::Center, ..ComputedStyle::block() }; flex_style.row_gap = 10.0; flex_style.column_gap = 10.0; let container = builder.root(flex_style); // Add flex items with grow factors for i in 0..3 { let mut item_style = ComputedStyle::block(); item_style.flex_grow = 1.0; item_style.flex_shrink = 1.0; item_style.height = LengthPercentageAuto::px(50.0); builder.element(container, item_style); } let tree = builder.build(); let result = compute_layout(&tree, &FixedWidthTextMeasure, Size::new(900.0, 600.0)); // Each item gets 300px width (900 / 3) let children = tree.children(tree.root()); for (i, &child) in children.iter().enumerate() { let rect = result.bounding_rect(child).unwrap(); println!("Item {}: x={}, width={}", i, rect.x, rect.width); } ``` -------------------------------- ### Run Specific CSSBox Core Tests Source: https://github.com/npow/cssbox/blob/main/README.md Filter and run tests related to specific layout algorithms like 'block', 'flex', or 'grid' within the `cssbox-core` crate. ```bash cargo test -p cssbox-core block ``` ```bash cargo test -p cssbox-core flex ``` ```bash cargo test -p cssbox-core grid ``` -------------------------------- ### Compute Layout with Box Tree Source: https://context7.com/npow/cssbox/llms.txt Use `compute_layout` with a `BoxTreeBuilder` to construct a box tree and then compute its layout. Access results via `bounding_rect` and `find_fragment`. ```rust use cssbox_core::tree::BoxTreeBuilder; use cssbox_core::style::ComputedStyle; use cssbox_core::geometry::Size; use cssbox_core::layout::{compute_layout, FixedWidthTextMeasure}; use cssbox_core::values::LengthPercentageAuto; let mut builder = BoxTreeBuilder::new(); let root = builder.root(ComputedStyle::block()); // Create nested structure let mut outer_style = ComputedStyle::block(); outer_style.width = LengthPercentageAuto::px(400.0); let outer = builder.element(root, outer_style); let mut inner1_style = ComputedStyle::block(); inner1_style.height = LengthPercentageAuto::px(100.0); let inner1 = builder.element(outer, inner1_style); let mut inner2_style = ComputedStyle::block(); inner2_style.height = LengthPercentageAuto::px(150.0); let inner2 = builder.element(outer, inner2_style); let tree = builder.build(); // Run layout computation let result = compute_layout(&tree, &FixedWidthTextMeasure, Size::new(800.0, 600.0)); // Access layout results let outer_rect = result.bounding_rect(outer).unwrap(); assert_eq!(outer_rect.height, 250.0); // 100 + 150 let inner1_rect = result.bounding_rect(inner1).unwrap(); assert_eq!(inner1_rect.y, 0.0); let inner2_rect = result.bounding_rect(inner2).unwrap(); assert_eq!(inner2_rect.y, 100.0); // Stacked below inner1 // Find specific fragments if let Some(fragment) = result.find_fragment(inner1) { println!("Fragment content size: {:?}", fragment.size); println!("Border box: {:?}", fragment.border_box()); println!("Margin box: {:?}", fragment.margin_box()); } ``` -------------------------------- ### Construct a box tree programmatically Source: https://context7.com/npow/cssbox/llms.txt Use BoxTreeBuilder to define styled nodes and compute layout coordinates for a specific viewport. ```rust use cssbox_core::tree::BoxTreeBuilder; use cssbox_core::style::ComputedStyle; use cssbox_core::geometry::Size; use cssbox_core::layout::{compute_layout, FixedWidthTextMeasure}; use cssbox_core::values::LengthPercentageAuto; // Create a new builder let mut builder = BoxTreeBuilder::new(); // Create root with block display let root = builder.root(ComputedStyle::block()); // Add a child element with explicit dimensions let mut child_style = ComputedStyle::block(); child_style.width = LengthPercentageAuto::px(200.0); child_style.height = LengthPercentageAuto::px(100.0); let child = builder.element(root, child_style); // Add a second child let mut child2_style = ComputedStyle::block(); child2_style.height = LengthPercentageAuto::px(75.0); builder.element(root, child2_style); // Add text content builder.text(child, "Hello, cssbox!"); // Build the final tree let tree = builder.build(); // Compute layout against an 800x600 viewport let result = compute_layout(&tree, &FixedWidthTextMeasure, Size::new(800.0, 600.0)); // Query the result - similar to getBoundingClientRect() let rect = result.bounding_rect(child).unwrap(); assert_eq!(rect.width, 200.0); assert_eq!(rect.height, 100.0); // Get detailed layout info let layout = result.get_layout(child).unwrap(); println!("Position: ({}, {})", layout.position.x, layout.position.y); println!("Content size: {}x{}", layout.size.width, layout.size.height); println!("Padding: {:?}", layout.padding); println!("Border: {:?}", layout.border); println!("Margin: {:?}", layout.margin); ``` -------------------------------- ### Parse HTML and CSS into a box tree Source: https://context7.com/npow/cssbox/llms.txt Utilize html_to_box_tree to convert HTML strings with inline or embedded styles into a layout-ready tree. ```rust use cssbox_dom::computed::html_to_box_tree; use cssbox_core::geometry::Size; use cssbox_core::layout::{compute_layout, FixedWidthTextMeasure}; // Parse HTML with inline styles let tree = html_to_box_tree(r#"
"#); let result = compute_layout(&tree, &FixedWidthTextMeasure, Size::new(800.0, 600.0)); let root_rect = result.bounding_rect(tree.root()).unwrap(); println!("Container size: {}x{}", root_rect.width, root_rect.height); // Parse HTML with embedded
Cell 1
Cell 2
Cell 3
Cell 4
"#); let result = compute_layout(&tree, &FixedWidthTextMeasure, Size::new(600.0, 400.0)); ``` -------------------------------- ### Implement Custom TextMeasure Trait Source: https://context7.com/npow/cssbox/llms.txt Implement the `TextMeasure` trait to provide custom text measurement logic, integrating with your font rasterizer. The `FixedWidthTextMeasure` is available for testing. ```rust use cssbox_core::layout::TextMeasure; use cssbox_core::geometry::Size; use cssbox_core::tree::BoxTreeBuilder; use cssbox_core::style::ComputedStyle; use cssbox_core::layout::compute_layout; // Custom text measurer using your font library struct MyFontMeasure { // Your font context (e.g., rusttype, fontdue, cosmic-text) } impl TextMeasure for MyFontMeasure { fn measure(&self, text: &str, font_size: f32, max_width: f32) -> Size { // Example: estimate based on character count and font metrics let avg_char_width = font_size * 0.5; // Approximate let line_height = font_size * 1.2; let total_width = text.len() as f32 * avg_char_width; if total_width <= max_width { Size::new(total_width, line_height) } else { // Calculate line wrapping let chars_per_line = (max_width / avg_char_width).floor() as usize; let lines = (text.len() + chars_per_line - 1) / chars_per_line; Size::new(max_width, lines as f32 * line_height) } } } // Use built-in FixedWidthTextMeasure for testing (8px per character) use cssbox_core::layout::FixedWidthTextMeasure; let mut builder = BoxTreeBuilder::new(); let root = builder.root(ComputedStyle::block()); builder.text(root, "Hello World"); let tree = builder.build(); let result = compute_layout(&tree, &FixedWidthTextMeasure, Size::new(800.0, 600.0)); // "Hello World" = 11 chars * 8px = 88px width ``` -------------------------------- ### Define Text Measurement Trait in Rust Source: https://github.com/npow/cssbox/blob/main/README.md Implement this trait to provide font metrics for text measurement in CSSBox. A `FixedWidthTextMeasure` is included for testing. ```rust pub trait TextMeasure { fn measure(&self, text: &str, font_size: f32, max_width: f32) -> Size; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.