forked from firka/flutter
Add empty metrics to account for truncated whitespace for GetRectsForRange. (flutter/engine#7164)
This commit is contained in:
@@ -479,10 +479,6 @@ void Paragraph::Layout(double width, bool force) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(garyq): Make GetRectsForRange return a zero-width box for the
|
||||
// excluded whitespace such that the caret placement is correct regardless
|
||||
// of the index being whitespace or not.
|
||||
|
||||
// Exclude trailing whitespace from right and center-justified lines so the
|
||||
// last visible character in the line will be flush with the right margin.
|
||||
size_t line_end_index =
|
||||
@@ -740,6 +736,23 @@ void Paragraph::Layout(double width, bool force) {
|
||||
code_unit_runs_.insert(code_unit_runs_.end(), line_code_unit_runs.begin(),
|
||||
line_code_unit_runs.end());
|
||||
|
||||
// Add extra empty metrics for skipped whitespace at line end. This allows
|
||||
// GetRectsForRange to properly draw empty rects at the ends of lines with
|
||||
// truncated whitespace.
|
||||
if (line_end_index < line_range.end) {
|
||||
std::vector<GlyphPosition> empty_glyph_positions;
|
||||
double end_x = line_code_unit_runs.back().positions.back().x_pos.end;
|
||||
for (size_t index = line_end_index; index < line_range.end; ++index) {
|
||||
empty_glyph_positions.emplace_back(end_x, 0, index, 1);
|
||||
}
|
||||
code_unit_runs_.emplace_back(
|
||||
std::move(empty_glyph_positions),
|
||||
Range<size_t>(line_end_index, line_range.end),
|
||||
Range<double>(end_x, end_x), line_code_unit_runs.back().line_number,
|
||||
line_code_unit_runs.back().font_metrics,
|
||||
line_code_unit_runs.back().direction);
|
||||
}
|
||||
|
||||
double max_line_spacing = 0;
|
||||
double max_descent = 0;
|
||||
SkScalar max_unscaled_ascent = 0;
|
||||
|
||||
@@ -1613,6 +1613,245 @@ TEST_F(ParagraphTest,
|
||||
ASSERT_TRUE(Snapshot());
|
||||
}
|
||||
|
||||
TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeCenterParagraph)) {
|
||||
const char* text = "01234 "; // includes ideographic space
|
||||
// and english space.
|
||||
auto icu_text = icu::UnicodeString::fromUTF8(text);
|
||||
std::u16string u16_text(icu_text.getBuffer(),
|
||||
icu_text.getBuffer() + icu_text.length());
|
||||
|
||||
txt::ParagraphStyle paragraph_style;
|
||||
paragraph_style.max_lines = 10;
|
||||
paragraph_style.text_align = TextAlign::center;
|
||||
txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection());
|
||||
|
||||
txt::TextStyle text_style;
|
||||
text_style.font_family = "Roboto";
|
||||
text_style.font_size = 50;
|
||||
text_style.letter_spacing = 0;
|
||||
text_style.font_weight = FontWeight::w500;
|
||||
text_style.word_spacing = 0;
|
||||
text_style.color = SK_ColorBLACK;
|
||||
text_style.height = 1;
|
||||
builder.PushStyle(text_style);
|
||||
|
||||
builder.AddText(u16_text);
|
||||
|
||||
builder.Pop();
|
||||
|
||||
auto paragraph = builder.Build();
|
||||
paragraph->Layout(550);
|
||||
|
||||
paragraph->Paint(GetCanvas(), 0, 0);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setStyle(SkPaint::kStroke_Style);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStrokeWidth(1);
|
||||
|
||||
// Tests for GetRectsForRange()
|
||||
Paragraph::RectHeightStyle rect_height_style =
|
||||
Paragraph::RectHeightStyle::kMax;
|
||||
Paragraph::RectWidthStyle rect_width_style =
|
||||
Paragraph::RectWidthStyle::kTight;
|
||||
paint.setColor(SK_ColorRED);
|
||||
std::vector<txt::Paragraph::TextBox> boxes =
|
||||
paragraph->GetRectsForRange(0, 0, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
GetCanvas()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
EXPECT_EQ(boxes.size(), 0ull);
|
||||
|
||||
boxes =
|
||||
paragraph->GetRectsForRange(0, 1, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
GetCanvas()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
EXPECT_EQ(boxes.size(), 1ull);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 203.95508);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0.40625);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 232.37305);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 59);
|
||||
|
||||
paint.setColor(SK_ColorBLUE);
|
||||
boxes =
|
||||
paragraph->GetRectsForRange(2, 4, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
GetCanvas()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
EXPECT_EQ(boxes.size(), 1ull);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 260.79102);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0.40625);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 317.62695);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 59);
|
||||
|
||||
paint.setColor(SK_ColorGREEN);
|
||||
boxes =
|
||||
paragraph->GetRectsForRange(4, 6, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
GetCanvas()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
EXPECT_EQ(boxes.size(), 2ull);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 317.62695);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0.40625);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 346.04492);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 59);
|
||||
|
||||
paint.setColor(SK_ColorBLACK);
|
||||
boxes =
|
||||
paragraph->GetRectsForRange(5, 6, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
GetCanvas()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
EXPECT_EQ(boxes.size(), 1ull);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 346.04492);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0.40625);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 346.04492);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 59);
|
||||
|
||||
paint.setColor(SK_ColorRED);
|
||||
boxes =
|
||||
paragraph->GetRectsForRange(21, 21, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
GetCanvas()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
EXPECT_EQ(boxes.size(), 0ull);
|
||||
|
||||
ASSERT_TRUE(Snapshot());
|
||||
}
|
||||
|
||||
TEST_F(ParagraphTest,
|
||||
DISABLE_ON_WINDOWS(GetRectsForRangeCenterMultiLineParagraph)) {
|
||||
const char* text = "01234 \n0123 "; // includes ideographic
|
||||
// space and english space.
|
||||
auto icu_text = icu::UnicodeString::fromUTF8(text);
|
||||
std::u16string u16_text(icu_text.getBuffer(),
|
||||
icu_text.getBuffer() + icu_text.length());
|
||||
|
||||
txt::ParagraphStyle paragraph_style;
|
||||
paragraph_style.max_lines = 10;
|
||||
paragraph_style.text_align = TextAlign::center;
|
||||
txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection());
|
||||
|
||||
txt::TextStyle text_style;
|
||||
text_style.font_family = "Roboto";
|
||||
text_style.font_size = 50;
|
||||
text_style.letter_spacing = 0;
|
||||
text_style.font_weight = FontWeight::w500;
|
||||
text_style.word_spacing = 0;
|
||||
text_style.color = SK_ColorBLACK;
|
||||
text_style.height = 1;
|
||||
builder.PushStyle(text_style);
|
||||
|
||||
builder.AddText(u16_text);
|
||||
|
||||
builder.Pop();
|
||||
|
||||
auto paragraph = builder.Build();
|
||||
paragraph->Layout(550);
|
||||
|
||||
paragraph->Paint(GetCanvas(), 0, 0);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setStyle(SkPaint::kStroke_Style);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStrokeWidth(1);
|
||||
|
||||
// Tests for GetRectsForRange()
|
||||
Paragraph::RectHeightStyle rect_height_style =
|
||||
Paragraph::RectHeightStyle::kMax;
|
||||
Paragraph::RectWidthStyle rect_width_style =
|
||||
Paragraph::RectWidthStyle::kTight;
|
||||
paint.setColor(SK_ColorRED);
|
||||
std::vector<txt::Paragraph::TextBox> boxes =
|
||||
paragraph->GetRectsForRange(0, 0, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
GetCanvas()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
EXPECT_EQ(boxes.size(), 0ull);
|
||||
|
||||
boxes =
|
||||
paragraph->GetRectsForRange(0, 1, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
GetCanvas()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
EXPECT_EQ(boxes.size(), 1ull);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 203.95508);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0.40625);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 232.37305);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 59);
|
||||
|
||||
paint.setColor(SK_ColorBLUE);
|
||||
boxes =
|
||||
paragraph->GetRectsForRange(2, 4, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
GetCanvas()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
EXPECT_EQ(boxes.size(), 1ull);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 260.79102);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0.40625);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 317.62695);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 59);
|
||||
|
||||
paint.setColor(SK_ColorGREEN);
|
||||
boxes =
|
||||
paragraph->GetRectsForRange(4, 6, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
GetCanvas()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
EXPECT_EQ(boxes.size(), 2ull);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 317.62695);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0.40625);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 346.04492);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 59);
|
||||
|
||||
paint.setColor(SK_ColorBLACK);
|
||||
boxes =
|
||||
paragraph->GetRectsForRange(5, 6, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
GetCanvas()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
EXPECT_EQ(boxes.size(), 1ull);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 346.04492);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0.40625);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 346.04492);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 59);
|
||||
|
||||
paint.setColor(SK_ColorBLACK);
|
||||
boxes =
|
||||
paragraph->GetRectsForRange(10, 12, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
GetCanvas()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
EXPECT_EQ(boxes.size(), 1ull);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 218.16406);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 59.40625);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 275);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 118);
|
||||
|
||||
paint.setColor(SK_ColorBLACK);
|
||||
boxes =
|
||||
paragraph->GetRectsForRange(14, 18, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
GetCanvas()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
EXPECT_EQ(boxes.size(), 1ull);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 331.83594);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 59.40625);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 331.83594);
|
||||
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 118);
|
||||
|
||||
paint.setColor(SK_ColorRED);
|
||||
boxes =
|
||||
paragraph->GetRectsForRange(21, 21, rect_height_style, rect_width_style);
|
||||
for (size_t i = 0; i < boxes.size(); ++i) {
|
||||
GetCanvas()->drawRect(boxes[i].rect, paint);
|
||||
}
|
||||
EXPECT_EQ(boxes.size(), 0ull);
|
||||
|
||||
ASSERT_TRUE(Snapshot());
|
||||
}
|
||||
|
||||
SkRect GetCoordinatesForGlyphPosition(const txt::Paragraph& paragraph,
|
||||
size_t pos) {
|
||||
std::vector<txt::Paragraph::TextBox> boxes =
|
||||
|
||||
Reference in New Issue
Block a user