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 cc7d16955ac1041cdc7e6cd77371223f2fc01ebc..1fb8f80bbed842a79d59c5fe3141bbb3ece0ad4e 100644 |
| --- a/ui/gfx/render_text_harfbuzz.cc |
| +++ b/ui/gfx/render_text_harfbuzz.cc |
| @@ -24,6 +24,9 @@ |
| #include "ui/gfx/font_fallback_win.h" |
| #endif |
| +using gfx::internal::RangeF; |
| +using gfx::internal::RoundRangeF; |
| + |
| namespace gfx { |
| namespace { |
| @@ -460,6 +463,10 @@ void GetClusterAtImpl(size_t pos, |
| namespace internal { |
| +Range RoundRangeF(const RangeF& range_f) { |
| + return Range(std::round(range_f.first), std::round(range_f.second)); |
| +} |
| + |
| TextRunHarfBuzz::TextRunHarfBuzz() |
| : width(0.0f), |
| preceding_run_widths(0.0f), |
| @@ -521,21 +528,19 @@ size_t TextRunHarfBuzz::CountMissingGlyphs() const { |
| return missing; |
| } |
| -Range TextRunHarfBuzz::GetGraphemeBounds( |
| +RangeF TextRunHarfBuzz::GetGraphemeBounds( |
| base::i18n::BreakIterator* grapheme_iterator, |
| size_t text_index) { |
| DCHECK_LT(text_index, range.end()); |
| - // TODO(msw): Support floating point grapheme bounds. |
| - const int preceding_run_widths_int = SkScalarRoundToInt(preceding_run_widths); |
| if (glyph_count == 0) |
| - return Range(preceding_run_widths_int, preceding_run_widths_int + width); |
| + return RangeF(preceding_run_widths, preceding_run_widths + width); |
| Range chars; |
| Range glyphs; |
| GetClusterAt(text_index, &chars, &glyphs); |
| - const int cluster_begin_x = SkScalarRoundToInt(positions[glyphs.start()].x()); |
| - const int cluster_end_x = glyphs.end() < glyph_count ? |
| - SkScalarRoundToInt(positions[glyphs.end()].x()) : width; |
| + const float cluster_begin_x = positions[glyphs.start()].x(); |
| + const float cluster_end_x = glyphs.end() < glyph_count ? |
| + positions[glyphs.end()].x() : SkFloatToScalar(width); |
| // A cluster consists of a number of code points and corresponds to a number |
| // of glyphs that should be drawn together. A cluster can contain multiple |
| @@ -562,13 +567,13 @@ Range TextRunHarfBuzz::GetGraphemeBounds( |
| cluster_width * before / static_cast<float>(total)); |
| const int grapheme_end_x = cluster_begin_x + static_cast<int>(0.5f + |
| cluster_width * (before + 1) / static_cast<float>(total)); |
| - return Range(preceding_run_widths_int + grapheme_begin_x, |
| - preceding_run_widths_int + grapheme_end_x); |
| + return RangeF(preceding_run_widths + grapheme_begin_x, |
| + preceding_run_widths + grapheme_end_x); |
| } |
| } |
| - return Range(preceding_run_widths_int + cluster_begin_x, |
| - preceding_run_widths_int + cluster_end_x); |
| + return RangeF(preceding_run_widths + cluster_begin_x, |
| + preceding_run_widths + cluster_end_x); |
| } |
| } // namespace internal |
| @@ -595,7 +600,7 @@ SelectionModel RenderTextHarfBuzz::FindCursorPosition(const Point& point) { |
| EnsureLayout(); |
| int x = ToTextPoint(point).x(); |
| - int offset = 0; |
| + float offset = 0; |
| size_t run_index = GetRunContainingXCoord(x, &offset); |
| if (run_index >= runs_.size()) |
| return EdgeSelectionModel((x < 0) ? CURSOR_LEFT : CURSOR_RIGHT); |
| @@ -645,8 +650,13 @@ Range RenderTextHarfBuzz::GetGlyphBounds(size_t index) { |
| return Range(GetStringSize().width()); |
| const size_t layout_index = TextIndexToLayoutIndex(index); |
| internal::TextRunHarfBuzz* run = runs_[run_index]; |
| - Range bounds = run->GetGraphemeBounds(grapheme_iterator_.get(), layout_index); |
| - return run->is_rtl ? Range(bounds.end(), bounds.start()) : bounds; |
| + RangeF bounds = |
| + run->GetGraphemeBounds(grapheme_iterator_.get(), layout_index); |
| + if (cursor_enabled() && run_index == runs_.size() - 1 && |
| + index == (run->is_rtl ? run->range.start() : run->range.end() - 1)) |
| + bounds.second = std::ceil(bounds.second); |
|
msw
2014/11/24 21:51:00
Add a comment here explaining why this is necessar
ckocagil
2014/11/25 01:39:47
Done.
msw
2014/11/25 04:52:05
Acknowledged.
|
| + return RoundRangeF(run->is_rtl ? |
| + RangeF(bounds.second, bounds.first) : bounds); |
| } |
| int RenderTextHarfBuzz::GetLayoutTextBaseline() { |
| @@ -777,12 +787,12 @@ std::vector<Rect> RenderTextHarfBuzz::GetSubstringBounds(const Range& range) { |
| if (!intersection.IsValid()) |
| continue; |
| DCHECK(!intersection.is_reversed()); |
| - const Range leftmost_character_x = run->GetGraphemeBounds( |
| + const Range leftmost_character_x = RoundRangeF(run->GetGraphemeBounds( |
| grapheme_iterator_.get(), |
| - run->is_rtl ? intersection.end() - 1 : intersection.start()); |
| - const Range rightmost_character_x = run->GetGraphemeBounds( |
| + run->is_rtl ? intersection.end() - 1 : intersection.start())); |
| + const Range rightmost_character_x = RoundRangeF(run->GetGraphemeBounds( |
| grapheme_iterator_.get(), |
| - run->is_rtl ? intersection.start() : intersection.end() - 1); |
| + run->is_rtl ? intersection.start() : intersection.end() - 1)); |
| Range range_x(leftmost_character_x.start(), rightmost_character_x.end()); |
| DCHECK(!range_x.is_reversed()); |
| if (range_x.is_empty()) |
| @@ -905,7 +915,6 @@ void RenderTextHarfBuzz::DrawVisualText(Canvas* canvas) { |
| ApplyTextShadows(&renderer); |
| ApplyCompositionAndSelectionStyles(); |
| - int current_x = 0; |
| const Vector2d line_offset = GetLineOffset(0); |
| for (size_t i = 0; i < runs_.size(); ++i) { |
| const internal::TextRunHarfBuzz& run = *runs_[visual_to_logical_[i]]; |
| @@ -914,11 +923,12 @@ void RenderTextHarfBuzz::DrawVisualText(Canvas* canvas) { |
| renderer.SetFontRenderParams(run.render_params, |
| background_is_transparent()); |
| - Vector2d origin = line_offset + Vector2d(current_x, lines()[0].baseline); |
| + Vector2d origin = line_offset + Vector2d(0, lines()[0].baseline); |
| scoped_ptr<SkPoint[]> positions(new SkPoint[run.glyph_count]); |
| for (size_t j = 0; j < run.glyph_count; ++j) { |
| positions[j] = run.positions[j]; |
| - positions[j].offset(SkIntToScalar(origin.x()), SkIntToScalar(origin.y())); |
| + positions[j].offset(SkIntToScalar(origin.x()) + run.preceding_run_widths, |
| + SkIntToScalar(origin.y())); |
| } |
| for (BreakList<SkColor>::const_iterator it = |
| @@ -940,13 +950,11 @@ void RenderTextHarfBuzz::DrawVisualText(Canvas* canvas) { |
| colored_glyphs.length()); |
| int start_x = SkScalarRoundToInt(positions[colored_glyphs.start()].x()); |
| int end_x = SkScalarRoundToInt((colored_glyphs.end() == run.glyph_count) ? |
| - (run.width + SkIntToScalar(origin.x())) : |
| + (run.width + run.preceding_run_widths + SkIntToScalar(origin.x())) : |
| positions[colored_glyphs.end()].x()); |
| renderer.DrawDecorations(start_x, origin.y(), end_x - start_x, |
| run.underline, run.strike, run.diagonal_strike); |
| } |
| - |
| - current_x += run.width; |
| } |
| renderer.EndDiagonalStrike(); |
| @@ -966,12 +974,13 @@ size_t RenderTextHarfBuzz::GetRunContainingCaret( |
| return runs_.size(); |
| } |
| -size_t RenderTextHarfBuzz::GetRunContainingXCoord(int x, int* offset) const { |
| +size_t RenderTextHarfBuzz::GetRunContainingXCoord(float x, |
| + float* offset) const { |
| DCHECK(!needs_layout_); |
| if (x < 0) |
| return runs_.size(); |
| // Find the text run containing the argument point (assumed already offset). |
| - int current_x = 0; |
| + float current_x = 0; |
| for (size_t i = 0; i < runs_.size(); ++i) { |
| size_t run = visual_to_logical_[i]; |
| current_x += runs_[run]->width; |
| @@ -1133,7 +1142,7 @@ void RenderTextHarfBuzz::ShapeRun(internal::TextRunHarfBuzz* run) { |
| #endif |
| // Try shaping with the fallback fonts. |
| - for (auto family : fallback_families) { |
| + for (const auto& family : fallback_families) { |
| if (family == primary_family) |
| continue; |
| #if defined(OS_WIN) |