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

[mathml] Implement the mpadded element

Implement the mpadded element [1]. This CL also renames LayoutNGMathMLSquareRoot to LayoutNGMathMLBlockWithAnonymousMrow, since now it is not just used by msqrt.

[1] https://mathml-refresh.github.io/mathml-core/#adjust-space-around-content-mpadded

Bug: 6606
Change-Id: I8243bb8e5fb0975a407bf12275487434283cfe4c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2288388
Commit-Queue: Rob Buis <rbuis@igalia.com>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798451}
parent 529337d9
...@@ -47,7 +47,7 @@ math[display="block"] { ...@@ -47,7 +47,7 @@ math[display="block"] {
outline: auto 1px -webkit-focus-ring-color; outline: auto 1px -webkit-focus-ring-color;
} }
maction, merror, mfrac, mphantom, mrow, mspace, mstyle, msub, msup, msubsup, munder, mover, munderover, msqrt, mroot, mmultiscripts, mprescripts, none maction, merror, mfrac, mmultiscripts, mover, mpadded, mphantom, mprescripts, mroot, mrow, msqrt, mspace, mstyle, msub, msup, msubsup, munder, munderover, none
{ {
display: math; display: math;
} }
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#include "third_party/blink/renderer/core/layout/layout_theme.h" #include "third_party/blink/renderer/core/layout/layout_theme.h"
#include "third_party/blink/renderer/core/layout/list_marker.h" #include "third_party/blink/renderer/core/layout/list_marker.h"
#include "third_party/blink/renderer/core/mathml/mathml_fraction_element.h" #include "third_party/blink/renderer/core/mathml/mathml_fraction_element.h"
#include "third_party/blink/renderer/core/mathml/mathml_padded_element.h"
#include "third_party/blink/renderer/core/mathml/mathml_space_element.h" #include "third_party/blink/renderer/core/mathml/mathml_space_element.h"
#include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h" #include "third_party/blink/renderer/core/style/computed_style_constants.h"
...@@ -748,6 +749,14 @@ void StyleAdjuster::AdjustComputedStyle(StyleResolverState& state, ...@@ -748,6 +749,14 @@ void StyleAdjuster::AdjustComputedStyle(StyleResolverState& state,
} }
if (auto* space = DynamicTo<MathMLSpaceElement>(*element)) { if (auto* space = DynamicTo<MathMLSpaceElement>(*element)) {
space->AddMathBaselineIfNeeded(style, state.CssToLengthConversionData()); space->AddMathBaselineIfNeeded(style, state.CssToLengthConversionData());
} else if (auto* padded = DynamicTo<MathMLPaddedElement>(*element)) {
padded->AddMathBaselineIfNeeded(style, state.CssToLengthConversionData());
padded->AddMathPaddedDepthIfNeeded(style,
state.CssToLengthConversionData());
padded->AddMathPaddedLSpaceIfNeeded(style,
state.CssToLengthConversionData());
padded->AddMathPaddedVOffsetIfNeeded(style,
state.CssToLengthConversionData());
} else if (auto* fraction = DynamicTo<MathMLFractionElement>(*element)) { } else if (auto* fraction = DynamicTo<MathMLFractionElement>(*element)) {
fraction->AddMathFractionBarThicknessIfNeeded( fraction->AddMathFractionBarThicknessIfNeeded(
style, state.CssToLengthConversionData()); style, state.CssToLengthConversionData());
......
...@@ -443,12 +443,14 @@ blink_core_sources("layout") { ...@@ -443,12 +443,14 @@ blink_core_sources("layout") {
"ng/list/ng_unpositioned_list_marker.h", "ng/list/ng_unpositioned_list_marker.h",
"ng/mathml/layout_ng_mathml_block.cc", "ng/mathml/layout_ng_mathml_block.cc",
"ng/mathml/layout_ng_mathml_block.h", "ng/mathml/layout_ng_mathml_block.h",
"ng/mathml/layout_ng_mathml_square_root.cc", "ng/mathml/layout_ng_mathml_block_with_anonymous_mrow.cc",
"ng/mathml/layout_ng_mathml_square_root.h", "ng/mathml/layout_ng_mathml_block_with_anonymous_mrow.h",
"ng/mathml/ng_math_fraction_layout_algorithm.cc", "ng/mathml/ng_math_fraction_layout_algorithm.cc",
"ng/mathml/ng_math_fraction_layout_algorithm.h", "ng/mathml/ng_math_fraction_layout_algorithm.h",
"ng/mathml/ng_math_layout_utils.cc", "ng/mathml/ng_math_layout_utils.cc",
"ng/mathml/ng_math_layout_utils.h", "ng/mathml/ng_math_layout_utils.h",
"ng/mathml/ng_math_padded_layout_algorithm.cc",
"ng/mathml/ng_math_padded_layout_algorithm.h",
"ng/mathml/ng_math_radical_layout_algorithm.cc", "ng/mathml/ng_math_radical_layout_algorithm.cc",
"ng/mathml/ng_math_radical_layout_algorithm.h", "ng/mathml/ng_math_radical_layout_algorithm.h",
"ng/mathml/ng_math_row_layout_algorithm.cc", "ng/mathml/ng_math_row_layout_algorithm.cc",
......
...@@ -2,17 +2,19 @@ ...@@ -2,17 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_square_root.h" #include "third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block_with_anonymous_mrow.h"
namespace blink { namespace blink {
LayoutNGMathMLSquareRoot::LayoutNGMathMLSquareRoot(Element* element) LayoutNGMathMLBlockWithAnonymousMrow::LayoutNGMathMLBlockWithAnonymousMrow(
Element* element)
: LayoutNGMathMLBlock(element) { : LayoutNGMathMLBlock(element) {
DCHECK(element); DCHECK(element);
} }
void LayoutNGMathMLSquareRoot::AddChild(LayoutObject* new_child, void LayoutNGMathMLBlockWithAnonymousMrow::AddChild(
LayoutObject* before_child) { LayoutObject* new_child,
LayoutObject* before_child) {
LayoutBlock* anonymous_mrow = To<LayoutBlock>(FirstChild()); LayoutBlock* anonymous_mrow = To<LayoutBlock>(FirstChild());
if (!anonymous_mrow) { if (!anonymous_mrow) {
scoped_refptr<ComputedStyle> new_style = scoped_refptr<ComputedStyle> new_style =
......
// Copyright 2019 The Chromium Authors. All rights reserved. // Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_LAYOUT_NG_MATHML_SQUARE_ROOT_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_LAYOUT_NG_MATHML_BLOCK_WITH_ANONYMOUS_MROW_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_LAYOUT_NG_MATHML_SQUARE_ROOT_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_LAYOUT_NG_MATHML_BLOCK_WITH_ANONYMOUS_MROW_H_
#include "third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.h" #include "third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.h"
namespace blink { namespace blink {
// FIXME: should probably be called LayoutNGMathMLBlockWithAnonymousMrow class LayoutNGMathMLBlockWithAnonymousMrow : public LayoutNGMathMLBlock {
// when there are multiple users of this class.
class LayoutNGMathMLSquareRoot : public LayoutNGMathMLBlock {
public: public:
explicit LayoutNGMathMLSquareRoot(Element*); explicit LayoutNGMathMLBlockWithAnonymousMrow(Element*);
void AddChild(LayoutObject* new_child, void AddChild(LayoutObject* new_child,
LayoutObject* before_child = nullptr) override; LayoutObject* before_child = nullptr) override;
...@@ -21,4 +19,4 @@ class LayoutNGMathMLSquareRoot : public LayoutNGMathMLBlock { ...@@ -21,4 +19,4 @@ class LayoutNGMathMLSquareRoot : public LayoutNGMathMLBlock {
} // namespace blink } // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_LAYOUT_NG_MATHML_SQUARE_ROOT_H_ #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_LAYOUT_NG_MATHML_BLOCK_WITH_ANONYMOUS_MROW_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_padded_layout_algorithm.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.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_names.h"
namespace blink {
NGMathPaddedLayoutAlgorithm::NGMathPaddedLayoutAlgorithm(
const NGLayoutAlgorithmParams& params)
: NGLayoutAlgorithm(params) {
container_builder_.SetIsNewFormattingContext(
params.space.IsNewFormattingContext());
}
LayoutUnit NGMathPaddedLayoutAlgorithm::RequestedLSpace() const {
return std::max(LayoutUnit(),
ValueForLength(Style().GetMathPaddedLSpace(), LayoutUnit()));
}
LayoutUnit NGMathPaddedLayoutAlgorithm::RequestedVOffset() const {
return ValueForLength(Style().GetMathPaddedVOffset(), LayoutUnit());
}
base::Optional<LayoutUnit> NGMathPaddedLayoutAlgorithm::RequestedAscent(
LayoutUnit content_ascent) const {
if (Style().GetMathBaseline().IsAuto())
return base::nullopt;
return std::max(LayoutUnit(),
ValueForLength(Style().GetMathBaseline(), content_ascent));
}
base::Optional<LayoutUnit> NGMathPaddedLayoutAlgorithm::RequestedDescent(
LayoutUnit content_descent) const {
if (Style().GetMathPaddedDepth().IsAuto())
return base::nullopt;
return std::max(LayoutUnit(), ValueForLength(Style().GetMathPaddedDepth(),
content_descent));
}
void NGMathPaddedLayoutAlgorithm::GatherChildren(
NGBlockNode* content,
NGBoxFragmentBuilder* container_builder) const {
for (NGLayoutInputNode child = Node().FirstChild(); child;
child = child.NextSibling()) {
NGBlockNode block_child = To<NGBlockNode>(child);
if (child.IsOutOfFlowPositioned()) {
if (container_builder) {
container_builder->AddOutOfFlowChildCandidate(
block_child, BorderScrollbarPadding().StartOffset());
}
continue;
}
if (!*content) {
*content = block_child;
continue;
}
NOTREACHED();
}
}
scoped_refptr<const NGLayoutResult> NGMathPaddedLayoutAlgorithm::Layout() {
DCHECK(!BreakToken());
NGBlockNode content = nullptr;
GatherChildren(&content, &container_builder_);
LayoutUnit content_ascent, content_descent;
NGBoxStrut content_margins;
scoped_refptr<const NGPhysicalBoxFragment> content_fragment;
if (content) {
NGConstraintSpace constraint_space = CreateConstraintSpaceForMathChild(
Node(), ChildAvailableSize(), ConstraintSpace(), content);
scoped_refptr<const NGLayoutResult> content_layout_result =
content.Layout(constraint_space);
content_fragment =
&To<NGPhysicalBoxFragment>(content_layout_result->PhysicalFragment());
content_margins =
ComputeMarginsFor(constraint_space, content.Style(), ConstraintSpace());
NGBoxFragment fragment(ConstraintSpace().GetWritingMode(),
ConstraintSpace().Direction(), *content_fragment);
content_ascent = content_margins.block_start +
fragment.Baseline().value_or(fragment.BlockSize());
content_descent =
fragment.BlockSize() + content_margins.BlockSum() - content_ascent;
}
// width/height/depth attributes can override width/ascent/descent.
LayoutUnit ascent = BorderScrollbarPadding().block_start +
RequestedAscent(content_ascent).value_or(content_ascent);
LayoutUnit descent =
RequestedDescent(content_descent).value_or(content_descent);
if (content_fragment) {
// Need to take into account border/padding, lspace and voffset.
LogicalOffset content_offset = {
BorderScrollbarPadding().inline_start + RequestedLSpace(),
(ascent - content_ascent) - RequestedVOffset()};
container_builder_.AddChild(*content_fragment, content_offset);
content.StoreMargins(ConstraintSpace(), content_margins);
}
auto total_block_size = ascent + descent + BorderScrollbarPadding().block_end;
container_builder_.SetIntrinsicBlockSize(total_block_size);
container_builder_.SetFragmentsTotalBlockSize(total_block_size);
container_builder_.SetBaseline(ascent);
NGOutOfFlowLayoutPart(Node(), ConstraintSpace(), &container_builder_).Run();
return container_builder_.ToBoxFragment();
}
MinMaxSizesResult NGMathPaddedLayoutAlgorithm::ComputeMinMaxSizes(
const MinMaxSizesInput& input) const {
if (auto result = CalculateMinMaxSizesIgnoringChildren(
Node(), BorderScrollbarPadding()))
return *result;
MinMaxSizes sizes;
bool depends_on_percentage_block_size = false;
sizes += BorderScrollbarPadding().InlineSum();
NGBlockNode content = nullptr;
GatherChildren(&content);
MinMaxSizesResult content_result =
ComputeMinAndMaxContentContribution(Style(), content, input);
NGBoxStrut content_margins = ComputeMinMaxMargins(Style(), content);
content_result.sizes += content_margins.InlineSum();
depends_on_percentage_block_size |=
content_result.depends_on_percentage_block_size;
sizes += content_result.sizes;
return {sizes, depends_on_percentage_block_size};
}
} // namespace blink
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATH_PADDED_LAYOUT_ALGORITHM_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATH_PADDED_LAYOUT_ALGORITHM_H_
#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h"
namespace blink {
class CORE_EXPORT NGMathPaddedLayoutAlgorithm
: public NGLayoutAlgorithm<NGBlockNode,
NGBoxFragmentBuilder,
NGBlockBreakToken> {
public:
explicit NGMathPaddedLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
scoped_refptr<const NGLayoutResult> Layout() final;
MinMaxSizesResult ComputeMinMaxSizes(const MinMaxSizesInput&) const final;
private:
LayoutUnit RequestedLSpace() const;
LayoutUnit RequestedVOffset() const;
base::Optional<LayoutUnit> RequestedAscent(LayoutUnit content_ascent) const;
base::Optional<LayoutUnit> RequestedDescent(LayoutUnit content_descent) const;
void GatherChildren(NGBlockNode* base, NGBoxFragmentBuilder* = nullptr) const;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATH_PADDED_LAYOUT_ALGORITHM_H_
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h" #include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.h" #include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.h" #include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.h"
#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_padded_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_radical_layout_algorithm.h" #include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_radical_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h" #include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.h" #include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_scripts_layout_algorithm.h"
...@@ -59,6 +60,7 @@ ...@@ -59,6 +60,7 @@
#include "third_party/blink/renderer/core/layout/text_autosizer.h" #include "third_party/blink/renderer/core/layout/text_autosizer.h"
#include "third_party/blink/renderer/core/mathml/mathml_element.h" #include "third_party/blink/renderer/core/mathml/mathml_element.h"
#include "third_party/blink/renderer/core/mathml/mathml_fraction_element.h" #include "third_party/blink/renderer/core/mathml/mathml_fraction_element.h"
#include "third_party/blink/renderer/core/mathml/mathml_padded_element.h"
#include "third_party/blink/renderer/core/mathml/mathml_radical_element.h" #include "third_party/blink/renderer/core/mathml/mathml_radical_element.h"
#include "third_party/blink/renderer/core/mathml/mathml_scripts_element.h" #include "third_party/blink/renderer/core/mathml/mathml_scripts_element.h"
#include "third_party/blink/renderer/core/mathml/mathml_space_element.h" #include "third_party/blink/renderer/core/mathml/mathml_space_element.h"
...@@ -124,6 +126,9 @@ NOINLINE void DetermineMathMLAlgorithmAndRun( ...@@ -124,6 +126,9 @@ NOINLINE void DetermineMathMLAlgorithmAndRun(
IsValidMathMLRadical(params.node)) { IsValidMathMLRadical(params.node)) {
CreateAlgorithmAndRun<NGMathRadicalLayoutAlgorithm>(params, callback); CreateAlgorithmAndRun<NGMathRadicalLayoutAlgorithm>(params, callback);
return; return;
} else if (IsA<MathMLPaddedElement>(element)) {
CreateAlgorithmAndRun<NGMathPaddedLayoutAlgorithm>(params, callback);
return;
} else if (IsA<MathMLScriptsElement>(element) && } else if (IsA<MathMLScriptsElement>(element) &&
IsValidMathMLScript(params.node)) { IsValidMathMLScript(params.node)) {
// TODO(rbuis): take into account movablelimits. // TODO(rbuis): take into account movablelimits.
......
...@@ -10,6 +10,8 @@ blink_core_sources("mathml") { ...@@ -10,6 +10,8 @@ blink_core_sources("mathml") {
"mathml_element.h", "mathml_element.h",
"mathml_fraction_element.cc", "mathml_fraction_element.cc",
"mathml_fraction_element.h", "mathml_fraction_element.h",
"mathml_padded_element.cc",
"mathml_padded_element.h",
"mathml_radical_element.cc", "mathml_radical_element.cc",
"mathml_radical_element.h", "mathml_radical_element.h",
"mathml_row_element.cc", "mathml_row_element.cc",
......
...@@ -14,11 +14,13 @@ ...@@ -14,11 +14,13 @@
"encoding", "encoding",
"height", "height",
"linethickness", "linethickness",
"lspace",
"mathbackground", "mathbackground",
"mathcolor", "mathcolor",
"mathsize", "mathsize",
"mathvariant", "mathvariant",
"scriptlevel", "scriptlevel",
"voffset",
"width", "width",
], ],
} }
...@@ -111,16 +111,18 @@ void MathMLElement::ParseAttribute(const AttributeModificationParams& param) { ...@@ -111,16 +111,18 @@ void MathMLElement::ParseAttribute(const AttributeModificationParams& param) {
} }
base::Optional<Length> MathMLElement::AddMathLengthToComputedStyle( base::Optional<Length> MathMLElement::AddMathLengthToComputedStyle(
ComputedStyle& style,
const CSSToLengthConversionData& conversion_data, const CSSToLengthConversionData& conversion_data,
const QualifiedName& attr_name) { const QualifiedName& attr_name,
AllowPercentages allow_percentages) {
if (!FastHasAttribute(attr_name)) if (!FastHasAttribute(attr_name))
return base::nullopt; return base::nullopt;
auto value = FastGetAttribute(attr_name); auto value = FastGetAttribute(attr_name);
const CSSPrimitiveValue* parsed_value = CSSParser::ParseLengthPercentage( const CSSPrimitiveValue* parsed_value = CSSParser::ParseLengthPercentage(
value, value,
StrictCSSParserContext(GetExecutionContext()->GetSecureContextMode())); StrictCSSParserContext(GetExecutionContext()->GetSecureContextMode()));
if (!parsed_value || parsed_value->IsCalculated()) if (!parsed_value || parsed_value->IsCalculated() ||
(parsed_value->IsPercentage() &&
(!value.EndsWith('%') || allow_percentages == AllowPercentages::kNo)))
return base::nullopt; return base::nullopt;
return parsed_value->ConvertToLength(conversion_data); return parsed_value->ConvertToLength(conversion_data);
} }
......
...@@ -37,13 +37,13 @@ class CORE_EXPORT MathMLElement : public Element { ...@@ -37,13 +37,13 @@ class CORE_EXPORT MathMLElement : public Element {
const AtomicString&, const AtomicString&,
MutableCSSPropertyValueSet*) override; MutableCSSPropertyValueSet*) override;
enum class AllowPercentages { kYes, kNo };
base::Optional<Length> AddMathLengthToComputedStyle( base::Optional<Length> AddMathLengthToComputedStyle(
ComputedStyle&,
const CSSToLengthConversionData&, const CSSToLengthConversionData&,
const QualifiedName&); const QualifiedName&,
AllowPercentages allow_percentages = AllowPercentages::kYes);
private: void ParseAttribute(const AttributeModificationParams&) override;
void ParseAttribute(const AttributeModificationParams&) final;
bool IsMathMLElement() const = bool IsMathMLElement() const =
delete; // This will catch anyone doing an unnecessary check. delete; // This will catch anyone doing an unnecessary check.
......
...@@ -15,7 +15,7 @@ void MathMLFractionElement::AddMathFractionBarThicknessIfNeeded( ...@@ -15,7 +15,7 @@ void MathMLFractionElement::AddMathFractionBarThicknessIfNeeded(
ComputedStyle& style, ComputedStyle& style,
const CSSToLengthConversionData& conversion_data) { const CSSToLengthConversionData& conversion_data) {
if (auto length_or_percentage_value = AddMathLengthToComputedStyle( if (auto length_or_percentage_value = AddMathLengthToComputedStyle(
style, conversion_data, mathml_names::kLinethicknessAttr)) conversion_data, mathml_names::kLinethicknessAttr))
style.SetMathFractionBarThickness(std::move(*length_or_percentage_value)); style.SetMathFractionBarThickness(std::move(*length_or_percentage_value));
} }
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/mathml/mathml_padded_element.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block_with_anonymous_mrow.h"
namespace blink {
MathMLPaddedElement::MathMLPaddedElement(Document& document)
: MathMLRowElement(mathml_names::kMpaddedTag, document) {}
void MathMLPaddedElement::AddMathBaselineIfNeeded(
ComputedStyle& style,
const CSSToLengthConversionData& conversion_data) {
if (auto length_or_percentage_value = AddMathLengthToComputedStyle(
conversion_data, mathml_names::kHeightAttr, AllowPercentages::kNo))
style.SetMathBaseline(std::move(*length_or_percentage_value));
}
void MathMLPaddedElement::AddMathPaddedDepthIfNeeded(
ComputedStyle& style,
const CSSToLengthConversionData& conversion_data) {
if (auto length_or_percentage_value = AddMathLengthToComputedStyle(
conversion_data, mathml_names::kDepthAttr, AllowPercentages::kNo))
style.SetMathPaddedDepth(std::move(*length_or_percentage_value));
}
void MathMLPaddedElement::AddMathPaddedLSpaceIfNeeded(
ComputedStyle& style,
const CSSToLengthConversionData& conversion_data) {
if (auto length_or_percentage_value = AddMathLengthToComputedStyle(
conversion_data, mathml_names::kLspaceAttr))
style.SetMathPaddedLSpace(std::move(*length_or_percentage_value));
}
void MathMLPaddedElement::AddMathPaddedVOffsetIfNeeded(
ComputedStyle& style,
const CSSToLengthConversionData& conversion_data) {
if (auto length_or_percentage_value = AddMathLengthToComputedStyle(
conversion_data, mathml_names::kVoffsetAttr))
style.SetMathPaddedVOffset(std::move(*length_or_percentage_value));
}
void MathMLPaddedElement::ParseAttribute(
const AttributeModificationParams& param) {
if (param.name == mathml_names::kLspaceAttr ||
param.name == mathml_names::kVoffsetAttr) {
SetNeedsStyleRecalc(
kLocalStyleChange,
StyleChangeReasonForTracing::Create(style_change_reason::kAttribute));
if (GetLayoutObject() && GetLayoutObject()->IsMathML()) {
GetLayoutObject()
->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAttributeChanged);
}
}
MathMLRowElement::ParseAttribute(param);
}
bool MathMLPaddedElement::IsPresentationAttribute(
const QualifiedName& name) const {
if (name == mathml_names::kWidthAttr)
return true;
return MathMLElement::IsPresentationAttribute(name);
}
void MathMLPaddedElement::CollectStyleForPresentationAttribute(
const QualifiedName& name,
const AtomicString& value,
MutableCSSPropertyValueSet* style) {
if (name == mathml_names::kWidthAttr) {
if (!value.EndsWith('%')) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kWidth,
value);
}
} else {
MathMLElement::CollectStyleForPresentationAttribute(name, value, style);
}
}
LayoutObject* MathMLPaddedElement::CreateLayoutObject(
const ComputedStyle& style,
LegacyLayout legacy) {
// TODO(rbuis): legacy check should be removed.
if (!RuntimeEnabledFeatures::MathMLCoreEnabled() ||
legacy == LegacyLayout::kForce || !style.IsDisplayMathType())
return MathMLElement::CreateLayoutObject(style, legacy);
return new LayoutNGMathMLBlockWithAnonymousMrow(this);
}
} // namespace blink
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_MATHML_MATHML_PADDED_ELEMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_MATHML_MATHML_PADDED_ELEMENT_H_
#include "third_party/blink/renderer/core/mathml/mathml_row_element.h"
namespace blink {
class ComputedStyle;
class Document;
class CORE_EXPORT MathMLPaddedElement final : public MathMLRowElement {
public:
explicit MathMLPaddedElement(Document&);
void AddMathBaselineIfNeeded(ComputedStyle&,
const CSSToLengthConversionData&);
void AddMathPaddedDepthIfNeeded(ComputedStyle&,
const CSSToLengthConversionData&);
void AddMathPaddedLSpaceIfNeeded(ComputedStyle&,
const CSSToLengthConversionData&);
void AddMathPaddedVOffsetIfNeeded(ComputedStyle&,
const CSSToLengthConversionData&);
private:
void ParseAttribute(const AttributeModificationParams&) final;
bool IsPresentationAttribute(const QualifiedName&) const final;
void CollectStyleForPresentationAttribute(const QualifiedName&,
const AtomicString&,
MutableCSSPropertyValueSet*) final;
LayoutObject* CreateLayoutObject(const ComputedStyle&,
LegacyLayout legacy) final;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_MATHML_MATHML_PADDED_ELEMENT_H_
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/mathml/mathml_radical_element.h" #include "third_party/blink/renderer/core/mathml/mathml_radical_element.h"
#include "third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_square_root.h" #include "third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block_with_anonymous_mrow.h"
namespace blink { namespace blink {
...@@ -24,7 +24,7 @@ LayoutObject* MathMLRadicalElement::CreateLayoutObject( ...@@ -24,7 +24,7 @@ LayoutObject* MathMLRadicalElement::CreateLayoutObject(
legacy == LegacyLayout::kForce || !style.IsDisplayMathType()) legacy == LegacyLayout::kForce || !style.IsDisplayMathType())
return MathMLElement::CreateLayoutObject(style, legacy); return MathMLElement::CreateLayoutObject(style, legacy);
if (HasTagName(mathml_names::kMsqrtTag)) if (HasTagName(mathml_names::kMsqrtTag))
return new LayoutNGMathMLSquareRoot(this); return new LayoutNGMathMLBlockWithAnonymousMrow(this);
return new LayoutNGMathMLBlock(this); return new LayoutNGMathMLBlock(this);
} }
......
...@@ -15,7 +15,7 @@ void MathMLSpaceElement::AddMathBaselineIfNeeded( ...@@ -15,7 +15,7 @@ void MathMLSpaceElement::AddMathBaselineIfNeeded(
ComputedStyle& style, ComputedStyle& style,
const CSSToLengthConversionData& conversion_data) { const CSSToLengthConversionData& conversion_data) {
if (auto length_or_percentage_value = AddMathLengthToComputedStyle( if (auto length_or_percentage_value = AddMathLengthToComputedStyle(
style, conversion_data, mathml_names::kHeightAttr)) conversion_data, mathml_names::kHeightAttr))
style.SetMathBaseline(std::move(*length_or_percentage_value)); style.SetMathBaseline(std::move(*length_or_percentage_value));
} }
......
...@@ -79,6 +79,10 @@ ...@@ -79,6 +79,10 @@
name: "mo", name: "mo",
interfaceName: "MathMLElement", interfaceName: "MathMLElement",
}, },
{
name: "mpadded",
interfaceName: "MathMLPaddedElement",
},
{ {
name: "mphantom", name: "mphantom",
interfaceName: "MathMLRowElement", interfaceName: "MathMLRowElement",
......
...@@ -1000,6 +1000,33 @@ ...@@ -1000,6 +1000,33 @@
field_group: "*", field_group: "*",
getter: "GetMathFractionBarThickness", getter: "GetMathFractionBarThickness",
}, },
{
name: "MathPaddedLSpace",
field_template: "external",
default_value: "Length()",
include_paths: ["third_party/blink/renderer/platform/geometry/length.h"],
type_name: "Length",
field_group: "*",
getter: "GetMathPaddedLSpace",
},
{
name: "MathPaddedVOffset",
field_template: "external",
default_value: "Length()",
include_paths: ["third_party/blink/renderer/platform/geometry/length.h"],
type_name: "Length",
field_group: "*",
getter: "GetMathPaddedVOffset",
},
{
name: "MathPaddedDepth",
field_template: "external",
default_value: "Length()",
include_paths: ["third_party/blink/renderer/platform/geometry/length.h"],
type_name: "Length",
field_group: "*",
getter: "GetMathPaddedDepth",
},
{ {
name: "MathScriptLevel", name: "MathScriptLevel",
inherited: true, inherited: true,
......
This is a testharness.js-based test.
PASS mpadded (no attributes)
FAIL Different widths assert_approx_equals: width 0 expected 25 +/- 1 but got 0
FAIL Different heights assert_approx_equals: height0 expected 25 +/- 1 but got 0
FAIL Different depths assert_approx_equals: depth0 expected 25 +/- 1 but got 0
FAIL Various combinations of height, depth and width. assert_approx_equals: width0 expected 25 +/- 1 but got 0
PASS Preferred width
PASS dynamic attributes (remove)
FAIL dynamic attributes (attach) assert_approx_equals: expected 50 +/- 1 but got 0
FAIL dynamic attributes (modify) assert_approx_equals: expected 50 +/- 1 but got 0
Harness: the test ran to completion.
...@@ -48,8 +48,8 @@ ...@@ -48,8 +48,8 @@
test(function() { test(function() {
var mpadded = getBox("percentages"); var mpadded = getBox("percentages");
assert_equals(mpadded.width, contentWidth / 2, "width"); assert_equals(mpadded.width, contentWidth, "width");
assert_approx_equals(getBox("baseline").bottom - mpadded.top, contentHeight / 3, epsilon, "height"); assert_approx_equals(getBox("baseline").bottom - mpadded.top, contentHeight, epsilon, "height");
assert_approx_equals(mpadded.bottom - getBox("baseline").bottom, contentDepth, epsilon, "depth"); assert_approx_equals(mpadded.bottom - getBox("baseline").bottom, contentDepth, epsilon, "depth");
}, "Percentage calculation for width, height and depth"); }, "Percentage calculation for width, height and depth");
...@@ -133,7 +133,7 @@ div.shrink-wrap { ...@@ -133,7 +133,7 @@ div.shrink-wrap {
<mpadded id="height0" height="25px"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> <mpadded id="height0" height="25px"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded>
<mpadded id="height1" height="50px"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> <mpadded id="height1" height="50px"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded>
<mpadded id="height2" height="75px"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> <mpadded id="height2" height="75px"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded>
<mpadded id="percentages" width="50%" height="33%" depth="100%"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded> <mpadded id="percentages" width="50%" height="33%" depth="10%"><mspace width="100px" depth="125px" height="150px" style="background: black; opacity: .5"/></mpadded>
</math> </math>
</p> </p>
<p> <p>
......
This is a testharness.js-based test.
PASS lspace/voffset shifts don't affect mpadded preferred width
PASS lspace/voffset shifts don't affect mpadded size
FAIL content is shifted by the specified lspace/voffset assert_approx_equals: positive lspace expected 5 +/- 1 but got 0
FAIL content is shifted by the specified lspace/voffset (RTL) assert_approx_equals: positive lspace expected -5 +/- 1 but got 0
FAIL dynamic changes of lspace/voffset assert_approx_equals: attach lspace expected 5 +/- 1 but got 0
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL mpadded with no attributes assert_approx_equals: content height expected 150 +/- 1 but got -4
FAIL Different widths assert_approx_equals: width 0 expected 25 +/- 1 but got 100
FAIL Different heights assert_approx_equals: height0 expected 25 +/- 1 but got -4
FAIL Percentage calculation for width, height and depth assert_equals: width expected 50 but got 100
FAIL Different depths assert_approx_equals: depth0 expected 25 +/- 1 but got 125
FAIL Various combinations of height, depth and width. assert_approx_equals: width0 expected 25 +/- 1 but got 100
PASS Preferred width
PASS dynamic attributes (remove)
FAIL dynamic attributes (attach) assert_approx_equals: expected 50 +/- 1 but got 100
FAIL dynamic attributes (modify) assert_approx_equals: expected 50 +/- 1 but got 100
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL mpadded with no attributes assert_approx_equals: content height expected 150 +/- 1 but got -5
FAIL Different widths assert_approx_equals: width 0 expected 25 +/- 1 but got 100
FAIL Different heights assert_approx_equals: height0 expected 25 +/- 1 but got -5
FAIL Percentage calculation for width, height and depth assert_equals: width expected 50 but got 100
FAIL Different depths assert_approx_equals: depth0 expected 25 +/- 1 but got 125
FAIL Various combinations of height, depth and width. assert_approx_equals: width0 expected 25 +/- 1 but got 100
PASS Preferred width
PASS dynamic attributes (remove)
FAIL dynamic attributes (attach) assert_approx_equals: expected 50 +/- 1 but got 100
FAIL dynamic attributes (modify) assert_approx_equals: expected 50 +/- 1 but got 100
Harness: the test ran to completion.
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