Commit 4c629ccf authored by Robert Hogan's avatar Robert Hogan Committed by Commit Bot

Place ellipsis correctly in justified text

When computing the position for an ellipsis we need to ensure
any expansion on the linebox is included in the width of the
text we use to arrive at the position.

Bug: 558283
Change-Id: Ib85acee76c3b97e3fea325412447c01cb9d2d7c2
Reviewed-on: https://chromium-review.googlesource.com/572902Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Commit-Queue: Emil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#488518}
parent 3046d581
<!DOCTYPE html>
<style>
.test {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4;
text-overflow: ellipsis;
text-align: justify;
overflow: hidden;
width: 250px;
}
</style>
<p>crbug.com/558283: Ellipsis should be positioned correctly in justified text. The bug shows up best inside a line-clamped flexbox.</p>
<div class="test">
"On the other hand, we denounce with righteous indignation and dislike men
who are so beguiled and demoralized by the charms of pleasure of the moment
</div>
...@@ -44,7 +44,8 @@ class LayoutBR final : public LayoutText { ...@@ -44,7 +44,8 @@ class LayoutBR final : public LayoutText {
LayoutUnit /* xpos */, LayoutUnit /* xpos */,
TextDirection, TextDirection,
HashSet<const SimpleFontData*>* = nullptr /* fallbackFonts */, HashSet<const SimpleFontData*>* = nullptr /* fallbackFonts */,
FloatRect* /* glyphBounds */ = nullptr) const override { FloatRect* /* glyphBounds */ = nullptr,
float /* expansion */ = false) const override {
return 0; return 0;
} }
float Width(unsigned /* from */, float Width(unsigned /* from */,
...@@ -53,7 +54,8 @@ class LayoutBR final : public LayoutText { ...@@ -53,7 +54,8 @@ class LayoutBR final : public LayoutText {
TextDirection, TextDirection,
bool = false /* firstLine */, bool = false /* firstLine */,
HashSet<const SimpleFontData*>* = nullptr /* fallbackFonts */, HashSet<const SimpleFontData*>* = nullptr /* fallbackFonts */,
FloatRect* /* glyphBounds */ = nullptr) const override { FloatRect* /* glyphBounds */ = nullptr,
float /* expansion */ = false) const override {
return 0; return 0;
} }
......
...@@ -798,7 +798,8 @@ ALWAYS_INLINE float LayoutText::WidthFromFont( ...@@ -798,7 +798,8 @@ ALWAYS_INLINE float LayoutText::WidthFromFont(
float text_width_so_far, float text_width_so_far,
TextDirection text_direction, TextDirection text_direction,
HashSet<const SimpleFontData*>* fallback_fonts, HashSet<const SimpleFontData*>* fallback_fonts,
FloatRect* glyph_bounds_accumulation) const { FloatRect* glyph_bounds_accumulation,
float expansion) const {
if (Style()->HasTextCombine() && IsCombineText()) { if (Style()->HasTextCombine() && IsCombineText()) {
const LayoutTextCombine* combine_text = ToLayoutTextCombine(this); const LayoutTextCombine* combine_text = ToLayoutTextCombine(this);
if (combine_text->IsCombined()) if (combine_text->IsCombined())
...@@ -811,6 +812,7 @@ ALWAYS_INLINE float LayoutText::WidthFromFont( ...@@ -811,6 +812,7 @@ ALWAYS_INLINE float LayoutText::WidthFromFont(
DCHECK_GE(run.CharactersLength(), run.length()); DCHECK_GE(run.CharactersLength(), run.length());
run.SetTabSize(!Style()->CollapseWhiteSpace(), Style()->GetTabSize()); run.SetTabSize(!Style()->CollapseWhiteSpace(), Style()->GetTabSize());
run.SetXPos(lead_width + text_width_so_far); run.SetXPos(lead_width + text_width_so_far);
run.SetExpansion(expansion);
FloatRect new_glyph_bounds; FloatRect new_glyph_bounds;
float result = float result =
...@@ -1757,7 +1759,8 @@ float LayoutText::Width(unsigned from, ...@@ -1757,7 +1759,8 @@ float LayoutText::Width(unsigned from,
TextDirection text_direction, TextDirection text_direction,
bool first_line, bool first_line,
HashSet<const SimpleFontData*>* fallback_fonts, HashSet<const SimpleFontData*>* fallback_fonts,
FloatRect* glyph_bounds) const { FloatRect* glyph_bounds,
float expansion) const {
if (from >= TextLength()) if (from >= TextLength())
return 0; return 0;
...@@ -1765,7 +1768,7 @@ float LayoutText::Width(unsigned from, ...@@ -1765,7 +1768,7 @@ float LayoutText::Width(unsigned from,
len = TextLength() - from; len = TextLength() - from;
return Width(from, len, Style(first_line)->GetFont(), x_pos, text_direction, return Width(from, len, Style(first_line)->GetFont(), x_pos, text_direction,
fallback_fonts, glyph_bounds); fallback_fonts, glyph_bounds, expansion);
} }
float LayoutText::Width(unsigned from, float LayoutText::Width(unsigned from,
...@@ -1774,7 +1777,8 @@ float LayoutText::Width(unsigned from, ...@@ -1774,7 +1777,8 @@ float LayoutText::Width(unsigned from,
LayoutUnit x_pos, LayoutUnit x_pos,
TextDirection text_direction, TextDirection text_direction,
HashSet<const SimpleFontData*>* fallback_fonts, HashSet<const SimpleFontData*>* fallback_fonts,
FloatRect* glyph_bounds) const { FloatRect* glyph_bounds,
float expansion) const {
DCHECK_LE(from + len, TextLength()); DCHECK_LE(from + len, TextLength());
if (!TextLength()) if (!TextLength())
return 0; return 0;
...@@ -1803,7 +1807,7 @@ float LayoutText::Width(unsigned from, ...@@ -1803,7 +1807,7 @@ float LayoutText::Width(unsigned from,
} }
} else { } else {
w = WidthFromFont(f, from, len, x_pos.ToFloat(), 0, text_direction, w = WidthFromFont(f, from, len, x_pos.ToFloat(), 0, text_direction,
fallback_fonts, glyph_bounds); fallback_fonts, glyph_bounds, expansion);
} }
} else { } else {
TextRun run = TextRun run =
......
...@@ -137,14 +137,16 @@ class CORE_EXPORT LayoutText : public LayoutObject { ...@@ -137,14 +137,16 @@ class CORE_EXPORT LayoutText : public LayoutObject {
LayoutUnit x_pos, LayoutUnit x_pos,
TextDirection, TextDirection,
HashSet<const SimpleFontData*>* fallback_fonts = nullptr, HashSet<const SimpleFontData*>* fallback_fonts = nullptr,
FloatRect* glyph_bounds = nullptr) const; FloatRect* glyph_bounds = nullptr,
float expansion = 0) const;
virtual float Width(unsigned from, virtual float Width(unsigned from,
unsigned len, unsigned len,
LayoutUnit x_pos, LayoutUnit x_pos,
TextDirection, TextDirection,
bool first_line = false, bool first_line = false,
HashSet<const SimpleFontData*>* fallback_fonts = nullptr, HashSet<const SimpleFontData*>* fallback_fonts = nullptr,
FloatRect* glyph_bounds = nullptr) const; FloatRect* glyph_bounds = nullptr,
float expansion = 0) const;
float MinLogicalWidth() const; float MinLogicalWidth() const;
float MaxLogicalWidth() const; float MaxLogicalWidth() const;
...@@ -276,7 +278,8 @@ class CORE_EXPORT LayoutText : public LayoutObject { ...@@ -276,7 +278,8 @@ class CORE_EXPORT LayoutText : public LayoutObject {
float text_width_so_far, float text_width_so_far,
TextDirection, TextDirection,
HashSet<const SimpleFontData*>* fallback_fonts, HashSet<const SimpleFontData*>* fallback_fonts,
FloatRect* glyph_bounds_accumulation) const; FloatRect* glyph_bounds_accumulation,
float expansion = 0) const;
void SecureText(UChar mask); void SecureText(UChar mask);
......
...@@ -53,7 +53,8 @@ float LayoutTextCombine::Width(unsigned from, ...@@ -53,7 +53,8 @@ float LayoutTextCombine::Width(unsigned from,
LayoutUnit x_position, LayoutUnit x_position,
TextDirection direction, TextDirection direction,
HashSet<const SimpleFontData*>* fallback_fonts, HashSet<const SimpleFontData*>* fallback_fonts,
FloatRect* glyph_bounds) const { FloatRect* glyph_bounds,
float) const {
if (!length) if (!length)
return 0; return 0;
......
...@@ -54,7 +54,8 @@ class LayoutTextCombine final : public LayoutText { ...@@ -54,7 +54,8 @@ class LayoutTextCombine final : public LayoutText {
LayoutUnit x_position, LayoutUnit x_position,
TextDirection, TextDirection,
HashSet<const SimpleFontData*>* fallback_fonts = nullptr, HashSet<const SimpleFontData*>* fallback_fonts = nullptr,
FloatRect* glyph_bounds = nullptr) const override; FloatRect* glyph_bounds = nullptr,
float expansion = 0) const override;
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override; void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
void SetTextInternal(RefPtr<StringImpl>) override; void SetTextInternal(RefPtr<StringImpl>) override;
void UpdateIsCombined(); void UpdateIsCombined();
......
...@@ -89,9 +89,10 @@ class LineLayoutText : public LineLayoutItem { ...@@ -89,9 +89,10 @@ class LineLayoutText : public LineLayoutItem {
LayoutUnit x_pos, LayoutUnit x_pos,
TextDirection text_direction, TextDirection text_direction,
HashSet<const SimpleFontData*>* fallback_fonts, HashSet<const SimpleFontData*>* fallback_fonts,
FloatRect* glyph_bounds) const { FloatRect* glyph_bounds,
float expansion = 0) const {
return ToText()->Width(from, len, font, x_pos, text_direction, return ToText()->Width(from, len, font, x_pos, text_direction,
fallback_fonts, glyph_bounds); fallback_fonts, glyph_bounds, expansion);
} }
float Width(unsigned from, float Width(unsigned from,
...@@ -100,9 +101,10 @@ class LineLayoutText : public LineLayoutItem { ...@@ -100,9 +101,10 @@ class LineLayoutText : public LineLayoutItem {
TextDirection text_direction, TextDirection text_direction,
bool first_line, bool first_line,
HashSet<const SimpleFontData*>* fallback_fonts = nullptr, HashSet<const SimpleFontData*>* fallback_fonts = nullptr,
FloatRect* glyph_bounds = nullptr) const { FloatRect* glyph_bounds = nullptr,
float expansion = 0) const {
return ToText()->Width(from, len, x_pos, text_direction, first_line, return ToText()->Width(from, len, x_pos, text_direction, first_line,
fallback_fonts, glyph_bounds); fallback_fonts, glyph_bounds, expansion);
} }
float HyphenWidth(const Font& font, TextDirection text_direction) { float HyphenWidth(const Font& font, TextDirection text_direction) {
......
...@@ -442,7 +442,7 @@ LayoutUnit InlineTextBox::PlaceEllipsisBox(bool flow_is_ltr, ...@@ -442,7 +442,7 @@ LayoutUnit InlineTextBox::PlaceEllipsisBox(bool flow_is_ltr,
ltr == flow_is_ltr ? start_ : start_ + offset, ltr == flow_is_ltr ? start_ : start_ + offset,
ltr == flow_is_ltr ? offset : len_ - offset, TextPos(), ltr == flow_is_ltr ? offset : len_ - offset, TextPos(),
flow_is_ltr ? TextDirection::kLtr : TextDirection::kRtl, flow_is_ltr ? TextDirection::kLtr : TextDirection::kRtl,
IsFirstLineStyle())); IsFirstLineStyle(), nullptr, nullptr, Expansion()));
// The ellipsis needs to be placed just after the last visible character. // The ellipsis needs to be placed just after the last visible character.
// Where "after" is defined by the flow directionality, not the inline // Where "after" is defined by the flow directionality, not the inline
......
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