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

[mathml] Extend the MathML painter class

Extend the MathML painter class to be more generic and offer
an API through NGMathMLPaintInfo to paint MathML fragments
besides fractions, i.e. the upcoming operators and radicals.

Bug: 6606
Change-Id: I8b143fc02965fa2d757b19d026d99c693dc33f5f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2190676
Commit-Queue: Rob Buis <rbuis@igalia.com>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#774547}
parent 6f062cd7
...@@ -446,6 +446,7 @@ blink_core_sources("layout") { ...@@ -446,6 +446,7 @@ blink_core_sources("layout") {
"ng/mathml/ng_math_space_layout_algorithm.h", "ng/mathml/ng_math_space_layout_algorithm.h",
"ng/mathml/ng_math_under_over_layout_algorithm.cc", "ng/mathml/ng_math_under_over_layout_algorithm.cc",
"ng/mathml/ng_math_under_over_layout_algorithm.h", "ng/mathml/ng_math_under_over_layout_algorithm.h",
"ng/mathml/ng_mathml_paint_info.h",
"ng/ng_absolute_utils.cc", "ng/ng_absolute_utils.cc",
"ng/ng_absolute_utils.h", "ng/ng_absolute_utils.h",
"ng/ng_block_break_token.cc", "ng/ng_block_break_token.cc",
......
...@@ -52,7 +52,7 @@ NGPhysicalTextFragment::NGPhysicalTextFragment( ...@@ -52,7 +52,7 @@ NGPhysicalTextFragment::NGPhysicalTextFragment(
DCHECK_LE(text_offset_.end, source.EndOffset()); DCHECK_LE(text_offset_.end, source.EndOffset());
DCHECK(shape_result_ || IsFlowControl()) << *this; DCHECK(shape_result_ || IsFlowControl()) << *this;
base_or_resolved_direction_ = source.base_or_resolved_direction_; base_or_resolved_direction_ = source.base_or_resolved_direction_;
ink_overflow_computed_ = false; ink_overflow_computed_or_mathml_paint_info_ = false;
} }
NGPhysicalTextFragment::NGPhysicalTextFragment(NGTextFragmentBuilder* builder) NGPhysicalTextFragment::NGPhysicalTextFragment(NGTextFragmentBuilder* builder)
...@@ -65,7 +65,7 @@ NGPhysicalTextFragment::NGPhysicalTextFragment(NGTextFragmentBuilder* builder) ...@@ -65,7 +65,7 @@ NGPhysicalTextFragment::NGPhysicalTextFragment(NGTextFragmentBuilder* builder)
DCHECK(shape_result_ || IsFlowControl()) << *this; DCHECK(shape_result_ || IsFlowControl()) << *this;
base_or_resolved_direction_ = base_or_resolved_direction_ =
static_cast<unsigned>(builder->ResolvedDirection()); static_cast<unsigned>(builder->ResolvedDirection());
ink_overflow_computed_ = false; ink_overflow_computed_or_mathml_paint_info_ = false;
} }
bool NGPhysicalTextFragment::IsGeneratedText() const { bool NGPhysicalTextFragment::IsGeneratedText() const {
...@@ -187,7 +187,7 @@ PhysicalRect NGFragmentItem::LocalRect(StringView text, ...@@ -187,7 +187,7 @@ PhysicalRect NGFragmentItem::LocalRect(StringView text,
} }
PhysicalRect NGPhysicalTextFragment::SelfInkOverflow() const { PhysicalRect NGPhysicalTextFragment::SelfInkOverflow() const {
if (!ink_overflow_computed_) if (!ink_overflow_computed_or_mathml_paint_info_)
ComputeSelfInkOverflow(); ComputeSelfInkOverflow();
if (ink_overflow_) if (ink_overflow_)
return ink_overflow_->self_ink_overflow; return ink_overflow_->self_ink_overflow;
...@@ -195,7 +195,7 @@ PhysicalRect NGPhysicalTextFragment::SelfInkOverflow() const { ...@@ -195,7 +195,7 @@ PhysicalRect NGPhysicalTextFragment::SelfInkOverflow() const {
} }
void NGPhysicalTextFragment::ComputeSelfInkOverflow() const { void NGPhysicalTextFragment::ComputeSelfInkOverflow() const {
ink_overflow_computed_ = true; ink_overflow_computed_or_mathml_paint_info_ = true;
if (UNLIKELY(!shape_result_)) { if (UNLIKELY(!shape_result_)) {
ink_overflow_ = nullptr; ink_overflow_ = nullptr;
......
// 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_MATHML_PAINT_INFO_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATHML_PAINT_INFO_H_
#include <unicode/uchar.h>
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
namespace blink {
class ShapeResultView;
struct CORE_EXPORT NGMathMLPaintInfo {
USING_FAST_MALLOC(NGMathMLPaintInfo);
public:
scoped_refptr<const ShapeResultView> operator_shape_result_view;
LayoutUnit operator_inline_size;
LayoutUnit operator_ascent;
LayoutUnit operator_descent;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATHML_PAINT_INFO_H_
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h" #include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_fragment_geometry.h" #include "third_party/blink/renderer/core/layout/ng/geometry/ng_fragment_geometry.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h"
#include "third_party/blink/renderer/core/layout/ng/mathml/ng_mathml_paint_info.h"
#include "third_party/blink/renderer/core/layout/ng/ng_break_token.h" #include "third_party/blink/renderer/core/layout/ng/ng_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h" #include "third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h" #include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
...@@ -254,6 +255,22 @@ class CORE_EXPORT NGBoxFragmentBuilder final ...@@ -254,6 +255,22 @@ class CORE_EXPORT NGBoxFragmentBuilder final
} }
void SetIsMathMLFraction() { is_math_fraction_ = true; } void SetIsMathMLFraction() { is_math_fraction_ = true; }
void SetMathMLPaintInfo(
UChar operator_character,
scoped_refptr<const ShapeResultView> operator_shape_result_view,
LayoutUnit operator_inline_size,
LayoutUnit operator_ascent,
LayoutUnit operator_descent) {
if (!mathml_paint_info_)
mathml_paint_info_ = std::make_unique<NGMathMLPaintInfo>();
mathml_paint_info_->operator_shape_result_view =
std::move(operator_shape_result_view);
mathml_paint_info_->operator_inline_size = operator_inline_size;
mathml_paint_info_->operator_ascent = operator_ascent;
mathml_paint_info_->operator_descent = operator_descent;
}
bool DidBreak() const { return did_break_; } bool DidBreak() const { return did_break_; }
...@@ -368,6 +385,8 @@ class CORE_EXPORT NGBoxFragmentBuilder final ...@@ -368,6 +385,8 @@ class CORE_EXPORT NGBoxFragmentBuilder final
scoped_refptr<SerializedScriptValue> custom_layout_data_; scoped_refptr<SerializedScriptValue> custom_layout_data_;
base::Optional<int> lines_until_clamp_; base::Optional<int> lines_until_clamp_;
std::unique_ptr<NGMathMLPaintInfo> mathml_paint_info_;
friend class NGPhysicalBoxFragment; friend class NGPhysicalBoxFragment;
friend class NGLayoutResult; friend class NGLayoutResult;
}; };
......
...@@ -52,10 +52,12 @@ scoped_refptr<const NGPhysicalBoxFragment> NGPhysicalBoxFragment::Create( ...@@ -52,10 +52,12 @@ scoped_refptr<const NGPhysicalBoxFragment> NGPhysicalBoxFragment::Create(
const NGPhysicalBoxStrut padding = const NGPhysicalBoxStrut padding =
builder->initial_fragment_geometry_->padding.ConvertToPhysical( builder->initial_fragment_geometry_->padding.ConvertToPhysical(
builder->GetWritingMode(), builder->Direction()); builder->GetWritingMode(), builder->Direction());
auto& mathml_paint_info = builder->mathml_paint_info_;
size_t byte_size = sizeof(NGPhysicalBoxFragment) + size_t byte_size = sizeof(NGPhysicalBoxFragment) +
sizeof(NGLink) * builder->children_.size() + sizeof(NGLink) * builder->children_.size() +
(borders.IsZero() ? 0 : sizeof(borders)) + (borders.IsZero() ? 0 : sizeof(borders)) +
(padding.IsZero() ? 0 : sizeof(padding)); (padding.IsZero() ? 0 : sizeof(padding)) +
(mathml_paint_info ? sizeof(NGMathMLPaintInfo*) : 0);
if (const NGFragmentItemsBuilder* items_builder = builder->ItemsBuilder()) { if (const NGFragmentItemsBuilder* items_builder = builder->ItemsBuilder()) {
// Omit |NGFragmentItems| if there were no items; e.g., display-lock. // Omit |NGFragmentItems| if there were no items; e.g., display-lock.
if (items_builder->Size()) if (items_builder->Size())
...@@ -68,8 +70,9 @@ scoped_refptr<const NGPhysicalBoxFragment> NGPhysicalBoxFragment::Create( ...@@ -68,8 +70,9 @@ scoped_refptr<const NGPhysicalBoxFragment> NGPhysicalBoxFragment::Create(
// we pass the buffer as a constructor argument. // we pass the buffer as a constructor argument.
void* data = ::WTF::Partitions::FastMalloc( void* data = ::WTF::Partitions::FastMalloc(
byte_size, ::WTF::GetStringWithTypeName<NGPhysicalBoxFragment>()); byte_size, ::WTF::GetStringWithTypeName<NGPhysicalBoxFragment>());
new (data) NGPhysicalBoxFragment(PassKey(), builder, borders, padding, new (data)
block_or_line_writing_mode); NGPhysicalBoxFragment(PassKey(), builder, borders, padding,
mathml_paint_info, block_or_line_writing_mode);
return base::AdoptRef(static_cast<NGPhysicalBoxFragment*>(data)); return base::AdoptRef(static_cast<NGPhysicalBoxFragment*>(data));
} }
...@@ -78,6 +81,7 @@ NGPhysicalBoxFragment::NGPhysicalBoxFragment( ...@@ -78,6 +81,7 @@ NGPhysicalBoxFragment::NGPhysicalBoxFragment(
NGBoxFragmentBuilder* builder, NGBoxFragmentBuilder* builder,
const NGPhysicalBoxStrut& borders, const NGPhysicalBoxStrut& borders,
const NGPhysicalBoxStrut& padding, const NGPhysicalBoxStrut& padding,
std::unique_ptr<NGMathMLPaintInfo>& mathml_paint_info,
WritingMode block_or_line_writing_mode) WritingMode block_or_line_writing_mode)
: NGPhysicalContainerFragment(builder, : NGPhysicalContainerFragment(builder,
block_or_line_writing_mode, block_or_line_writing_mode,
...@@ -106,6 +110,13 @@ NGPhysicalBoxFragment::NGPhysicalBoxFragment( ...@@ -106,6 +110,13 @@ NGPhysicalBoxFragment::NGPhysicalBoxFragment(
has_padding_ = !padding.IsZero(); has_padding_ = !padding.IsZero();
if (has_padding_) if (has_padding_)
*const_cast<NGPhysicalBoxStrut*>(ComputePaddingAddress()) = padding; *const_cast<NGPhysicalBoxStrut*>(ComputePaddingAddress()) = padding;
ink_overflow_computed_or_mathml_paint_info_ = !!mathml_paint_info;
if (ink_overflow_computed_or_mathml_paint_info_) {
memset(ComputeMathMLPaintInfoAddress(), 0, sizeof(NGMathMLPaintInfo));
new (static_cast<void*>(ComputeMathMLPaintInfoAddress()))
NGMathMLPaintInfo(*mathml_paint_info);
}
is_first_for_node_ = builder->is_first_for_node_; is_first_for_node_ = builder->is_first_for_node_;
is_fieldset_container_ = builder->is_fieldset_container_; is_fieldset_container_ = builder->is_fieldset_container_;
is_legacy_layout_root_ = builder->is_legacy_layout_root_; is_legacy_layout_root_ = builder->is_legacy_layout_root_;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h" #include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h"
#include "third_party/blink/renderer/core/layout/ng/mathml/ng_mathml_paint_info.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h"
#include "third_party/blink/renderer/platform/graphics/scroll_types.h" #include "third_party/blink/renderer/platform/graphics/scroll_types.h"
#include "third_party/blink/renderer/platform/wtf/casting.h" #include "third_party/blink/renderer/platform/wtf/casting.h"
...@@ -29,6 +30,7 @@ class CORE_EXPORT NGPhysicalBoxFragment final ...@@ -29,6 +30,7 @@ class CORE_EXPORT NGPhysicalBoxFragment final
NGBoxFragmentBuilder* builder, NGBoxFragmentBuilder* builder,
const NGPhysicalBoxStrut& borders, const NGPhysicalBoxStrut& borders,
const NGPhysicalBoxStrut& padding, const NGPhysicalBoxStrut& padding,
std::unique_ptr<NGMathMLPaintInfo>& mathml_paint_info,
WritingMode block_or_line_writing_mode); WritingMode block_or_line_writing_mode);
scoped_refptr<const NGLayoutResult> CloneAsHiddenForPaint() const; scoped_refptr<const NGLayoutResult> CloneAsHiddenForPaint() const;
...@@ -36,6 +38,8 @@ class CORE_EXPORT NGPhysicalBoxFragment final ...@@ -36,6 +38,8 @@ class CORE_EXPORT NGPhysicalBoxFragment final
~NGPhysicalBoxFragment() { ~NGPhysicalBoxFragment() {
if (has_fragment_items_) if (has_fragment_items_)
ComputeItemsAddress()->~NGFragmentItems(); ComputeItemsAddress()->~NGFragmentItems();
if (ink_overflow_computed_or_mathml_paint_info_)
ComputeMathMLPaintInfoAddress()->~NGMathMLPaintInfo();
for (const NGLink& child : Children()) for (const NGLink& child : Children())
child.fragment->Release(); child.fragment->Release();
} }
...@@ -152,15 +156,21 @@ class CORE_EXPORT NGPhysicalBoxFragment final ...@@ -152,15 +156,21 @@ class CORE_EXPORT NGPhysicalBoxFragment final
bool check_same_block_size) const; bool check_same_block_size) const;
#endif #endif
bool HasExtraMathMLPainting() const {
return IsMathMLFraction() || ink_overflow_computed_or_mathml_paint_info_;
}
private: private:
const NGFragmentItems* ComputeItemsAddress() const { const NGFragmentItems* ComputeItemsAddress() const {
DCHECK(has_fragment_items_ || has_borders_ || has_padding_); DCHECK(has_fragment_items_ || has_borders_ || has_padding_ ||
ink_overflow_computed_or_mathml_paint_info_);
const NGLink* children_end = children_ + Children().size(); const NGLink* children_end = children_ + Children().size();
return reinterpret_cast<const NGFragmentItems*>(children_end); return reinterpret_cast<const NGFragmentItems*>(children_end);
} }
const NGPhysicalBoxStrut* ComputeBordersAddress() const { const NGPhysicalBoxStrut* ComputeBordersAddress() const {
DCHECK(has_borders_ || has_padding_); DCHECK(has_borders_ || has_padding_ ||
ink_overflow_computed_or_mathml_paint_info_);
const NGFragmentItems* items = ComputeItemsAddress(); const NGFragmentItems* items = ComputeItemsAddress();
if (!has_fragment_items_) if (!has_fragment_items_)
return reinterpret_cast<const NGPhysicalBoxStrut*>(items); return reinterpret_cast<const NGPhysicalBoxStrut*>(items);
...@@ -169,11 +179,19 @@ class CORE_EXPORT NGPhysicalBoxFragment final ...@@ -169,11 +179,19 @@ class CORE_EXPORT NGPhysicalBoxFragment final
} }
const NGPhysicalBoxStrut* ComputePaddingAddress() const { const NGPhysicalBoxStrut* ComputePaddingAddress() const {
DCHECK(has_padding_); DCHECK(has_padding_ || ink_overflow_computed_or_mathml_paint_info_);
const NGPhysicalBoxStrut* address = ComputeBordersAddress(); const NGPhysicalBoxStrut* address = ComputeBordersAddress();
return has_borders_ ? address + 1 : address; return has_borders_ ? address + 1 : address;
} }
NGMathMLPaintInfo* ComputeMathMLPaintInfoAddress() const {
DCHECK(ink_overflow_computed_or_mathml_paint_info_);
NGPhysicalBoxStrut* address =
const_cast<NGPhysicalBoxStrut*>(ComputePaddingAddress());
return has_padding_ ? reinterpret_cast<NGMathMLPaintInfo*>(address + 1)
: reinterpret_cast<NGMathMLPaintInfo*>(address);
}
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
void CheckIntegrity() const; void CheckIntegrity() const;
#endif #endif
......
...@@ -430,7 +430,7 @@ class CORE_EXPORT NGPhysicalFragment ...@@ -430,7 +430,7 @@ class CORE_EXPORT NGPhysicalFragment
// The following bitfields are only to be used by NGPhysicalTextFragment // The following bitfields are only to be used by NGPhysicalTextFragment
// (it's defined here to save memory, since that class has no bitfields). // (it's defined here to save memory, since that class has no bitfields).
mutable unsigned ink_overflow_computed_ : 1; mutable unsigned ink_overflow_computed_or_mathml_paint_info_ : 1;
// Note: We've used 32-bit bit field. If you need more bits, please think to // Note: We've used 32-bit bit field. If you need more bits, please think to
// share bit fields, or put them before layout_object_ to fill the gap after // share bit fields, or put them before layout_object_ to fill the gap after
......
...@@ -505,8 +505,8 @@ void NGBoxFragmentPainter::PaintObject( ...@@ -505,8 +505,8 @@ void NGBoxFragmentPainter::PaintObject(
NGFragmentPainter(box_fragment_, GetDisplayItemClient()) NGFragmentPainter(box_fragment_, GetDisplayItemClient())
.AddURLRectIfNeeded(paint_info, paint_offset); .AddURLRectIfNeeded(paint_info, paint_offset);
} }
if (is_visible && box_fragment_.IsMathMLFraction()) if (is_visible && box_fragment_.HasExtraMathMLPainting())
NGMathMLPainter(box_fragment_).PaintFractionBar(paint_info, paint_offset); NGMathMLPainter(box_fragment_).Paint(paint_info, paint_offset);
} }
if (paint_phase != PaintPhase::kSelfOutlineOnly && if (paint_phase != PaintPhase::kSelfOutlineOnly &&
......
...@@ -55,4 +55,15 @@ void NGMathMLPainter::PaintFractionBar(const PaintInfo& info, ...@@ -55,4 +55,15 @@ void NGMathMLPainter::PaintFractionBar(const PaintInfo& info,
} }
} }
void NGMathMLPainter::Paint(const PaintInfo& info,
PhysicalOffset paint_offset) {
// Fraction
if (box_fragment_.IsMathMLFraction()) {
PaintFractionBar(info, paint_offset);
return;
}
// TODO(rbuis): paint operator and radicals.
}
} // namespace blink } // namespace blink
...@@ -20,6 +20,7 @@ class NGMathMLPainter { ...@@ -20,6 +20,7 @@ class NGMathMLPainter {
public: public:
explicit NGMathMLPainter(const NGPhysicalBoxFragment& box_fragment) explicit NGMathMLPainter(const NGPhysicalBoxFragment& box_fragment)
: box_fragment_(box_fragment) {} : box_fragment_(box_fragment) {}
void Paint(const PaintInfo&, PhysicalOffset);
void PaintFractionBar(const PaintInfo&, PhysicalOffset); void PaintFractionBar(const PaintInfo&, PhysicalOffset);
private: private:
......
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