Chromium Code Reviews| Index: ui/gfx/render_text_harfbuzz.cc |
| diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc |
| index 0580abe3375e09bddae437c08a958ee6a7d16977..0861999052d68520595e9f283e885483aac47622 100644 |
| --- a/ui/gfx/render_text_harfbuzz.cc |
| +++ b/ui/gfx/render_text_harfbuzz.cc |
| @@ -233,6 +233,8 @@ class HarfBuzzLineBreaker { |
| run_list_(run_list), |
| text_x_(0), |
| line_x_(0), |
| + max_top_(0), |
| + max_bottom_(0), |
| max_descent_(0), |
| max_ascent_(0) { |
| DCHECK_EQ(multiline_, (words_ != nullptr)); |
| @@ -256,10 +258,15 @@ class HarfBuzzLineBreaker { |
| // Finishes line breaking and outputs the results. Can be called at most once. |
| void Finalize(std::vector<internal::Line>* lines, SizeF* size) { |
| DCHECK(!lines_.empty()); |
| + float trailing_height = std::max(0.f, max_bottom_ - max_descent_); |
| // Add an empty line to finish the line size calculation and remove it. |
| AdvanceLine(); |
| lines_.pop_back(); |
| *size = total_size_; |
| + // Add extra space below the last line, because some characters (eg. |
| + // underscore) may be drawn under the descent. See http://crbug.com/459812 |
| + // and the comments in AdvanceLine() below. |
|
msw
2015/02/26 00:47:21
nit: you can remove this line "// and the comments
|
| + size->Enlarge(0, trailing_height); |
| lines->swap(lines_); |
| } |
| @@ -384,10 +391,23 @@ class HarfBuzzLineBreaker { |
| line->size.set_height(std::max(min_height_, max_descent_ + max_ascent_)); |
| line->baseline = |
| std::max(min_baseline_, SkScalarRoundToInt(max_ascent_)); |
| - line->preceding_heights = std::ceil(total_size_.height()); |
| - total_size_.set_height(total_size_.height() + line->size.height()); |
| + // Line height is assumed to be the height between the ascent and the |
|
msw
2015/02/26 00:47:21
nit: consider just using a comment like that above
|
| + // descent, however some diacritic marks may appear above the ascent. |
| + // Therefore prepare enough space above the first line. Note that the |
| + // line height wouldn't be the height between top and bottom to avoid |
| + // making extra space between lines. See http://crbug.com/459812 |
| + if (line == &lines_.front()) { |
| + line->preceding_heights = |
| + std::ceil(std::max(0.f, max_top_ - max_ascent_)); |
| + total_size_.set_height(line->preceding_heights + line->size.height()); |
| + } else { |
| + line->preceding_heights = std::ceil(total_size_.height()); |
| + total_size_.set_height(total_size_.height() + line->size.height()); |
| + } |
| total_size_.set_width(std::max(total_size_.width(), line->size.width())); |
| } |
| + max_top_ = 0; |
| + max_bottom_ = 0; |
| max_descent_ = 0; |
| max_ascent_ = 0; |
| line_x_ = 0; |
| @@ -422,8 +442,10 @@ class HarfBuzzLineBreaker { |
| line->size.set_width(line->size.width() + width); |
| max_descent_ = std::max(max_descent_, metrics.fDescent); |
| - // fAscent is always negative. |
| + max_bottom_ = std::max(max_bottom_, metrics.fBottom); |
| + // fAscent and fTop are always negative. |
| max_ascent_ = std::max(max_ascent_, -metrics.fAscent); |
| + max_top_ = std::max(max_top_, -metrics.fTop); |
| if (run.is_rtl) { |
| rtl_segments_.push_back( |
| @@ -452,6 +474,8 @@ class HarfBuzzLineBreaker { |
| SkScalar text_x_; |
| SkScalar line_x_; |
| + float max_top_; |
| + float max_bottom_; |
| float max_descent_; |
| float max_ascent_; |