diff --git a/Cargo.lock b/Cargo.lock index ee5352f3e..1aa8ba246 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3273,9 +3273,8 @@ dependencies = [ [[package]] name = "fontique" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6688bc1294fe7117d788937b6c53480169b29c566954af490830d4c09da9516a" +version = "0.11.0" +source = "git+https://github.com/DioxusLabs/parley?rev=a0752c7bdc3ad88dac19fc194d2b8e57e59bea2e#a0752c7bdc3ad88dac19fc194d2b8e57e59bea2e" dependencies = [ "hashbrown 0.17.1", "linebender_resource_handle", @@ -5933,36 +5932,47 @@ dependencies = [ [[package]] name = "parlance" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6937eda350acc1a5d05872c3cbf99fe78619c269096e2be3d4a350058639d5" +source = "git+https://github.com/DioxusLabs/parley?rev=a0752c7bdc3ad88dac19fc194d2b8e57e59bea2e#a0752c7bdc3ad88dac19fc194d2b8e57e59bea2e" [[package]] name = "parley" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22d2ff88bd3f7d68d1d9b09c7e6209f9a8e8c05088295140a2bcf2e9b17038c5" +version = "0.11.0" +source = "git+https://github.com/DioxusLabs/parley?rev=a0752c7bdc3ad88dac19fc194d2b8e57e59bea2e#a0752c7bdc3ad88dac19fc194d2b8e57e59bea2e" dependencies = [ "fontique", - "harfrust", "hashbrown 0.17.1", - "icu_normalizer", - "icu_properties", - "icu_segmenter", "linebender_resource_handle", "parlance", - "parley_data", + "parley_engine", "skrifa", + "smallvec", ] [[package]] name = "parley_data" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1567535334d6ba2d3cde19221ba9a7bd0fabb3cbd99046ddfb10ae061cfcc889" +version = "0.11.0" +source = "git+https://github.com/DioxusLabs/parley?rev=a0752c7bdc3ad88dac19fc194d2b8e57e59bea2e#a0752c7bdc3ad88dac19fc194d2b8e57e59bea2e" dependencies = [ "icu_properties", ] +[[package]] +name = "parley_engine" +version = "0.11.0" +source = "git+https://github.com/DioxusLabs/parley?rev=a0752c7bdc3ad88dac19fc194d2b8e57e59bea2e#a0752c7bdc3ad88dac19fc194d2b8e57e59bea2e" +dependencies = [ + "fontique", + "harfrust", + "hashbrown 0.17.1", + "icu_normalizer", + "icu_properties", + "icu_segmenter", + "linebender_resource_handle", + "parlance", + "parley_data", + "skrifa", +] + [[package]] name = "paste" version = "1.0.15" diff --git a/Cargo.toml b/Cargo.toml index 7e6552be1..4d738810c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -107,7 +107,7 @@ taffy = { version = "0.14.0", default-features = false, features = [ "calc", "detailed_layout_info", ] } -parley = { version = "0.11.1", default-features = false, features = ["std"] } +parley = { git = "https://github.com/DioxusLabs/parley", rev = "5335bd6bc7cfde320e7c9a5c5725b1586588724d", default-features = false, features = ["std"] } skrifa = { version = "0.44", default-features = false, features = [ "std", ] } # Should match parley and vello versions diff --git a/packages/blitz-dom/src/layout/construct.rs b/packages/blitz-dom/src/layout/construct.rs index e1131e082..914167124 100644 --- a/packages/blitz-dom/src/layout/construct.rs +++ b/packages/blitz-dom/src/layout/construct.rs @@ -4,8 +4,8 @@ use std::sync::Arc; use markup5ever::{QualName, local_name, ns}; use parley::{ - FontContext, InlineBox, InlineBoxKind, LayoutContext, StyleProperty, TreeBuilder, - WhiteSpaceCollapse, + FontContext, InlineBox, InlineBoxKind, InlineBoxVerticalAlign, LayoutContext, StyleProperty, + TreeBuilder, WhiteSpaceCollapse, }; use style::{ computed_values::position::T as PositionProperty, @@ -13,6 +13,7 @@ use style::{ shared_lock::StylesheetGuards, values::{ computed::{Content, ContentItem, Display, Float, TextTransform}, + generics::box_::{BaselineShiftKeyword, GenericBaselineShift}, specified::box_::{DisplayInside, DisplayOutside}, }, }; @@ -1041,6 +1042,10 @@ pub(crate) fn build_inline_layout_into( // Create a parley tree builder let mut builder = layout_ctx.tree_builder(font_ctx, scale, true, &parley_style); + // Size every line box as if it started with a zero-width glyph in the root style + // (the CSS "strut", https://www.w3.org/TR/CSS22/visudet.html#strut) + builder.set_compute_strut(true); + // Set whitespace collapsing mode let collapse_mode = root_node_style .as_ref() @@ -1164,6 +1169,17 @@ pub(crate) fn build_inline_layout_into( } else { InlineBoxKind::InFlow }; + let vertical_align = style + .map(|s| match s.clone_baseline_shift() { + GenericBaselineShift::Keyword(BaselineShiftKeyword::Top) => { + InlineBoxVerticalAlign::Top + } + GenericBaselineShift::Keyword(BaselineShiftKeyword::Bottom) => { + InlineBoxVerticalAlign::Bottom + } + _ => InlineBoxVerticalAlign::Baseline, + }) + .unwrap_or_default(); match (display.outside(), display.inside()) { (DisplayOutside::None, DisplayInside::None) => { @@ -1199,6 +1215,8 @@ pub(crate) fn build_inline_layout_into( // Width and height are set during layout width: 0.0, height: 0.0, + baseline: None, + vertical_align, }); } else if *tag_name == local_name!("br") { // node.remove_damage(CONSTRUCT_DESCENDENT | CONSTRUCT_FC | CONSTRUCT_BOX); @@ -1279,6 +1297,8 @@ pub(crate) fn build_inline_layout_into( // Width and height are set during layout width: 0.0, height: 0.0, + baseline: None, + vertical_align, }); } }; diff --git a/packages/blitz-dom/src/layout/inline.rs b/packages/blitz-dom/src/layout/inline.rs index 0b46d3b77..9d4bf348d 100644 --- a/packages/blitz-dom/src/layout/inline.rs +++ b/packages/blitz-dom/src/layout/inline.rs @@ -312,6 +312,10 @@ impl BaseDocument { ibox.height = 0.0; } else { let output = self.compute_child_layout(taffy::NodeId::from(ibox.id), child_inputs); + ibox.baseline = output + .baselines + .first + .map(|baseline| (margin.top + baseline) * scale); ibox.width = (margin.left + margin.right + output.size.width) * scale; // Vertical margins adjust the space the box reserves in the line, but the // reserved space cannot be negative. @@ -604,7 +608,7 @@ impl BaseDocument { // dbg!(&layout.size); // dbg!(&layout.location); - state.append_inline_box_to_line(box_break_data.advance, 0.0); + state.append_inline_box_to_line(box_break_data.advance, None, false); // if float.is_floated() { // println!("INLINE FLOATED BOX ({}) {:?}", ibox.id, float); diff --git a/packages/blitz-dom/src/node/node.rs b/packages/blitz-dom/src/node/node.rs index 3717cba6e..a2c25406a 100644 --- a/packages/blitz-dom/src/node/node.rs +++ b/packages/blitz-dom/src/node/node.rs @@ -1434,8 +1434,8 @@ impl Node { if let Some((cluster, _side)) = Cluster::from_point_exact(layout, x * scale, y * scale) { - let style_index = cluster.glyphs().next()?.style_index(); - let node_id = layout.styles()[style_index].brush.id; + let style_index = cluster.style_index(); + let node_id = layout.styles()[usize::from(style_index)].brush.id; let text_pointer_events_none = self .with(node_id) .primary_styles() diff --git a/packages/blitz-paint/src/text.rs b/packages/blitz-paint/src/text.rs index 358c55881..fa4476f22 100644 --- a/packages/blitz-paint/src/text.rs +++ b/packages/blitz-paint/src/text.rs @@ -54,7 +54,7 @@ pub(crate) fn draw_inline_backgrounds<'a>( continue; } - let metrics = glyph_run.run().metrics(); + let metrics = glyph_run.run().font_metrics(); let x = glyph_run.offset() as f64; let w = glyph_run.advance() as f64; let baseline = glyph_run.baseline() as f64; @@ -574,9 +574,9 @@ pub(crate) fn stroke_text<'a>( for item in line.items() { if let PositionedLayoutItem::GlyphRun(glyph_run) = item { let run = glyph_run.run(); - let font = run.font(); + let font = &run.font().font; let font_size = run.font_size(); - let metrics = run.metrics(); + let metrics = run.font_metrics(); let style = glyph_run.style(); let synthesis = run.synthesis(); let glyph_xform = synthesis @@ -620,11 +620,17 @@ pub(crate) fn stroke_text<'a>( kurbo::Vec2::default() }; + let normalized_coords: Vec = run + .normalized_coords() + .iter() + .map(|coord| coord.to_bits()) + .collect(); + scene.draw_glyphs( font, font_size, !FONT_EMBOLDEN_ENABLED, // hint - run.normalized_coords(), + &normalized_coords, embolden, Fill::NonZero, &anyrender::Paint::from(text_color),