Skip to content

Fixed-size layout overflows with measure_function. #732

Open
@SoulSharer

Description

taffy version

02453b2 and fae17c2 (v0.6.1)

Platform

Rust

What you did

I took examples/measure.rs and changed:

  • Available space on compute_layout_with_measure() to be fixed 512x512.
  • Changed image size to be 600x720, so that aspect ratio could cause overflow of the layout.
  • Added flex_shrink: 1 to children Styles in hopes it would fix calculation.
  • Root node size fills available space with percent(1.0).

Modified measure.rs follows:

mod common {
    pub mod image;
    pub mod text;
}
use common::image::{image_measure_function, ImageContext};
use common::text::{text_measure_function, FontMetrics, TextContext, WritingMode, LOREM_IPSUM};
use taffy::prelude::*;

enum NodeContext {
    Text(TextContext),
    Image(ImageContext),
}

fn measure_function(
    known_dimensions: taffy::geometry::Size<Option<f32>>,
    available_space: taffy::geometry::Size<taffy::style::AvailableSpace>,
    node_context: Option<&mut NodeContext>,
    font_metrics: &FontMetrics,
) -> Size<f32> {
    if let Size { width: Some(width), height: Some(height) } = known_dimensions {
        return Size { width, height };
    }

    match node_context {
        None => Size::ZERO,
        Some(NodeContext::Text(text_context)) => {
            text_measure_function(known_dimensions, available_space, &*text_context, font_metrics)
        }
        Some(NodeContext::Image(image_context)) => image_measure_function(known_dimensions, image_context),
    }
}

fn main() -> Result<(), taffy::TaffyError> {
    let mut taffy: TaffyTree<NodeContext> = TaffyTree::new();

    let font_metrics = FontMetrics { char_width: 10.0, char_height: 10.0 };

    let text_node = taffy.new_leaf_with_context(
        Style {
            flex_shrink: 1.0,
            ..Default::default()
        },
        NodeContext::Text(TextContext { text_content: LOREM_IPSUM.into(), writing_mode: WritingMode::Horizontal }),
    )?;

    let image_node = taffy
        .new_leaf_with_context(Style {
            flex_shrink: 1.0,
            ..Default::default()
        }, NodeContext::Image(ImageContext { width: 600.0, height: 720.0 }))?;

    let root = taffy.new_with_children(
        Style {
            display: Display::Flex,
            flex_direction: FlexDirection::Column,
            size: percent(1.0),
            ..Default::default()
        },
        &[text_node, image_node],
    )?;

    // Compute layout and print result
    taffy.compute_layout_with_measure(
        root,
        Size { width: taffy::AvailableSpace::Definite(512.0), height: taffy::AvailableSpace::Definite(512.0) },
        // Note: this closure is a FnMut closure and can be used to borrow external context for the duration of layout
        // For example, you may wish to borrow a global font registry and pass it into your text measuring function
        |known_dimensions, available_space, _node_id, node_context, _style| {
            measure_function(known_dimensions, available_space, node_context, &font_metrics)
        },
    )?;
    taffy.print_tree(root);

    Ok(())
}

Result is:

TREE
└──  FLEX COL [x: 0    y: 0    w: 512  h: 512  content_w: 600  content_h: 810  border: l:0 r:0 t:0 b:0, padding: l:0 r:0 t:0 b:0] (NodeId(4294967299))
    ├──  LEAF [x: 0    y: 0    w: 512  h: 90   content_w: 512  content_h: 90   border: l:0 r:0 t:0 b:0, padding: l:0 r:0 t:0 b:0] (NodeId(4294967297))
    └──  LEAF [x: 0    y: 90   w: 512  h: 614  content_w: 600  content_h: 720  border: l:0 r:0 t:0 b:0, padding: l:0 r:0 t:0 b:0] (NodeId(4294967298))

Second leaf height overflows available space.

What went wrong

  • what were you expecting?
    Leaf children should fit into available space.

  • what actually happened?
    Second leaf overflows layout.

Additional information

I've tried different style configurations, including flex-basis, but all seems to come down to a measure_function which does not receive full information from a parent to properly size image content that would fit the layout.

[examples\common\image.rs:12:5] known_dimensions = Size {
    width: Some(
        512.0,
    ),
    height: None,
}
[examples\common\image.rs:12:5] known_dimensions = Size {
    width: Some(
        512.0,
    ),
    height: None,
}
[examples\common\image.rs:12:5] known_dimensions = Size {
    width: None,
    height: Some(
        614.4,
    ),
}
[examples\common\image.rs:12:5] known_dimensions = Size {
    width: None,
    height: None,
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions