diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-05-20 09:47:09 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-06-07 11:15:42 +0000 |
commit | 189d4fd8fad9e3c776873be51938cd31a42b6177 (patch) | |
tree | 6497caeff5e383937996768766ab3bb2081a40b2 /chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc | |
parent | 8bc75099d364490b22f43a7ce366b366c08f4164 (diff) | |
download | qtwebengine-chromium-189d4fd8fad9e3c776873be51938cd31a42b6177.tar.gz |
BASELINE: Update Chromium to 90.0.4430.221
Change-Id: Iff4d9d18d2fcf1a576f3b1f453010f744a232920
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc new file mode 100644 index 00000000000..87478d8b386 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc @@ -0,0 +1,187 @@ +// 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/modules/canvas/canvas2d/canvas_formatted_text.h" +#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" +#include "third_party/blink/renderer/core/layout/layout_block_flow.h" +#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h" +#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h" +#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h" +#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h" +#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" +#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h" +#include "third_party/blink/renderer/core/paint/paint_info.h" +#include "third_party/blink/renderer/core/style/computed_style.h" +#include "third_party/blink/renderer/platform/fonts/font_description.h" +#include "third_party/blink/renderer/platform/graphics/graphics_context.h" +#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" + +namespace blink { + +void CanvasFormattedText::Trace(Visitor* visitor) const { + visitor->Trace(text_runs_); + ScriptWrappable::Trace(visitor); +} + +CanvasFormattedText* CanvasFormattedText::Create( + ExecutionContext* execution_context, + const String text) { + CanvasFormattedText* canvas_formatted_text = + MakeGarbageCollected<CanvasFormattedText>(execution_context); + CanvasFormattedTextRun* run = + MakeGarbageCollected<CanvasFormattedTextRun>(execution_context, text); + canvas_formatted_text->text_runs_.push_back(run); + canvas_formatted_text->block_->AddChild(run->GetLayoutObject()); + return canvas_formatted_text; +} + +CanvasFormattedText::CanvasFormattedText(ExecutionContext* execution_context) { + scoped_refptr<ComputedStyle> style = ComputedStyle::Create(); + style->SetDisplay(EDisplay::kBlock); + // Refrain from extending the use of document, apart from creating layout + // block flow. In the future we should handle execution_context's from worker + // threads that do not have a document. + auto* window = To<LocalDOMWindow>(execution_context); + block_ = LayoutBlockFlow::CreateAnonymous(window->document(), style, + LegacyLayout::kAuto); + block_->SetIsLayoutNGObjectForCanvasFormattedText(true); +} + +void CanvasFormattedText::Dispose() { + // Detach all the anonymous children we added, since block_->Destroy will + // destroy them. We want the lifetime of the children to be managed by their + // corresponding CanvasFormattedTextRun and not destroyed at this point. + while (block_->FirstChild()) { + block_->RemoveChild(block_->FirstChild()); + } + AllowDestroyingLayoutObjectInFinalizerScope scope; + if (block_) + block_->Destroy(); +} + +LayoutBlockFlow* CanvasFormattedText::GetLayoutBlock( + Document& document, + const FontDescription& defaultFont) { + scoped_refptr<ComputedStyle> style = ComputedStyle::Create(); + style->SetDisplay(EDisplay::kBlock); + style->SetFontDescription(defaultFont); + block_->SetStyle(style); + return block_; +} + +CanvasFormattedTextRun* CanvasFormattedText::appendRun( + CanvasFormattedTextRun* run, + ExceptionState& exception_state) { + if (!CheckRunIsNotParented(run, &exception_state)) + return nullptr; + text_runs_.push_back(run); + block_->AddChild(run->GetLayoutObject()); + return run; +} + +CanvasFormattedTextRun* CanvasFormattedText::setRun( + unsigned index, + CanvasFormattedTextRun* run, + ExceptionState& exception_state) { + if (!CheckRunsIndexBound(index, &exception_state) || + !CheckRunIsNotParented(run, &exception_state)) + return nullptr; + block_->AddChild(run->GetLayoutObject(), + text_runs_[index]->GetLayoutObject()); + block_->RemoveChild(text_runs_[index]->GetLayoutObject()); + text_runs_[index] = run; + return text_runs_[index]; +} + +CanvasFormattedTextRun* CanvasFormattedText::insertRun( + unsigned index, + CanvasFormattedTextRun* run, + ExceptionState& exception_state) { + if (!CheckRunIsNotParented(run, &exception_state)) + return nullptr; + if (index == text_runs_.size()) + return appendRun(run, exception_state); + if (!CheckRunsIndexBound(index, &exception_state)) + return nullptr; + block_->AddChild(run->GetLayoutObject(), + text_runs_[index]->GetLayoutObject()); + text_runs_.insert(index, run); + return text_runs_[index]; +} + +void CanvasFormattedText::deleteRun(unsigned index, + unsigned length, + ExceptionState& exception_state) { + if (!CheckRunsIndexBound(index, &exception_state)) + return; + // Protect against overflow, do not perform math like index + length < + // text_runs_.size(). The length passed in can be close to INT_MAX. + if (text_runs_.size() - index < length) { + exception_state.ThrowDOMException( + DOMExceptionCode::kIndexSizeError, + ExceptionMessages::IndexExceedsMaximumBound("length", length, + text_runs_.size() - index)); + return; + } + + for (wtf_size_t i = index; i < index + length; i++) { + block_->RemoveChild(text_runs_[i]->GetLayoutObject()); + } + block_->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation( + layout_invalidation_reason::kCanvasFormattedTextRunChange); + text_runs_.EraseAt(static_cast<wtf_size_t>(index), + static_cast<wtf_size_t>(length)); +} + +sk_sp<PaintRecord> CanvasFormattedText::PaintFormattedText( + Document& document, + const FontDescription& font, + double x, + double y, + double wrap_width, + FloatRect& bounds) { + LayoutBlockFlow* block = GetLayoutBlock(document, font); + NGBlockNode block_node(block); + NGInlineNode node(block); + // Call IsEmptyInline to force prepare layout. + if (node.IsEmptyInline()) + return nullptr; + + // TODO(sushraja) Once we add support for writing mode on the canvas formatted + // text, fix this to be not hardcoded horizontal top to bottom. + NGConstraintSpaceBuilder builder( + WritingMode::kHorizontalTb, + {WritingMode::kHorizontalTb, TextDirection::kLtr}, + /* is_new_fc */ true); + LayoutUnit available_logical_width(wrap_width); + LogicalSize available_size = {available_logical_width, kIndefiniteSize}; + builder.SetAvailableSize(available_size); + NGConstraintSpace space = builder.ToConstraintSpace(); + scoped_refptr<const NGLayoutResult> block_results = + block_node.Layout(space, nullptr); + const auto& fragment = + To<NGPhysicalBoxFragment>(block_results->PhysicalFragment()); + block->RecalcInlineChildrenVisualOverflow(); + bounds = FloatRect(block->PhysicalVisualOverflowRect()); + + PaintController paint_controller(PaintController::Usage::kTransient); + paint_controller.UpdateCurrentPaintChunkProperties(nullptr, + PropertyTreeState::Root()); + GraphicsContext graphics_context(paint_controller); + PhysicalOffset physical_offset((LayoutUnit(x)), (LayoutUnit(y))); + NGBoxFragmentPainter box_fragment_painter(fragment); + PaintInfo paint_info(graphics_context, CullRect::Infinite(), + PaintPhase::kForeground, kGlobalPaintNormalPhase, + kPaintLayerPaintingRenderingClipPathAsMask | + kPaintLayerPaintingRenderingResourceSubtree); + box_fragment_painter.PaintObject(paint_info, physical_offset); + paint_controller.CommitNewDisplayItems(); + paint_controller.FinishCycle(); + sk_sp<PaintRecord> recording = + paint_controller.GetPaintArtifact().GetPaintRecord( + PropertyTreeState::Root()); + return recording; +} + +} // namespace blink |