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_; |