未验证 提交 9f8cf7eb 编写于 作者: J Jason Simmons 提交者: GitHub

libtxt: track the font metrics of each run in order to calculate heights in...

libtxt: track the font metrics of each run in order to calculate heights in GetRectsForRange (#4442)

Previously GetRectsForRange was assigning each rectangle a height matching the
height of the entire line.  If the line includes multiple text styles, callers
will expect each span's rectangle to reflect the height of that span.
(see text_painter_rtl_test.dart)
上级 edaecdc8
......@@ -157,11 +157,13 @@ Paragraph::CodeUnitRun::CodeUnitRun(std::vector<GlyphPosition>&& p,
Range<size_t> cu,
Range<double> x,
size_t line,
const SkPaint::FontMetrics& metrics,
TextDirection dir)
: positions(std::move(p)),
code_units(cu),
x_pos(x),
line_number(line),
font_metrics(metrics),
direction(dir) {}
Paragraph::Paragraph() {
......@@ -484,7 +486,6 @@ void Paragraph::Layout(double width, bool force) {
blob_start += blob_len;
}
std::vector<GlyphPosition> glyph_positions;
size_t code_unit_index;
if (run.is_rtl()) {
code_unit_index = text_count;
......@@ -496,6 +497,8 @@ void Paragraph::Layout(double width, bool force) {
// Build a Skia text blob from each group of glyphs.
for (const Range<size_t>& glyph_blob : glyph_blobs) {
std::vector<GlyphPosition> glyph_positions;
paint.setTypeface(GetTypefaceForGlyph(layout, glyph_blob.start));
const SkTextBlobBuilder::RunBuffer& blob_buffer =
builder.allocRunPos(paint, glyph_blob.end - glyph_blob.start);
......@@ -578,23 +581,23 @@ void Paragraph::Layout(double width, bool force) {
paint_records.emplace_back(run.style, SkPoint::Make(run_x_offset, 0),
builder.make(), metrics, line_number,
layout.getAdvance());
}
line_glyph_positions.insert(line_glyph_positions.end(),
glyph_positions.begin(),
glyph_positions.end());
// Add a record of glyph positions sorted by code unit index.
std::vector<GlyphPosition> code_unit_positions(glyph_positions);
std::sort(code_unit_positions.begin(), code_unit_positions.end(),
[](const GlyphPosition& a, const GlyphPosition& b) {
return a.code_units.start < b.code_units.start;
});
code_unit_runs_.emplace_back(
std::move(code_unit_positions), Range<size_t>(run.start, run.end),
Range<double>(glyph_positions.front().x_pos.start,
glyph_positions.back().x_pos.end),
line_number, run.direction);
line_glyph_positions.insert(line_glyph_positions.end(),
glyph_positions.begin(),
glyph_positions.end());
// Add a record of glyph positions sorted by code unit index.
std::vector<GlyphPosition> code_unit_positions(glyph_positions);
std::sort(code_unit_positions.begin(), code_unit_positions.end(),
[](const GlyphPosition& a, const GlyphPosition& b) {
return a.code_units.start < b.code_units.start;
});
code_unit_runs_.emplace_back(
std::move(code_unit_positions), Range<size_t>(run.start, run.end),
Range<double>(glyph_positions.front().x_pos.start,
glyph_positions.back().x_pos.end),
line_number, metrics, run.direction);
}
run_x_offset += layout.getAdvance();
}
......@@ -625,6 +628,7 @@ void Paragraph::Layout(double width, bool force) {
line_heights_.push_back((line_heights_.empty() ? 0 : line_heights_.back()) +
round(max_line_spacing + max_descent));
line_baselines_.push_back(line_heights_.back() - max_descent);
y_offset += round(max_line_spacing + prev_max_descent);
prev_max_descent = max_descent;
......@@ -897,9 +901,9 @@ std::vector<Paragraph::TextBox> Paragraph::GetRectsForRange(size_t start,
if (run.code_units.end <= start)
continue;
SkScalar top =
(run.line_number > 0) ? line_heights_[run.line_number - 1] : 0;
SkScalar bottom = line_heights_[run.line_number];
double baseline = line_baselines_[run.line_number];
SkScalar top = baseline + run.font_metrics.fAscent;
SkScalar bottom = baseline + run.font_metrics.fDescent;
SkScalar left, right;
if (run.code_units.start >= start && run.code_units.end <= end) {
......
......@@ -206,6 +206,7 @@ class Paragraph {
std::vector<PaintRecord> records_;
std::vector<double> line_heights_;
std::vector<double> line_baselines_;
bool did_exceed_max_lines_;
struct GlyphPosition {
......@@ -232,12 +233,14 @@ class Paragraph {
Range<size_t> code_units;
Range<double> x_pos;
size_t line_number;
SkPaint::FontMetrics font_metrics;
TextDirection direction;
CodeUnitRun(std::vector<GlyphPosition>&& p,
Range<size_t> cu,
Range<double> x,
size_t line,
const SkPaint::FontMetrics& metrics,
TextDirection dir);
};
......
......@@ -968,7 +968,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeParagraph)) {
}
EXPECT_EQ(boxes.size(), 1ull);
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 0);
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0);
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0.40625);
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 28.417969);
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 59);
......@@ -979,7 +979,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeParagraph)) {
}
EXPECT_EQ(boxes.size(), 1ull);
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 56.835938);
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0);
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0.40625);
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 177.44922);
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 59);
......@@ -990,7 +990,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeParagraph)) {
}
EXPECT_EQ(boxes.size(), 1ull);
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 177);
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0);
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0.40625);
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 506.08984);
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 59);
......@@ -1001,14 +1001,14 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeParagraph)) {
}
EXPECT_EQ(boxes.size(), 4ull);
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 210.83594);
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 59);
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 59.40625);
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 463.44922);
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 118);
// TODO(garyq): The following set of vals are definetly wrong and
// end of paragraph handling needs to be fixed in a later patch.
EXPECT_FLOAT_EQ(boxes[3].rect.left(), 0);
EXPECT_FLOAT_EQ(boxes[3].rect.top(), 236);
EXPECT_FLOAT_EQ(boxes[3].rect.top(), 236.40625);
EXPECT_FLOAT_EQ(boxes[3].rect.right(), 142.08984);
EXPECT_FLOAT_EQ(boxes[3].rect.bottom(), 295);
......@@ -1019,7 +1019,7 @@ TEST_F(ParagraphTest, DISABLE_ON_WINDOWS(GetRectsForRangeParagraph)) {
}
EXPECT_EQ(boxes.size(), 1ull);
EXPECT_FLOAT_EQ(boxes[0].rect.left(), 449.25391);
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0);
EXPECT_FLOAT_EQ(boxes[0].rect.top(), 0.40625);
EXPECT_FLOAT_EQ(boxes[0].rect.right(), 519.44922);
EXPECT_FLOAT_EQ(boxes[0].rect.bottom(), 59);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册