mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Implement ParagraphStyle.line_height and add tests for line_height and baselines. (flutter/engine#6417)
This commit is contained in:
parent
9c4eca63a7
commit
98e4b8df32
@ -729,14 +729,15 @@ void Paragraph::Layout(double width, bool force) {
|
||||
auto update_line_metrics = [&](const SkPaint::FontMetrics& metrics,
|
||||
const TextStyle& style) {
|
||||
double line_spacing =
|
||||
(line_number == 0)
|
||||
? -metrics.fAscent * style.height
|
||||
: (-metrics.fAscent + metrics.fLeading) * style.height;
|
||||
(line_number == 0) ? -metrics.fAscent * style.height
|
||||
: (-metrics.fAscent + metrics.fLeading) *
|
||||
style.height * paragraph_style_.line_height;
|
||||
if (line_spacing > max_line_spacing) {
|
||||
max_line_spacing = line_spacing;
|
||||
if (line_number == 0) {
|
||||
alphabetic_baseline_ = line_spacing;
|
||||
// TODO(garyq): Properly implement ideographic_baseline_.
|
||||
// TODO(garyq): Properly implement ideographic_baseline_ and update
|
||||
// tests.
|
||||
ideographic_baseline_ =
|
||||
(metrics.fUnderlinePosition - metrics.fAscent) * style.height;
|
||||
}
|
||||
|
||||
@ -206,6 +206,7 @@ class Paragraph {
|
||||
FRIEND_TEST(ParagraphTest, RepeatLayoutParagraph);
|
||||
FRIEND_TEST(ParagraphTest, Ellipsize);
|
||||
FRIEND_TEST(ParagraphTest, UnderlineShiftParagraph);
|
||||
FRIEND_TEST(ParagraphTest, LineHeightsParagraph);
|
||||
|
||||
// Starting data to layout.
|
||||
std::vector<uint16_t> text_;
|
||||
|
||||
@ -79,6 +79,7 @@ class StyledRuns {
|
||||
FRIEND_TEST(ParagraphTest, HyphenBreakParagraph);
|
||||
FRIEND_TEST(ParagraphTest, RepeatLayoutParagraph);
|
||||
FRIEND_TEST(ParagraphTest, Ellipsize);
|
||||
FRIEND_TEST(ParagraphTest, LineHeightsParagraph);
|
||||
|
||||
struct IndexedRun {
|
||||
size_t style_index = 0;
|
||||
|
||||
@ -1731,4 +1731,155 @@ TEST_F(ParagraphTest, UnderlineShiftParagraph) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(LineHeightsParagraph)) {
|
||||
const char* text =
|
||||
"This is a very long sentence to test if the text will properly wrap "
|
||||
"around and go to the next line. Sometimes, short sentence. Longer "
|
||||
"sentences are okay too because they are nessecary. Very short. "
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
|
||||
"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
|
||||
"veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
|
||||
"commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
|
||||
"velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
|
||||
"occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
|
||||
"mollit anim id est laborum. "
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
|
||||
"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
|
||||
"veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
|
||||
"commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
|
||||
"velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
|
||||
"occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
|
||||
"mollit anim id est laborum.";
|
||||
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 = 14;
|
||||
paragraph_style.text_align = TextAlign::left;
|
||||
double line_height = 2.0;
|
||||
paragraph_style.line_height = line_height;
|
||||
txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection());
|
||||
|
||||
txt::TextStyle text_style;
|
||||
text_style.font_family = "Roboto";
|
||||
text_style.font_size = 26;
|
||||
text_style.letter_spacing = 1;
|
||||
text_style.word_spacing = 5;
|
||||
text_style.color = SK_ColorBLACK;
|
||||
text_style.height = 1;
|
||||
text_style.decoration = TextDecoration::kUnderline;
|
||||
text_style.decoration_color = SK_ColorBLACK;
|
||||
builder.PushStyle(text_style);
|
||||
|
||||
builder.AddText(u16_text);
|
||||
|
||||
builder.Pop();
|
||||
|
||||
auto paragraph = builder.Build();
|
||||
paragraph->Layout(GetTestCanvasWidth() - 100);
|
||||
|
||||
paragraph->Paint(GetCanvas(), 0, 0);
|
||||
|
||||
ASSERT_TRUE(Snapshot());
|
||||
|
||||
ASSERT_EQ(paragraph->text_.size(), std::string{text}.length());
|
||||
for (size_t i = 0; i < u16_text.length(); i++) {
|
||||
ASSERT_EQ(paragraph->text_[i], u16_text[i]);
|
||||
}
|
||||
ASSERT_EQ(paragraph->runs_.runs_.size(), 1ull);
|
||||
ASSERT_EQ(paragraph->runs_.styles_.size(), 2ull);
|
||||
ASSERT_TRUE(paragraph->runs_.styles_[1].equals(text_style));
|
||||
ASSERT_EQ(paragraph->records_.size(), paragraph_style.max_lines);
|
||||
double expected_y = 24;
|
||||
|
||||
ASSERT_TRUE(paragraph->records_[0].style().equals(text_style));
|
||||
ASSERT_DOUBLE_EQ(paragraph->records_[0].offset().y(), expected_y);
|
||||
expected_y += 27.5 * line_height;
|
||||
ASSERT_DOUBLE_EQ(paragraph->records_[0].offset().x(), 0);
|
||||
|
||||
ASSERT_TRUE(paragraph->records_[1].style().equals(text_style));
|
||||
ASSERT_DOUBLE_EQ(paragraph->records_[1].offset().y(), expected_y);
|
||||
expected_y += 27.5 * line_height;
|
||||
ASSERT_DOUBLE_EQ(paragraph->records_[1].offset().x(), 0);
|
||||
|
||||
ASSERT_TRUE(paragraph->records_[2].style().equals(text_style));
|
||||
ASSERT_DOUBLE_EQ(paragraph->records_[2].offset().y(), expected_y);
|
||||
expected_y += 27.5 * line_height;
|
||||
ASSERT_DOUBLE_EQ(paragraph->records_[2].offset().x(), 0);
|
||||
|
||||
ASSERT_TRUE(paragraph->records_[3].style().equals(text_style));
|
||||
ASSERT_DOUBLE_EQ(paragraph->records_[3].offset().y(), expected_y);
|
||||
expected_y += 27.5 * 10 * line_height;
|
||||
ASSERT_DOUBLE_EQ(paragraph->records_[3].offset().x(), 0);
|
||||
|
||||
ASSERT_TRUE(paragraph->records_[13].style().equals(text_style));
|
||||
ASSERT_DOUBLE_EQ(paragraph->records_[13].offset().y(), expected_y);
|
||||
ASSERT_DOUBLE_EQ(paragraph->records_[13].offset().x(), 0);
|
||||
|
||||
ASSERT_EQ(paragraph_style.text_align,
|
||||
paragraph->GetParagraphStyle().text_align);
|
||||
|
||||
// Tests for GetGlyphPositionAtCoordinate()
|
||||
ASSERT_EQ(paragraph->GetGlyphPositionAtCoordinate(0, 0).position, 0ull);
|
||||
ASSERT_EQ(paragraph->GetGlyphPositionAtCoordinate(1, 1).position, 0ull);
|
||||
ASSERT_EQ(paragraph->GetGlyphPositionAtCoordinate(1, 35).position, 68ull);
|
||||
ASSERT_EQ(paragraph->GetGlyphPositionAtCoordinate(1, 70).position, 68ull);
|
||||
ASSERT_EQ(paragraph->GetGlyphPositionAtCoordinate(2000, 35).position, 134ull);
|
||||
|
||||
ASSERT_TRUE(Snapshot());
|
||||
}
|
||||
|
||||
TEST_F(ParagraphTest, BaselineParagraph) {
|
||||
const char* text =
|
||||
"左線読設Byg後碁給能上目秘使約。満毎冠行来昼本可必図将発確年。今属場育"
|
||||
"図情闘陰野高備込制詩西校客。審対江置講今固残必託地集済決維駆年策。立得";
|
||||
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 = 14;
|
||||
paragraph_style.text_align = TextAlign::justify;
|
||||
paragraph_style.line_height = 1.5;
|
||||
txt::ParagraphBuilder builder(paragraph_style, GetTestFontCollection());
|
||||
|
||||
txt::TextStyle text_style;
|
||||
text_style.color = SK_ColorBLACK;
|
||||
text_style.font_size = 55;
|
||||
text_style.letter_spacing = 2;
|
||||
text_style.font_family = "Source Han Serif CN";
|
||||
text_style.decoration_style = txt::TextDecorationStyle::kSolid;
|
||||
text_style.decoration_color = SK_ColorBLACK;
|
||||
builder.PushStyle(text_style);
|
||||
|
||||
builder.AddText(u16_text);
|
||||
|
||||
builder.Pop();
|
||||
|
||||
auto paragraph = builder.Build();
|
||||
paragraph->Layout(GetTestCanvasWidth() - 100);
|
||||
|
||||
paragraph->Paint(GetCanvas(), 0, 0);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setStyle(SkPaint::kStroke_Style);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStrokeWidth(1);
|
||||
paint.setColor(SK_ColorRED);
|
||||
GetCanvas()->drawLine(0, paragraph->GetIdeographicBaseline(),
|
||||
paragraph->GetMaxWidth(),
|
||||
paragraph->GetIdeographicBaseline(), paint);
|
||||
|
||||
paint.setColor(SK_ColorGREEN);
|
||||
|
||||
GetCanvas()->drawLine(0, paragraph->GetAlphabeticBaseline(),
|
||||
paragraph->GetMaxWidth(),
|
||||
paragraph->GetAlphabeticBaseline(), paint);
|
||||
ASSERT_DOUBLE_EQ(paragraph->GetIdeographicBaseline(), 70.180000305175781);
|
||||
ASSERT_DOUBLE_EQ(paragraph->GetAlphabeticBaseline(), 63.305000305175781);
|
||||
|
||||
ASSERT_TRUE(Snapshot());
|
||||
}
|
||||
|
||||
} // namespace txt
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user