Chromium Code Reviews| Index: ui/gfx/render_text_win.cc |
| =================================================================== |
| --- ui/gfx/render_text_win.cc (revision 111848) |
| +++ ui/gfx/render_text_win.cc (working copy) |
| @@ -171,12 +171,6 @@ |
| return string_width_; |
| } |
| -void RenderTextWin::Draw(Canvas* canvas) { |
|
Alexei Svitkine (slow)
2011/11/29 15:41:37
I have a CL that adds an EnsureLayout() call here:
xji
2011/11/29 23:07:15
Done. And I made EnsureLayout() to base too.
|
| - DrawSelection(canvas); |
| - DrawVisualText(canvas); |
| - DrawCursor(canvas); |
| -} |
| - |
| SelectionModel RenderTextWin::FindCursorPosition(const Point& point) { |
| if (text().empty()) |
| return SelectionModel(); |
| @@ -305,12 +299,14 @@ |
| return SelectionModel(cursor, caret, placement); |
| } |
| -std::vector<Rect> RenderTextWin::GetSubstringBounds(size_t from, size_t to) { |
| +void RenderTextWin::GetSubstringBounds(size_t from, |
| + size_t to, |
| + std::vector<Rect>* bounds) { |
| ui::Range range(from, to); |
| DCHECK(ui::Range(0, text().length()).Contains(range)); |
| Point display_offset(GetUpdatedDisplayOffset()); |
| - std::vector<Rect> bounds; |
| HRESULT hr = 0; |
| + bounds->clear(); |
| // Add a Rect for each run/selection intersection. |
| // TODO(msw): The bounds should probably not always be leading the range ends. |
| @@ -349,14 +345,14 @@ |
| rect.Offset(0, (display_rect().height() - rect.height()) / 2); |
| rect.set_origin(ToViewPoint(rect.origin())); |
| // Union this with the last rect if they're adjacent. |
| - if (!bounds.empty() && rect.SharesEdgeWith(bounds.back())) { |
| - rect = rect.Union(bounds.back()); |
| - bounds.pop_back(); |
| + if (!bounds->empty() && rect.SharesEdgeWith(bounds->back())) { |
| + rect = rect.Union(bounds->back()); |
| + bounds->pop_back(); |
| } |
| - bounds.push_back(rect); |
| + bounds->push_back(rect); |
| } |
| } |
| - return bounds; |
| + return; |
| } |
| bool RenderTextWin::IsCursorablePosition(size_t position) { |
| @@ -382,6 +378,65 @@ |
| LayoutVisualText(); |
| } |
| +void RenderTextWin::DrawVisualText(Canvas* canvas) { |
| + if (text().empty()) |
| + return; |
| + |
| + SkCanvas* canvas_skia = canvas->GetSkCanvas(); |
| + |
| + Point offset(ToViewPoint(Point())); |
| + // TODO(msw): Establish a vertical baseline for strings of mixed font heights. |
| + size_t height = default_style().font.GetHeight(); |
| + |
| + SkScalar x = SkIntToScalar(offset.x()); |
| + SkScalar y = SkIntToScalar(offset.y()); |
| + // Center the text vertically in the display area. |
| + y += (display_rect().height() - height) / 2; |
| + // Offset by the font size to account for Skia expecting y to be the bottom. |
| + y += default_style().font.GetFontSize(); |
| + |
| + SkPaint paint; |
| + paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
| + paint.setStyle(SkPaint::kFill_Style); |
| + paint.setAntiAlias(true); |
| + paint.setSubpixelText(true); |
| + paint.setLCDRenderText(true); |
| + |
| + std::vector<SkPoint> pos; |
| + for (size_t i = 0; i < runs_.size(); ++i) { |
| + // Get the run specified by the visual-to-logical map. |
| + internal::TextRun* run = runs_[visual_to_logical_[i]]; |
| + |
| + // TODO(msw): Font default/fallback and style integration. |
| + SkTypeface::Style style = SkTypeface::kNormal; |
| + SkTypeface* typeface = |
| + SkTypeface::CreateFromName(run->font.GetFontName().c_str(), style); |
| + if (typeface) { |
| + paint.setTypeface(typeface); |
| + // |paint| adds its own ref. Release the ref from CreateFromName. |
| + typeface->unref(); |
| + } |
| + paint.setTextSize(run->font.GetFontSize()); |
| + paint.setColor(run->foreground); |
| + |
| + SkScalar run_x = x; |
| + |
| + // Based on WebCore::skiaDrawText. |
| + pos.resize(run->glyph_count); |
| + for (int glyph = 0; glyph < run->glyph_count; glyph++) { |
| + pos[glyph].set(x + run->offsets[glyph].du, |
| + y + run->offsets[glyph].dv); |
| + x += SkIntToScalar(run->advance_widths[glyph]); |
| + } |
| + |
| + size_t byte_length = run->glyph_count * sizeof(WORD); |
| + canvas_skia->drawPosText(run->glyphs.get(), byte_length, &pos[0], paint); |
| + |
| + if (run->strike || run->underline) |
| + DrawTextRunDecorations(canvas_skia, paint, *run, run_x, y); |
| + } |
| +} |
| + |
| size_t RenderTextWin::IndexOfAdjacentGrapheme(size_t index, bool next) { |
| size_t run_index = GetRunContainingPosition(index); |
| internal::TextRun* run = run_index < runs_.size() ? runs_[run_index] : NULL; |
| @@ -660,82 +715,6 @@ |
| FirstSelectionModelInsideRun(next); |
| } |
| -void RenderTextWin::DrawSelection(Canvas* canvas) { |
| - std::vector<Rect> sel( |
| - GetSubstringBounds(GetSelectionStart(), GetCursorPosition())); |
| - SkColor color = focused() ? kFocusedSelectionColor : kUnfocusedSelectionColor; |
| - for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) |
| - canvas->FillRect(color, *i); |
| -} |
| - |
| -void RenderTextWin::DrawVisualText(Canvas* canvas) { |
| - if (text().empty()) |
| - return; |
| - |
| - SkCanvas* canvas_skia = canvas->GetSkCanvas(); |
| - |
| - Point offset(ToViewPoint(Point())); |
| - // TODO(msw): Establish a vertical baseline for strings of mixed font heights. |
| - size_t height = default_style().font.GetHeight(); |
| - |
| - SkScalar x = SkIntToScalar(offset.x()); |
| - SkScalar y = SkIntToScalar(offset.y()); |
| - // Center the text vertically in the display area. |
| - y += (display_rect().height() - height) / 2; |
| - // Offset by the font size to account for Skia expecting y to be the bottom. |
| - y += default_style().font.GetFontSize(); |
| - |
| - SkPaint paint; |
| - paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
| - paint.setStyle(SkPaint::kFill_Style); |
| - paint.setAntiAlias(true); |
| - paint.setSubpixelText(true); |
| - paint.setLCDRenderText(true); |
| - |
| - std::vector<SkPoint> pos; |
| - for (size_t i = 0; i < runs_.size(); ++i) { |
| - // Get the run specified by the visual-to-logical map. |
| - internal::TextRun* run = runs_[visual_to_logical_[i]]; |
| - |
| - // TODO(msw): Font default/fallback and style integration. |
| - SkTypeface::Style style = SkTypeface::kNormal; |
| - SkTypeface* typeface = |
| - SkTypeface::CreateFromName(run->font.GetFontName().c_str(), style); |
| - if (typeface) { |
| - paint.setTypeface(typeface); |
| - // |paint| adds its own ref. Release the ref from CreateFromName. |
| - typeface->unref(); |
| - } |
| - paint.setTextSize(run->font.GetFontSize()); |
| - paint.setColor(run->foreground); |
| - |
| - SkScalar run_x = x; |
| - |
| - // Based on WebCore::skiaDrawText. |
| - pos.resize(run->glyph_count); |
| - for (int glyph = 0; glyph < run->glyph_count; glyph++) { |
| - pos[glyph].set(x + run->offsets[glyph].du, |
| - y + run->offsets[glyph].dv); |
| - x += SkIntToScalar(run->advance_widths[glyph]); |
| - } |
| - |
| - size_t byte_length = run->glyph_count * sizeof(WORD); |
| - canvas_skia->drawPosText(run->glyphs.get(), byte_length, &pos[0], paint); |
| - |
| - if (run->strike || run->underline) |
| - DrawTextRunDecorations(canvas_skia, paint, *run, run_x, y); |
| - } |
| -} |
| - |
| -void RenderTextWin::DrawCursor(Canvas* canvas) { |
| - // Paint cursor. Replace cursor is drawn as rectangle for now. |
| - // TODO(msw): Draw a better cursor with a better indication of association. |
| - if (cursor_visible() && focused()) { |
| - Rect r(GetUpdatedCursorBounds()); |
| - canvas->DrawRectInt(kCursorColor, r.x(), r.y(), r.width(), r.height()); |
| - } |
| -} |
| - |
| RenderText* RenderText::CreateRenderText() { |
| return new RenderTextWin; |
| } |