未验证 提交 10b45405 编写于 作者: G Gary Qian 提交者: GitHub

Implement ParagraphStyle.line_height and add tests for line_height and baselines. (#6417)

上级 7e3b41dc
......@@ -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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册