render: separate text and item alignment
This commit is contained in:
1 parent
49541792ee
commit
bd9c161f55
4 files changed
+32
-31
No files matched your search
@@ -341,6 +341,7 @@ pub fn layout_dom_with_images(
|
|||||||
font_size: Option<f32>,
|
font_size: Option<f32>,
|
||||||
font_weight: Option<String>,
|
font_weight: Option<String>,
|
||||||
font_family: Option<String>,
|
font_family: Option<String>,
|
||||||
|
text_align: Option<taffy::AlignItems>,
|
||||||
visibility_hidden: bool,
|
visibility_hidden: bool,
|
||||||
opacity_product: f32,
|
opacity_product: f32,
|
||||||
list_style: crate::ListStyle,
|
list_style: crate::ListStyle,
|
||||||
@@ -362,6 +363,7 @@ pub fn layout_dom_with_images(
|
|||||||
font_size: None,
|
font_size: None,
|
||||||
font_weight: None,
|
font_weight: None,
|
||||||
font_family: None,
|
font_family: None,
|
||||||
|
text_align: None,
|
||||||
visibility_hidden: false,
|
visibility_hidden: false,
|
||||||
opacity_product: 1.0,
|
opacity_product: 1.0,
|
||||||
// CSS initial value of list-style-type.
|
// CSS initial value of list-style-type.
|
||||||
@@ -466,6 +468,7 @@ pub fn layout_dom_with_images(
|
|||||||
}
|
}
|
||||||
match &style.font_weight { Some(w) => inh.font_weight = Some(w.clone()), None => style.font_weight = inh.font_weight.clone() }
|
match &style.font_weight { Some(w) => inh.font_weight = Some(w.clone()), None => style.font_weight = inh.font_weight.clone() }
|
||||||
match &style.font_family { Some(f) => inh.font_family = Some(f.clone()), None => style.font_family = inh.font_family.clone() }
|
match &style.font_family { Some(f) => inh.font_family = Some(f.clone()), None => style.font_family = inh.font_family.clone() }
|
||||||
|
match style.text_align { Some(a) => inh.text_align = Some(a), None => style.text_align = inh.text_align }
|
||||||
inh.visibility_hidden = style.visibility_hidden.unwrap_or(inh.visibility_hidden);
|
inh.visibility_hidden = style.visibility_hidden.unwrap_or(inh.visibility_hidden);
|
||||||
inh.opacity_product *= style.opacity.unwrap_or(1.0);
|
inh.opacity_product *= style.opacity.unwrap_or(1.0);
|
||||||
style.effectively_invisible = inh.visibility_hidden || inh.opacity_product < 0.02;
|
style.effectively_invisible = inh.visibility_hidden || inh.opacity_product < 0.02;
|
||||||
@@ -2056,17 +2059,11 @@ fn build(
|
|||||||
taffy_style.flex_direction = taffy::FlexDirection::Row;
|
taffy_style.flex_direction = taffy::FlexDirection::Row;
|
||||||
taffy_style.flex_wrap = taffy::FlexWrap::Wrap;
|
taffy_style.flex_wrap = taffy::FlexWrap::Wrap;
|
||||||
|
|
||||||
// Before promotion, `align_items` was the horizontal-position stand-in
|
// The promoted container's main axis is horizontal, so text alignment
|
||||||
// for a column container (from `text-align` or `<center>`; see
|
// belongs on `justify_content`. Real `justify-content` from actual CSS
|
||||||
// `style::apply_value`'s "text-align" arm): correct there, since a
|
// wins if present.
|
||||||
// column's cross axis is horizontal. The promoted container's *main*
|
|
||||||
// axis is horizontal instead, so that same "where should content sit
|
|
||||||
// horizontally" intent now belongs on `justify_content`, not
|
|
||||||
// `align_items` — otherwise e.g. `text-align: right` shoves wrapped
|
|
||||||
// text to the bottom of its line (the new cross axis) rather than to
|
|
||||||
// the right. Real `justify-content` from actual CSS wins if present.
|
|
||||||
if style.justify_content.is_none() {
|
if style.justify_content.is_none() {
|
||||||
taffy_style.justify_content = match style.align_items {
|
taffy_style.justify_content = match style.text_align {
|
||||||
Some(taffy::AlignItems::FLEX_END) => Some(taffy::JustifyContent::FLEX_END),
|
Some(taffy::AlignItems::FLEX_END) => Some(taffy::JustifyContent::FLEX_END),
|
||||||
Some(taffy::AlignItems::CENTER) => Some(taffy::JustifyContent::CENTER),
|
Some(taffy::AlignItems::CENTER) => Some(taffy::JustifyContent::CENTER),
|
||||||
_ => taffy_style.justify_content,
|
_ => taffy_style.justify_content,
|
||||||
@@ -2349,11 +2346,11 @@ fn run_leaf_style() -> taffy::Style {
|
|||||||
|
|
||||||
/// Style for an anonymous inline-run wrapper: a full-width block-level box
|
/// Style for an anonymous inline-run wrapper: a full-width block-level box
|
||||||
/// whose interior is the flex-wrap approximation of an inline formatting
|
/// whose interior is the flex-wrap approximation of an inline formatting
|
||||||
/// context. The parent's `text-align` stand-in (align_items) moves the run's
|
/// context. The parent's `text-align` moves the run's line content via
|
||||||
/// line content via justify-content, exactly as the old whole-container
|
/// justify-content, exactly as the old whole-container
|
||||||
/// promotion did, but scoped to the run so sibling blocks stay full width.
|
/// promotion did, but scoped to the run so sibling blocks stay full width.
|
||||||
fn run_wrapper_style(parent: &crate::LayoutStyle) -> taffy::Style {
|
fn run_wrapper_style(parent: &crate::LayoutStyle) -> taffy::Style {
|
||||||
let justify = match parent.align_items {
|
let justify = match parent.text_align {
|
||||||
Some(taffy::AlignItems::FLEX_END) => Some(taffy::JustifyContent::FLEX_END),
|
Some(taffy::AlignItems::FLEX_END) => Some(taffy::JustifyContent::FLEX_END),
|
||||||
Some(taffy::AlignItems::CENTER) => Some(taffy::JustifyContent::CENTER),
|
Some(taffy::AlignItems::CENTER) => Some(taffy::JustifyContent::CENTER),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ impl TextEngine {
|
|||||||
let rich = spans.iter().map(|(t, a)| (t.as_str(), a.to_attrs()));
|
let rich = spans.iter().map(|(t, a)| (t.as_str(), a.to_attrs()));
|
||||||
buffer.set_rich_text(&mut self.font_system, rich, Attrs::new().family(Family::Name(FAMILY)), Shaping::Advanced);
|
buffer.set_rich_text(&mut self.font_system, rich, Attrs::new().family(Family::Name(FAMILY)), Shaping::Advanced);
|
||||||
|
|
||||||
let align = match base.align_items {
|
let align = match base.text_align {
|
||||||
Some(taffy::AlignItems::CENTER) => Some(Align::Center),
|
Some(taffy::AlignItems::CENTER) => Some(Align::Center),
|
||||||
Some(taffy::AlignItems::FLEX_END) => Some(Align::End),
|
Some(taffy::AlignItems::FLEX_END) => Some(Align::End),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|||||||
@@ -278,6 +278,10 @@ pub struct LayoutStyle {
|
|||||||
/// resolves it to a bundled face (Liberation Sans/Serif/Mono) the way
|
/// resolves it to a bundled face (Liberation Sans/Serif/Mono) the way
|
||||||
/// Chromium picks a generic family on this host.
|
/// Chromium picks a generic family on this host.
|
||||||
pub font_family: Option<String>,
|
pub font_family: Option<String>,
|
||||||
|
/// Inherited `text-align`, represented with the matching horizontal
|
||||||
|
/// alignment keywords. Kept separate from flex/grid `align-items`: using
|
||||||
|
/// one field for both made `text-align:left` shrink-wrap flex children.
|
||||||
|
pub text_align: Option<taffy::AlignItems>,
|
||||||
pub align_items: Option<taffy::AlignItems>,
|
pub align_items: Option<taffy::AlignItems>,
|
||||||
pub flex_direction: Option<taffy::FlexDirection>,
|
pub flex_direction: Option<taffy::FlexDirection>,
|
||||||
pub flex_wrap: Option<taffy::FlexWrap>,
|
pub flex_wrap: Option<taffy::FlexWrap>,
|
||||||
@@ -644,16 +648,12 @@ pub(crate) fn to_taffy_style(style: &LayoutStyle) -> Style {
|
|||||||
BoxSizing::Inherit => taffy::BoxSizing::ContentBox,
|
BoxSizing::Inherit => taffy::BoxSizing::ContentBox,
|
||||||
};
|
};
|
||||||
|
|
||||||
// A block box that wants non-default cross-axis alignment (from
|
// A block box with centered/right inline content needs a flex-column
|
||||||
// text-align: center/right, the only way our engine currently sets
|
// stand-in because taffy's native block algorithm has no line alignment.
|
||||||
// align_items on a block-level element) needs a flex column to have any
|
// `text_align` is separate from real flex/grid `align-items`, so a
|
||||||
// effect at all: taffy's native block algorithm (used for plain
|
// text-align declaration never changes how flex children are sized.
|
||||||
// Display::Block) has no align-items concept whatsoever, it only ever
|
|
||||||
// places block children at the start edge. Promote such boxes to a flex
|
|
||||||
// column, matching the same column-flex approximation already used for
|
|
||||||
// elements like <td> and <center>.
|
|
||||||
let promote_for_alignment = style.display == Display::Block
|
let promote_for_alignment = style.display == Display::Block
|
||||||
&& matches!(style.align_items, Some(taffy::AlignItems::CENTER) | Some(taffy::AlignItems::FLEX_END));
|
&& matches!(style.text_align, Some(taffy::AlignItems::CENTER) | Some(taffy::AlignItems::FLEX_END));
|
||||||
|
|
||||||
s.display = match style.display {
|
s.display = match style.display {
|
||||||
Display::Block if promote_for_alignment => taffy::style::Display::Flex,
|
Display::Block if promote_for_alignment => taffy::style::Display::Flex,
|
||||||
@@ -665,6 +665,7 @@ pub(crate) fn to_taffy_style(style: &LayoutStyle) -> Style {
|
|||||||
};
|
};
|
||||||
if promote_for_alignment {
|
if promote_for_alignment {
|
||||||
s.flex_direction = taffy::FlexDirection::Column;
|
s.flex_direction = taffy::FlexDirection::Column;
|
||||||
|
s.align_items = style.text_align;
|
||||||
}
|
}
|
||||||
if let Some(fd) = style.flex_direction {
|
if let Some(fd) = style.flex_direction {
|
||||||
s.flex_direction = fd;
|
s.flex_direction = fd;
|
||||||
@@ -704,9 +705,14 @@ pub(crate) fn to_taffy_style(style: &LayoutStyle) -> Style {
|
|||||||
s.aspect_ratio = Some(ar);
|
s.aspect_ratio = Some(ar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if style.display != Display::Block {
|
||||||
if let Some(ai) = style.align_items {
|
if let Some(ai) = style.align_items {
|
||||||
s.align_items = Some(ai);
|
s.align_items = Some(ai);
|
||||||
}
|
}
|
||||||
|
} else if !promote_for_alignment {
|
||||||
|
// `align-items` has no effect on a block formatting context.
|
||||||
|
s.align_items = None;
|
||||||
|
}
|
||||||
if let Some(jc) = style.justify_content {
|
if let Some(jc) = style.justify_content {
|
||||||
s.justify_content = Some(jc);
|
s.justify_content = Some(jc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -394,15 +394,13 @@ fn apply_value(style: &mut LayoutStyle, name: &str, value: &str) {
|
|||||||
style.font_family = Some(v);
|
style.font_family = Some(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Our engine has no real inline formatting context, so text-align is
|
// Text alignment is inherited and applies to inline line boxes. It is
|
||||||
// approximated the same way as align-items: it positions a block's
|
// deliberately separate from flex/grid `align-items`, which positions
|
||||||
// (or column-flex's) children along the cross axis. See
|
// child boxes rather than text inside them.
|
||||||
// `to_taffy_style`'s block-to-flex-column promotion, which is what
|
|
||||||
// makes this actually take effect on plain block elements.
|
|
||||||
"text-align" => match value {
|
"text-align" => match value {
|
||||||
"right" => style.align_items = Some(taffy::AlignItems::FLEX_END),
|
"right" | "end" => style.text_align = Some(taffy::AlignItems::FLEX_END),
|
||||||
"center" => style.align_items = Some(taffy::AlignItems::CENTER),
|
"center" => style.text_align = Some(taffy::AlignItems::CENTER),
|
||||||
"left" | "start" | "justify" => style.align_items = Some(taffy::AlignItems::FLEX_START),
|
"left" | "start" | "justify" => style.text_align = Some(taffy::AlignItems::FLEX_START),
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
"align-items" => {
|
"align-items" => {
|
||||||
|
|||||||
Reference in new issue
Block a user