Commit f8da20ea authored by Rob Buis's avatar Rob Buis Committed by Commit Bot

[mathml] Layout constraints for target stretch sizes

This commit adds new constraints to NGConstraintSpace to indicate the "target"
inline/block size to which the unique operator in the sub tree should try
to stretch.
See https://mathml-refresh.github.io/mathml-core/#dfn-inline-stretch-size-constraint

Bug: 6606
Change-Id: Ia7b8d9c1b153d6e55ce5fa5f6a716fa26f0e9a2e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1911741
Commit-Queue: Rob Buis <rbuis@igalia.com>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: default avatarFrédéric Wang <fwang@igalia.com>
Cr-Commit-Position: refs/heads/master@{#733423}
parent 4fdd0cc5
...@@ -251,6 +251,36 @@ class CORE_EXPORT NGConstraintSpace final { ...@@ -251,6 +251,36 @@ class CORE_EXPORT NGConstraintSpace final {
return LayoutUnit(); return LayoutUnit();
} }
// Inline/block target stretch size constraints.
// See:
// https://mathml-refresh.github.io/mathml-core/#dfn-inline-stretch-size-constraint
LayoutUnit TargetStretchInlineSize() const {
return HasRareData() ? rare_data_->TargetStretchInlineSize()
: kIndefiniteSize;
}
bool HasTargetStretchInlineSize() const {
return TargetStretchInlineSize() != kIndefiniteSize;
}
LayoutUnit TargetStretchAscentSize() const {
return HasRareData() ? rare_data_->TargetStretchAscentSize()
: kIndefiniteSize;
}
bool HasTargetStretchAscentSize() const {
return TargetStretchAscentSize() != kIndefiniteSize;
}
LayoutUnit TargetStretchDescentSize() const {
return HasRareData() ? rare_data_->TargetStretchDescentSize()
: kIndefiniteSize;
}
bool HasTargetStretchDescentSize() const {
return TargetStretchDescentSize() != kIndefiniteSize;
}
// Return the borders which should be used for a table-cell. // Return the borders which should be used for a table-cell.
NGBoxStrut TableCellBorders() const { NGBoxStrut TableCellBorders() const {
return HasRareData() ? rare_data_->TableCellBorders() : NGBoxStrut(); return HasRareData() ? rare_data_->TableCellBorders() : NGBoxStrut();
...@@ -600,6 +630,7 @@ class CORE_EXPORT NGConstraintSpace final { ...@@ -600,6 +630,7 @@ class CORE_EXPORT NGConstraintSpace final {
// - The margin strut. // - The margin strut.
// - Anything to do with floats (the exclusion space, clearance offset, etc). // - Anything to do with floats (the exclusion space, clearance offset, etc).
// - Anything to do with fragmentation. // - Anything to do with fragmentation.
// - Anything to do with stretching of math operators.
// //
// This information is kept in a separate in this heap-allocated struct to // This information is kept in a separate in this heap-allocated struct to
// reduce memory usage. Over time this may have to change based on usage data. // reduce memory usage. Over time this may have to change based on usage data.
...@@ -645,6 +676,9 @@ class CORE_EXPORT NGConstraintSpace final { ...@@ -645,6 +676,9 @@ class CORE_EXPORT NGConstraintSpace final {
case kCustomData: case kCustomData:
new (&custom_data_) CustomData(other.custom_data_); new (&custom_data_) CustomData(other.custom_data_);
break; break;
case kStretchData:
new (&stretch_data_) StretchData(other.stretch_data_);
break;
default: default:
NOTREACHED(); NOTREACHED();
} }
...@@ -662,6 +696,9 @@ class CORE_EXPORT NGConstraintSpace final { ...@@ -662,6 +696,9 @@ class CORE_EXPORT NGConstraintSpace final {
case kCustomData: case kCustomData:
custom_data_.~CustomData(); custom_data_.~CustomData();
break; break;
case kStretchData:
stretch_data_.~StretchData();
break;
default: default:
NOTREACHED(); NOTREACHED();
} }
...@@ -673,7 +710,8 @@ class CORE_EXPORT NGConstraintSpace final { ...@@ -673,7 +710,8 @@ class CORE_EXPORT NGConstraintSpace final {
kNone, kNone,
kBlockData, // An inflow block which doesn't establish a new FC. kBlockData, // An inflow block which doesn't establish a new FC.
kTableCellData, // A table-cell (display: table-cell). kTableCellData, // A table-cell (display: table-cell).
kCustomData // A custom layout (display: layout(foo)). kCustomData, // A custom layout (display: layout(foo)).
kStretchData // The target inline/block stretch sizes for MathML.
}; };
LogicalSize percentage_resolution_size; LogicalSize percentage_resolution_size;
...@@ -683,7 +721,7 @@ class CORE_EXPORT NGConstraintSpace final { ...@@ -683,7 +721,7 @@ class CORE_EXPORT NGConstraintSpace final {
LayoutUnit fragmentainer_block_size = kIndefiniteSize; LayoutUnit fragmentainer_block_size = kIndefiniteSize;
LayoutUnit fragmentainer_offset_at_bfc; LayoutUnit fragmentainer_offset_at_bfc;
unsigned data_union_type : 2; unsigned data_union_type : 3;
unsigned is_restricted_block_size_table_cell : 1; unsigned is_restricted_block_size_table_cell : 1;
unsigned hide_table_cell_if_empty : 1; unsigned hide_table_cell_if_empty : 1;
...@@ -716,8 +754,11 @@ class CORE_EXPORT NGConstraintSpace final { ...@@ -716,8 +754,11 @@ class CORE_EXPORT NGConstraintSpace final {
if (data_union_type == kTableCellData) if (data_union_type == kTableCellData)
return table_cell_data_.MaySkipLayout(other.table_cell_data_); return table_cell_data_.MaySkipLayout(other.table_cell_data_);
DCHECK_EQ(data_union_type, kCustomData); if (data_union_type == kCustomData)
return custom_data_.MaySkipLayout(other.custom_data_); return custom_data_.MaySkipLayout(other.custom_data_);
DCHECK_EQ(data_union_type, kStretchData);
return stretch_data_.MaySkipLayout(other.stretch_data_);
} }
// Must be kept in sync with members checked within |MaySkipLayout|. // Must be kept in sync with members checked within |MaySkipLayout|.
...@@ -739,8 +780,11 @@ class CORE_EXPORT NGConstraintSpace final { ...@@ -739,8 +780,11 @@ class CORE_EXPORT NGConstraintSpace final {
if (data_union_type == kTableCellData) if (data_union_type == kTableCellData)
return table_cell_data_.IsInitialForMaySkipLayout(); return table_cell_data_.IsInitialForMaySkipLayout();
DCHECK_EQ(data_union_type, kCustomData); if (data_union_type == kCustomData)
return custom_data_.IsInitialForMaySkipLayout(); return custom_data_.IsInitialForMaySkipLayout();
DCHECK_EQ(data_union_type, kStretchData);
return stretch_data_.IsInitialForMaySkipLayout();
} }
NGMarginStrut MarginStrut() const { NGMarginStrut MarginStrut() const {
...@@ -818,6 +862,39 @@ class CORE_EXPORT NGConstraintSpace final { ...@@ -818,6 +862,39 @@ class CORE_EXPORT NGConstraintSpace final {
EnsureCustomData()->data = std::move(custom_layout_data); EnsureCustomData()->data = std::move(custom_layout_data);
} }
LayoutUnit TargetStretchInlineSize() const {
return data_union_type == kStretchData
? stretch_data_.target_stretch_inline_size
: kIndefiniteSize;
}
void SetTargetStretchInlineSize(LayoutUnit target_stretch_inline_size) {
EnsureStretchData()->target_stretch_inline_size =
target_stretch_inline_size;
}
LayoutUnit TargetStretchAscentSize() const {
return data_union_type == kStretchData
? stretch_data_.target_stretch_ascent_size
: kIndefiniteSize;
}
void SetTargetStretchAscentSize(LayoutUnit target_stretch_ascent_size) {
EnsureStretchData()->target_stretch_ascent_size =
target_stretch_ascent_size;
}
LayoutUnit TargetStretchDescentSize() const {
return data_union_type == kStretchData
? stretch_data_.target_stretch_descent_size
: kIndefiniteSize;
}
void SetTargetStretchDescentSize(LayoutUnit target_stretch_descent_size) {
EnsureStretchData()->target_stretch_descent_size =
target_stretch_descent_size;
}
private: private:
struct BlockData { struct BlockData {
NGMarginStrut margin_strut; NGMarginStrut margin_strut;
...@@ -883,10 +960,38 @@ class CORE_EXPORT NGConstraintSpace final { ...@@ -883,10 +960,38 @@ class CORE_EXPORT NGConstraintSpace final {
return &custom_data_; return &custom_data_;
} }
struct StretchData {
LayoutUnit target_stretch_inline_size = kIndefiniteSize;
LayoutUnit target_stretch_ascent_size = kIndefiniteSize;
LayoutUnit target_stretch_descent_size = kIndefiniteSize;
bool MaySkipLayout(const StretchData& other) const {
return target_stretch_inline_size == other.target_stretch_inline_size &&
target_stretch_ascent_size == other.target_stretch_ascent_size &&
target_stretch_descent_size == other.target_stretch_descent_size;
}
bool IsInitialForMaySkipLayout() const {
return target_stretch_inline_size == kIndefiniteSize &&
target_stretch_ascent_size == kIndefiniteSize &&
target_stretch_descent_size == kIndefiniteSize;
}
};
StretchData* EnsureStretchData() {
DCHECK(data_union_type == kNone || data_union_type == kStretchData);
if (data_union_type != kStretchData) {
data_union_type = kStretchData;
new (&stretch_data_) StretchData();
}
return &stretch_data_;
}
union { union {
BlockData block_data_; BlockData block_data_;
TableCellData table_cell_data_; TableCellData table_cell_data_;
CustomData custom_data_; CustomData custom_data_;
StretchData stretch_data_;
}; };
}; };
......
...@@ -314,6 +314,24 @@ class CORE_EXPORT NGConstraintSpaceBuilder final { ...@@ -314,6 +314,24 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
} }
} }
void SetTargetStretchInlineSize(LayoutUnit target_stretch_inline_size) {
DCHECK_GE(target_stretch_inline_size, LayoutUnit());
space_.EnsureRareData()->SetTargetStretchInlineSize(
target_stretch_inline_size);
}
void SetTargetStretchAscentSize(LayoutUnit target_stretch_ascent_size) {
DCHECK_GE(target_stretch_ascent_size, LayoutUnit());
space_.EnsureRareData()->SetTargetStretchAscentSize(
target_stretch_ascent_size);
}
void SetTargetStretchDescentSize(LayoutUnit target_stretch_descent_size) {
DCHECK_GE(target_stretch_descent_size, LayoutUnit());
space_.EnsureRareData()->SetTargetStretchDescentSize(
target_stretch_descent_size);
}
// Creates a new constraint space. // Creates a new constraint space.
const NGConstraintSpace ToConstraintSpace() { const NGConstraintSpace ToConstraintSpace() {
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment