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 e4469a6fdfa2500f117317a0b22e84bfac6deb4c..b4a809ad9b5e2bc4fd72aea703a05b7c10c33367 100644 |
| --- a/ui/gfx/render_text_harfbuzz.cc |
| +++ b/ui/gfx/render_text_harfbuzz.cc |
| @@ -220,6 +220,7 @@ class HarfBuzzLineBreaker { |
| float min_height, |
| bool multiline, |
| const base::string16& text, |
| + const std::vector<int32_t>& logical_to_visual, |
| const BreakList<size_t>* words, |
| const ScopedVector<internal::TextRunHarfBuzz>& runs) |
| : max_width_((max_width == 0) ? SK_ScalarMax : SkIntToScalar(max_width)), |
| @@ -227,6 +228,7 @@ class HarfBuzzLineBreaker { |
| min_height_(min_height), |
| multiline_(multiline), |
| text_(text), |
| + logical_to_visual_(logical_to_visual), |
| words_(words), |
| runs_(runs), |
| text_x_(0), |
| @@ -265,6 +267,18 @@ class HarfBuzzLineBreaker { |
| // A (line index, segment index) pair that specifies a segment in |lines_|. |
| typedef std::pair<size_t, size_t> SegmentHandle; |
| + struct SortByVisualPosition { |
|
ckocagil
2015/02/13 19:05:25
Make this comparator a lambda expression and defin
Jun Mukai
2015/02/13 21:57:58
Done.
|
| + explicit SortByVisualPosition(const std::vector<int32_t>& logical_to_visual) |
| + : logical_to_visual(logical_to_visual) {} |
| + |
| + bool operator()(const internal::LineSegment& segment1, |
| + const internal::LineSegment& segment2) { |
| + return logical_to_visual[segment1.run] < logical_to_visual[segment2.run]; |
| + } |
| + |
| + const std::vector<int32_t>& logical_to_visual; |
| + }; |
| + |
| internal::LineSegment* SegmentFromHandle(const SegmentHandle& handle) { |
| return &lines_[handle.first].segments[handle.second]; |
| } |
| @@ -373,6 +387,8 @@ class HarfBuzzLineBreaker { |
| void AdvanceLine() { |
| if (!lines_.empty()) { |
| internal::Line* line = &lines_.back(); |
| + std::sort(line->segments.begin(), line->segments.end(), |
| + SortByVisualPosition(logical_to_visual_)); |
| line->size.set_height(std::max(min_height_, max_descent_ + max_ascent_)); |
| line->baseline = |
| std::max(min_baseline_, SkScalarRoundToInt(max_ascent_)); |
| @@ -434,6 +450,7 @@ class HarfBuzzLineBreaker { |
| const float min_height_; |
| const bool multiline_; |
| const base::string16& text_; |
| + const std::vector<int32_t>& logical_to_visual_; |
| const BreakList<size_t>* const words_; |
| const ScopedVector<internal::TextRunHarfBuzz>& runs_; |
| @@ -923,7 +940,8 @@ void RenderTextHarfBuzz::EnsureLayout() { |
| HarfBuzzLineBreaker line_breaker( |
| display_rect().width(), font_list().GetBaseline(), |
| std::max(font_list().GetHeight(), min_line_height()), multiline(), |
| - GetLayoutText(), multiline() ? &GetLineBreaks() : nullptr, runs_); |
| + GetLayoutText(), logical_to_visual_, |
| + multiline() ? &GetLineBreaks() : nullptr, runs_); |
| // TODO(vadimt): Remove ScopedTracker below once crbug.com/431326 is fixed. |
| tracked_objects::ScopedTracker tracking_profile3( |
| @@ -931,7 +949,7 @@ void RenderTextHarfBuzz::EnsureLayout() { |
| "431326 RenderTextHarfBuzz::EnsureLayout3")); |
| for (size_t i = 0; i < runs_.size(); ++i) |
| - line_breaker.AddRun(visual_to_logical_[i]); |
| + line_breaker.AddRun(i); |
| std::vector<internal::Line> lines; |
| line_breaker.Finalize(&lines, &total_size_); |
| set_lines(&lines); |
| @@ -939,13 +957,18 @@ void RenderTextHarfBuzz::EnsureLayout() { |
| } |
| void RenderTextHarfBuzz::DrawVisualText(Canvas* canvas) { |
| + internal::SkiaTextRenderer renderer(canvas); |
| + DrawVisualTextInternal(&renderer); |
| +} |
| + |
| +void RenderTextHarfBuzz::DrawVisualTextInternal( |
| + internal::SkiaTextRenderer* renderer) { |
| DCHECK(!needs_layout_); |
| if (lines().empty()) |
| return; |
| - internal::SkiaTextRenderer renderer(canvas); |
| - ApplyFadeEffects(&renderer); |
| - ApplyTextShadows(&renderer); |
| + ApplyFadeEffects(renderer); |
| + ApplyTextShadows(renderer); |
| ApplyCompositionAndSelectionStyles(); |
| for (size_t i = 0; i < lines().size(); ++i) { |
| @@ -954,10 +977,10 @@ void RenderTextHarfBuzz::DrawVisualText(Canvas* canvas) { |
| SkScalar preceding_segment_widths = 0; |
| for (const internal::LineSegment& segment : line.segments) { |
| const internal::TextRunHarfBuzz& run = *runs_[segment.run]; |
| - renderer.SetTypeface(run.skia_face.get()); |
| - renderer.SetTextSize(SkIntToScalar(run.font_size)); |
| - renderer.SetFontRenderParams(run.render_params, |
| - background_is_transparent()); |
| + renderer->SetTypeface(run.skia_face.get()); |
| + renderer->SetTextSize(SkIntToScalar(run.font_size)); |
| + renderer->SetFontRenderParams(run.render_params, |
| + background_is_transparent()); |
| Range glyphs_range = run.CharRangeToGlyphRange(segment.char_range); |
| scoped_ptr<SkPoint[]> positions(new SkPoint[glyphs_range.length()]); |
| SkScalar offset_x = |
| @@ -984,8 +1007,8 @@ void RenderTextHarfBuzz::DrawVisualText(Canvas* canvas) { |
| if (colored_glyphs.is_empty()) |
| continue; |
| - renderer.SetForegroundColor(it->second); |
| - renderer.DrawPosText( |
| + renderer->SetForegroundColor(it->second); |
| + renderer->DrawPosText( |
| &positions[colored_glyphs.start() - glyphs_range.start()], |
| &run.glyphs[colored_glyphs.start()], colored_glyphs.length()); |
| int start_x = SkScalarRoundToInt( |
| @@ -995,15 +1018,15 @@ void RenderTextHarfBuzz::DrawVisualText(Canvas* canvas) { |
| ? (SkFloatToScalar(segment.width) + preceding_segment_widths + |
| SkIntToScalar(origin.x())) |
| : positions[colored_glyphs.end() - glyphs_range.start()].x()); |
| - renderer.DrawDecorations(start_x, origin.y(), end_x - start_x, |
| - run.underline, run.strike, |
| - run.diagonal_strike); |
| + renderer->DrawDecorations(start_x, origin.y(), end_x - start_x, |
| + run.underline, run.strike, |
| + run.diagonal_strike); |
| } |
| preceding_segment_widths += SkFloatToScalar(segment.width); |
| } |
| } |
| - renderer.EndDiagonalStrike(); |
| + renderer->EndDiagonalStrike(); |
| UndoCompositionAndSelectionStyles(); |
| } |
| @@ -1318,8 +1341,8 @@ bool RenderTextHarfBuzz::ShapeRunWithFont(internal::TextRunHarfBuzz* run, |
| const SkScalar y_offset = SkFixedToScalar(hb_positions[i].y_offset); |
| run->positions[i].set(run->width + x_offset, -y_offset); |
| run->width += (glyph_width_for_test_ > 0) |
| - ? SkIntToScalar(glyph_width_for_test_) |
| - : SkFixedToScalar(hb_positions[i].x_advance); |
| + ? glyph_width_for_test_ |
| + : SkFixedToFloat(hb_positions[i].x_advance); |
| // Round run widths if subpixel positioning is off to match native behavior. |
| if (!run->render_params.subpixel_positioning) |
| run->width = std::floor(run->width + 0.5f); |