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") {
"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.h",
"ng/mathml/ng_mathml_paint_info.h",
"ng/ng_absolute_utils.cc",
"ng/ng_absolute_utils.h",
"ng/ng_block_break_token.cc",
......
......@@ -52,7 +52,7 @@ NGPhysicalTextFragment::NGPhysicalTextFragment(
DCHECK_LE(text_offset_.end, source.EndOffset());
DCHECK(shape_result_ || IsFlowControl()) << *this;
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)
......@@ -65,7 +65,7 @@ NGPhysicalTextFragment::NGPhysicalTextFragment(NGTextFragmentBuilder* builder)
DCHECK(shape_result_ || IsFlowControl()) << *this;
base_or_resolved_direction_ =
static_cast<unsigned>(builder->ResolvedDirection());
ink_overflow_computed_ = false;
ink_overflow_computed_or_mathml_paint_info_ = false;
}
bool NGPhysicalTextFragment::IsGeneratedText() const {
......@@ -187,7 +187,7 @@ PhysicalRect NGFragmentItem::LocalRect(StringView text,
}
PhysicalRect NGPhysicalTextFragment::SelfInkOverflow() const {
if (!ink_overflow_computed_)
if (!ink_overflow_computed_or_mathml_paint_info_)
ComputeSelfInkOverflow();
if (ink_overflow_)
return ink_overflow_->self_ink_overflow;
......@@ -195,7 +195,7 @@ PhysicalRect NGPhysicalTextFragment::SelfInkOverflow() const {
}
void NGPhysicalTextFragment::ComputeSelfInkOverflow() const {
ink_overflow_computed_ = true;
ink_overflow_computed_or_mathml_paint_info_ = true;
if (UNLIKELY(!shape_result_)) {
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 @@
#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/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_container_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
......@@ -254,6 +255,22 @@ class CORE_EXPORT NGBoxFragmentBuilder final
}
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_; }
......@@ -368,6 +385,8 @@ class CORE_EXPORT NGBoxFragmentBuilder final
scoped_refptr<SerializedScriptValue> custom_layout_data_;
base::Optional<int> lines_until_clamp_;
std::unique_ptr<NGMathMLPaintInfo> mathml_paint_info_;
friend class NGPhysicalBoxFragment;
friend class NGLayoutResult;
};
......
......@@ -52,10 +52,12 @@ scoped_refptr<const NGPhysicalBoxFragment> NGPhysicalBoxFragment::Create(
const NGPhysicalBoxStrut padding =
builder->initial_fragment_geometry_->padding.ConvertToPhysical(
builder->GetWritingMode(), builder->Direction());
auto& mathml_paint_info = builder->mathml_paint_info_;
size_t byte_size = sizeof(NGPhysicalBoxFragment) +
sizeof(NGLink) * builder->children_.size() +
(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()) {
// Omit |NGFragmentItems| if there were no items; e.g., display-lock.
if (items_builder->Size())
......@@ -68,8 +70,9 @@ scoped_refptr<const NGPhysicalBoxFragment> NGPhysicalBoxFragment::Create(
// we pass the buffer as a constructor argument.
void* data = ::WTF::Partitions::FastMalloc(
byte_size, ::WTF::GetStringWithTypeName<NGPhysicalBoxFragment>());
new (data) NGPhysicalBoxFragment(PassKey(), builder, borders, padding,
block_or_line_writing_mode);
new (data)
NGPhysicalBoxFragment(PassKey(), builder, borders, padding,
mathml_paint_info, block_or_line_writing_mode);
return base::AdoptRef(static_cast<NGPhysicalBoxFragment*>(data));
}
......@@ -78,6 +81,7 @@ NGPhysicalBoxFragment::NGPhysicalBoxFragment(
NGBoxFragmentBuilder* builder,
const NGPhysicalBoxStrut& borders,
const NGPhysicalBoxStrut& padding,
std::unique_ptr<NGMathMLPaintInfo>& mathml_paint_info,
WritingMode block_or_line_writing_mode)
: NGPhysicalContainerFragment(builder,
block_or_line_writing_mode,
......@@ -106,6 +110,13 @@ NGPhysicalBoxFragment::NGPhysicalBoxFragment(
has_padding_ = !padding.IsZero();
if (has_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_fieldset_container_ = builder->is_fieldset_container_;
is_legacy_layout_root_ = builder->is_legacy_layout_root_;
......
......@@ -8,6 +8,7 @@
#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/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/platform/graphics/scroll_types.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
......@@ -29,6 +30,7 @@ class CORE_EXPORT NGPhysicalBoxFragment final
NGBoxFragmentBuilder* builder,
const NGPhysicalBoxStrut& borders,
const NGPhysicalBoxStrut& padding,
std::unique_ptr<NGMathMLPaintInfo>& mathml_paint_info,
WritingMode block_or_line_writing_mode);
scoped_refptr<const NGLayoutResult> CloneAsHiddenForPaint() const;
......@@ -36,6 +38,8 @@ class CORE_EXPORT NGPhysicalBoxFragment final
~NGPhysicalBoxFragment() {
if (has_fragment_items_)
ComputeItemsAddress()->~NGFragmentItems();
if (ink_overflow_computed_or_mathml_paint_info_)
ComputeMathMLPaintInfoAddress()->~NGMathMLPaintInfo();
for (const NGLink& child : Children())
child.fragment->Release();
}
......@@ -152,15 +156,21 @@ class CORE_EXPORT NGPhysicalBoxFragment final
bool check_same_block_size) const;
#endif
bool HasExtraMathMLPainting() const {
return IsMathMLFraction() || ink_overflow_computed_or_mathml_paint_info_;
}
private:
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();
return reinterpret_cast<const NGFragmentItems*>(children_end);
}
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();
if (!has_fragment_items_)
return reinterpret_cast<const NGPhysicalBoxStrut*>(items);
......@@ -169,11 +179,19 @@ class CORE_EXPORT NGPhysicalBoxFragment final
}
const NGPhysicalBoxStrut* ComputePaddingAddress() const {
DCHECK(has_padding_);
DCHECK(has_padding_ || ink_overflow_computed_or_mathml_paint_info_);
const NGPhysicalBoxStrut* address = ComputeBordersAddress();
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()
void CheckIntegrity() const;
#endif
......
......@@ -430,7 +430,7 @@ class CORE_EXPORT NGPhysicalFragment
// The following bitfields are only to be used by NGPhysicalTextFragment
// (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
// share bit fields, or put them before layout_object_ to fill the gap after
......
......@@ -505,8 +505,8 @@ void NGBoxFragmentPainter::PaintObject(
NGFragmentPainter(box_fragment_, GetDisplayItemClient())
.AddURLRectIfNeeded(paint_info, paint_offset);
}
if (is_visible && box_fragment_.IsMathMLFraction())
NGMathMLPainter(box_fragment_).PaintFractionBar(paint_info, paint_offset);
if (is_visible && box_fragment_.HasExtraMathMLPainting())
NGMathMLPainter(box_fragment_).Paint(paint_info, paint_offset);
}
if (paint_phase != PaintPhase::kSelfOutlineOnly &&
......
......@@ -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
......@@ -20,6 +20,7 @@ class NGMathMLPainter {
public:
explicit NGMathMLPainter(const NGPhysicalBoxFragment& box_fragment)
: box_fragment_(box_fragment) {}
void Paint(const PaintInfo&, PhysicalOffset);
void PaintFractionBar(const PaintInfo&, PhysicalOffset);
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