Commit 2e4742ed authored by Frédéric Wang's avatar Frédéric Wang Committed by Commit Bot

[mathml] Refine constants used for <munderover> layout

This CL reorganizes a bit how constants are determined for the layout
algorithm of the mover/munder/moverunder elements, trying to match
more closely the text in the specification. In particular, the three
main cases are now considered [1] [2]:

1. The base is an embellished operator with the largeop property.
2. The base is an embellished operator with the stretchy property and
   stretch axis inline.
3. Otherwise

These are verified by underover-parameters-* WPT tests. Tests 1 and 2
cover the corresponding cases in the spec. The other tests verify the
otherwise clause, but will require follow-up work [3] [4]. Finally, this
CL updates the TODO comments in the underover algorithm to point to new
Chromium bug entries.

[1] https://mathml-refresh.github.io/mathml-core/#base-with-underscript
[2] https://mathml-refresh.github.io/mathml-core/#base-with-overscript
[3] http://crbug.com/1124289
[4] http://crbug.com/1124285

Bug: 6606, 1124285, 1124289
Change-Id: I89f26214ce42b64671490c55bc59835f7afcbbcf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2390760Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: default avatarRob Buis <rbuis@igalia.com>
Commit-Queue: Frédéric Wang <fwang@igalia.com>
Cr-Commit-Position: refs/heads/master@{#803906}
parent b2d537e8
......@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
#include "third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/mathml/mathml_operator_element.h"
#include "third_party/blink/renderer/core/mathml/mathml_under_over_element.h"
namespace blink {
......@@ -32,42 +33,85 @@ struct UnderOverVerticalParameters {
};
UnderOverVerticalParameters GetUnderOverVerticalParameters(
const ComputedStyle& style) {
const ComputedStyle& style,
bool is_base_large_operator,
bool is_base_stretchy_in_inline_axis) {
UnderOverVerticalParameters parameters;
const SimpleFontData* font_data = style.GetFont().PrimaryFont();
if (font_data && !OpenTypeMathSupport::HasMathData(
font_data->PlatformData().GetHarfBuzzFace())) {
// The MATH table specification does not really provide any suggestions,
// except for some underbar/overbar values and AccentBaseHeight.
LayoutUnit default_line_thickness =
LayoutUnit(RuleThicknessFallback(style));
parameters.under_gap_min = 3 * default_line_thickness;
parameters.over_gap_min = 3 * default_line_thickness;
parameters.under_extra_descender = default_line_thickness;
parameters.over_extra_ascender = default_line_thickness;
parameters.accent_base_height =
LayoutUnit(font_data->GetFontMetrics().XHeight());
parameters.use_under_over_bar_fallback = true;
// https://mathml-refresh.github.io/mathml-core/#dfn-default-fallback-constant
const float default_fallback_constant = 0;
if (is_base_large_operator) {
parameters.under_gap_min = LayoutUnit(
MathConstant(style,
OpenTypeMathSupport::MathConstants::kLowerLimitGapMin)
.value_or(default_fallback_constant));
parameters.over_gap_min = LayoutUnit(
MathConstant(style,
OpenTypeMathSupport::MathConstants::kUpperLimitGapMin)
.value_or(default_fallback_constant));
parameters.under_shift_min = LayoutUnit(
MathConstant(
style,
OpenTypeMathSupport::MathConstants::kLowerLimitBaselineDropMin)
.value_or(default_fallback_constant));
parameters.over_shift_min = LayoutUnit(
MathConstant(
style,
OpenTypeMathSupport::MathConstants::kUpperLimitBaselineRiseMin)
.value_or(default_fallback_constant));
parameters.under_extra_descender = LayoutUnit();
parameters.over_extra_ascender = LayoutUnit();
parameters.use_under_over_bar_fallback = false;
return parameters;
}
if (is_base_stretchy_in_inline_axis) {
parameters.under_gap_min = LayoutUnit(
MathConstant(
style, OpenTypeMathSupport::MathConstants::kStretchStackGapBelowMin)
.value_or(default_fallback_constant));
parameters.over_gap_min = LayoutUnit(
MathConstant(
style, OpenTypeMathSupport::MathConstants::kStretchStackGapAboveMin)
.value_or(default_fallback_constant));
parameters.under_shift_min = LayoutUnit(
MathConstant(
style,
OpenTypeMathSupport::MathConstants::kStretchStackBottomShiftDown)
.value_or(default_fallback_constant));
parameters.over_shift_min = LayoutUnit(
MathConstant(
style, OpenTypeMathSupport::MathConstants::kStretchStackTopShiftUp)
.value_or(default_fallback_constant));
parameters.under_extra_descender = LayoutUnit();
parameters.over_extra_ascender = LayoutUnit();
parameters.use_under_over_bar_fallback = false;
return parameters;
}
// The base is a large operator so we read UpperLimit/LowerLimit constants
// from the MATH table.
// TODO(crbug.com/1124285): Handle accent/accentunder attributes.
// TODO(crbug.com/1124289): Implement AccentBaseHeight.
const float default_rule_thickness = RuleThicknessFallback(style);
parameters.under_gap_min = LayoutUnit(
MathConstant(style, OpenTypeMathSupport::MathConstants::kLowerLimitGapMin)
.value_or(0));
MathConstant(style,
OpenTypeMathSupport::MathConstants::kUnderbarVerticalGap)
.value_or(3 * default_rule_thickness));
parameters.over_gap_min = LayoutUnit(
MathConstant(style, OpenTypeMathSupport::MathConstants::kUpperLimitGapMin)
.value_or(0));
parameters.under_shift_min = LayoutUnit(
MathConstant(
style, OpenTypeMathSupport::MathConstants::kLowerLimitBaselineDropMin)
.value_or(0));
parameters.over_shift_min = LayoutUnit(
MathConstant(
style, OpenTypeMathSupport::MathConstants::kUpperLimitBaselineRiseMin)
.value_or(0));
parameters.use_under_over_bar_fallback = false;
MathConstant(style,
OpenTypeMathSupport::MathConstants::kOverbarVerticalGap)
.value_or(3 * default_rule_thickness));
parameters.under_shift_min = LayoutUnit();
parameters.over_shift_min = LayoutUnit();
parameters.under_extra_descender = LayoutUnit(
MathConstant(style,
OpenTypeMathSupport::MathConstants::kUnderbarExtraDescender)
.value_or(default_rule_thickness));
parameters.over_extra_ascender = LayoutUnit(
MathConstant(style,
OpenTypeMathSupport::MathConstants::kOverbarExtraAscender)
.value_or(default_rule_thickness));
parameters.use_under_over_bar_fallback = true;
return parameters;
}
......@@ -135,10 +179,21 @@ scoped_refptr<const NGLayoutResult> NGMathUnderOverLayoutAlgorithm::Layout() {
BorderScrollbarPadding().StartOffset();
LayoutUnit block_offset = content_start_offset.block_offset;
UnderOverVerticalParameters parameters =
GetUnderOverVerticalParameters(Style());
// TODO(rbuis): handle stretchy operators.
// TODO(rbuis): handle accent.
bool is_base_large_operator = false;
bool is_base_stretchy_in_inline_axis = false;
if (auto* core_operator =
DynamicTo<MathMLOperatorElement>(base.GetLayoutBox()->GetNode())) {
// TODO(crbug.com/1124298): Implement embellished operators.
is_base_large_operator =
core_operator->HasBooleanProperty(MathMLOperatorElement::kLargeOp);
is_base_stretchy_in_inline_axis =
core_operator->HasBooleanProperty(MathMLOperatorElement::kStretchy) &&
!core_operator->GetOperatorContent().is_vertical;
}
UnderOverVerticalParameters parameters = GetUnderOverVerticalParameters(
Style(), is_base_large_operator, is_base_stretchy_in_inline_axis);
// TODO(crbug.com/1124301): handle stretchy operators.
// All children are positioned centered relative to the container (and
// therefore centered relative to themselves).
......
......@@ -36,10 +36,10 @@ class CORE_EXPORT MathMLOperatorElement final : public MathMLElement {
void AddMathRSpaceIfNeeded(ComputedStyle&, const CSSToLengthConversionData&);
void AddMathMinSizeIfNeeded(ComputedStyle&, const CSSToLengthConversionData&);
void AddMathMaxSizeIfNeeded(ComputedStyle&, const CSSToLengthConversionData&);
const OperatorContent& GetOperatorContent();
private:
base::Optional<OperatorContent> operator_content_;
const OperatorContent& GetOperatorContent();
// Operator properties calculated from dictionary and attributes.
// It contains dirty flags to allow efficient dictionary updating.
struct Properties {
......
......@@ -1250,7 +1250,6 @@ crbug.com/6606 external/wpt/mathml/presentation-markup/operators/mo-movablelimit
crbug.com/6606 external/wpt/mathml/presentation-markup/operators/mo-paint-lspace-rspace.html [ Failure ]
crbug.com/6606 external/wpt/mathml/presentation-markup/operators/operator-dictionary-001.html [ Failure ]
crbug.com/6606 external/wpt/mathml/presentation-markup/operators/operator-dictionary-002.html [ Failure ]
crbug.com/6606 external/wpt/mathml/presentation-markup/scripts/underover-parameters-2.html [ Failure ]
crbug.com/6606 external/wpt/mathml/presentation-markup/scripts/underover-parameters-3.html [ Failure ]
crbug.com/6606 external/wpt/mathml/presentation-markup/scripts/underover-parameters-4.html [ Failure ]
crbug.com/6606 external/wpt/mathml/presentation-markup/spaces/space-like-001.html [ Failure ]
......
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