Commit 6cf9aaf5 authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

Transform the selection rect in vertical writing mode

In InlineTextBoxPainter and NGTextFragmentPainter, previously we
manually transpose the selection rect to convert it between the space of
the original space and the rotated space for vertical text. The code
might be inconsistent with the rotation transform. Actually
crrev.com/c/2319540 exposed the bug in InlineTextBoxPainter when the
vertical selection rect is wider than the text rect.

Now use the rotation transform to transform the selection rect to avoid
the inconsistency.

Change-Id: If75fa61539842cc32a9129391b1a32edbe631847
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2324066
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#792443}
parent b042343a
...@@ -222,7 +222,8 @@ void InlineTextBoxPainter::Paint(const PaintInfo& paint_info, ...@@ -222,7 +222,8 @@ void InlineTextBoxPainter::Paint(const PaintInfo& paint_info,
if (inline_text_box_.HasHyphen()) if (inline_text_box_.HasHyphen())
length = text_run.length(); length = text_run.length();
bool should_rotate = false; base::Optional<AffineTransform> rotation;
base::Optional<GraphicsContextStateSaver> state_saver;
LayoutTextCombine* combined_text = nullptr; LayoutTextCombine* combined_text = nullptr;
if (!inline_text_box_.IsHorizontal()) { if (!inline_text_box_.IsHorizontal()) {
if (style_to_use.HasTextCombine() && if (style_to_use.HasTextCombine() &&
...@@ -248,9 +249,10 @@ void InlineTextBoxPainter::Paint(const PaintInfo& paint_info, ...@@ -248,9 +249,10 @@ void InlineTextBoxPainter::Paint(const PaintInfo& paint_info,
} }
} }
} else { } else {
should_rotate = true; rotation.emplace(
context.ConcatCTM(
TextPainterBase::Rotation(box_rect, TextPainterBase::kClockwise)); TextPainterBase::Rotation(box_rect, TextPainterBase::kClockwise));
state_saver.emplace(context);
context.ConcatCTM(*rotation);
} }
} }
...@@ -298,15 +300,10 @@ void InlineTextBoxPainter::Paint(const PaintInfo& paint_info, ...@@ -298,15 +300,10 @@ void InlineTextBoxPainter::Paint(const PaintInfo& paint_info,
} }
if (recorder && !box_rect.Contains(selection_rect)) { if (recorder && !box_rect.Contains(selection_rect)) {
if (should_rotate) { IntRect selection_visual_rect = EnclosingIntRect(selection_rect);
// selection_rect is in the coordinates space of the rotation if (rotation)
// transform. Convert it to the non-rotated space for visual rect. selection_visual_rect = rotation->MapRect(selection_visual_rect);
selection_rect.Move(-box_rect.offset); recorder->UniteVisualRect(selection_visual_rect);
std::swap(selection_rect.offset.left, selection_rect.offset.top);
std::swap(selection_rect.size.width, selection_rect.size.height);
selection_rect.Move(box_rect.offset);
}
recorder->UniteVisualRect(EnclosingIntRect(selection_rect));
} }
} }
} }
...@@ -444,11 +441,6 @@ void InlineTextBoxPainter::Paint(const PaintInfo& paint_info, ...@@ -444,11 +441,6 @@ void InlineTextBoxPainter::Paint(const PaintInfo& paint_info,
font, DocumentMarkerPaintPhase::kForeground); font, DocumentMarkerPaintPhase::kForeground);
} }
if (should_rotate) {
context.ConcatCTM(TextPainterBase::Rotation(
box_rect, TextPainterBase::kCounterclockwise));
}
if (!font.ShouldSkipDrawing()) if (!font.ShouldSkipDrawing())
PaintTimingDetector::NotifyTextPaint(visual_rect); PaintTimingDetector::NotifyTextPaint(visual_rect);
} }
......
...@@ -401,14 +401,11 @@ class SelectionPaintState { ...@@ -401,14 +401,11 @@ class SelectionPaintState {
PaintRect(context, *selection_rect_, color); PaintRect(context, *selection_rect_, color);
} }
// Transposes selection_rect_. Called before we paint vertical selected text // Called before we paint vertical selected text under a rotation transform.
// under a rotation transform. void MapSelectionRectIntoRotatedSpace(const AffineTransform& rotation) {
void TransposeSelectionRect(const PhysicalOffset& origin) {
DCHECK(selection_rect_); DCHECK(selection_rect_);
selection_rect_->Move(-origin); *selection_rect_ = PhysicalRect::EnclosingRect(
std::swap(selection_rect_->offset.top, selection_rect_->offset.left); rotation.Inverse().MapRect(FloatRect(*selection_rect_)));
std::swap(selection_rect_->size.width, selection_rect_->size.height);
selection_rect_->Move(origin);
} }
// Paint the selected text only. // Paint the selected text only.
...@@ -599,8 +596,6 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info, ...@@ -599,8 +596,6 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info,
const SimpleFontData* font_data = font.PrimaryFont(); const SimpleFontData* font_data = font.PrimaryFont();
DCHECK(font_data); DCHECK(font_data);
base::Optional<GraphicsContextStateSaver> state_saver;
// 1. Paint backgrounds behind text if needed. Examples of such backgrounds // 1. Paint backgrounds behind text if needed. Examples of such backgrounds
// include selection and composition highlights. They use physical coordinates // include selection and composition highlights. They use physical coordinates
// so are painted before GraphicsContext rotation. // so are painted before GraphicsContext rotation.
...@@ -619,6 +614,8 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info, ...@@ -619,6 +614,8 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info,
} }
} }
base::Optional<GraphicsContextStateSaver> state_saver;
base::Optional<AffineTransform> rotation;
const WritingMode writing_mode = style.GetWritingMode(); const WritingMode writing_mode = style.GetWritingMode();
const bool is_horizontal = IsHorizontalWritingMode(writing_mode); const bool is_horizontal = IsHorizontalWritingMode(writing_mode);
if (!is_horizontal) { if (!is_horizontal) {
...@@ -626,10 +623,11 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info, ...@@ -626,10 +623,11 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info,
// Because we rotate the GraphicsContext to match the logical direction, // Because we rotate the GraphicsContext to match the logical direction,
// transpose the |box_rect| to match to it. // transpose the |box_rect| to match to it.
box_rect.size = PhysicalSize(box_rect.Height(), box_rect.Width()); box_rect.size = PhysicalSize(box_rect.Height(), box_rect.Width());
context.ConcatCTM(TextPainterBase::Rotation( rotation.emplace(TextPainterBase::Rotation(
box_rect, writing_mode != WritingMode::kSidewaysLr box_rect, writing_mode != WritingMode::kSidewaysLr
? TextPainterBase::kClockwise ? TextPainterBase::kClockwise
: TextPainterBase::kCounterclockwise)); : TextPainterBase::kCounterclockwise));
context.ConcatCTM(*rotation);
} }
// 2. Now paint the foreground, including text and decorations. // 2. Now paint the foreground, including text and decorations.
...@@ -700,8 +698,8 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info, ...@@ -700,8 +698,8 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info,
// Paint only the text that is selected. // Paint only the text that is selected.
if (!selection->IsSelectionRectComputed()) if (!selection->IsSelectionRectComputed())
selection->ComputeSelectionRect(box_rect.offset); selection->ComputeSelectionRect(box_rect.offset);
if (!is_horizontal) if (rotation)
selection->TransposeSelectionRect(box_rect.offset); selection->MapSelectionRectIntoRotatedSpace(*rotation);
selection->PaintSelectedText(text_painter, length, text_style, node_id); selection->PaintSelectedText(text_painter, length, text_style, node_id);
} }
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
"backgroundColor": "#FFFFFF", "backgroundColor": "#FFFFFF",
"invalidations": [ "invalidations": [
[398, 123, 375, 404], [398, 123, 375, 404],
[389, 123, 34, 399],
[750, 522, 25, 5] [750, 522, 25, 5]
] ]
} }
......
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