| Index: ui/gfx/render_text_win.cc
|
| ===================================================================
|
| --- ui/gfx/render_text_win.cc (revision 112051)
|
| +++ ui/gfx/render_text_win.cc (working copy)
|
| @@ -173,13 +173,6 @@
|
| return string_width_;
|
| }
|
|
|
| -void RenderTextWin::Draw(Canvas* canvas) {
|
| - EnsureLayout();
|
| - DrawSelection(canvas);
|
| - DrawVisualText(canvas);
|
| - DrawCursor(canvas);
|
| -}
|
| -
|
| SelectionModel RenderTextWin::FindCursorPosition(const Point& point) {
|
| if (text().empty())
|
| return SelectionModel();
|
| @@ -319,14 +312,19 @@
|
| 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) {
|
| DCHECK(!needs_layout_);
|
| 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();
|
| + if (from == to)
|
| + return;
|
| +
|
| // Add a Rect for each run/selection intersection.
|
| // TODO(msw): The bounds should probably not always be leading the range ends.
|
| for (size_t i = 0; i < runs_.size(); ++i) {
|
| @@ -364,14 +362,13 @@
|
| 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;
|
| }
|
|
|
| bool RenderTextWin::IsCursorablePosition(size_t position) {
|
| @@ -396,6 +393,72 @@
|
| needs_layout_ = true;
|
| }
|
|
|
| +void RenderTextWin::EnsureLayout() {
|
| + if (!needs_layout_)
|
| + return;
|
| + // TODO(msw): Skip complex processing if ScriptIsComplex returns false.
|
| + ItemizeLogicalText();
|
| + if (!runs_.empty())
|
| + LayoutVisualText();
|
| + needs_layout_ = false;
|
| +}
|
| +
|
| +void RenderTextWin::DrawVisualText(Canvas* canvas) {
|
| + 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) {
|
| EnsureLayout();
|
| size_t run_index = GetRunContainingPosition(index);
|
| @@ -416,16 +479,6 @@
|
| return std::max(std::min(ch, length) + start, 0);
|
| }
|
|
|
| -void RenderTextWin::EnsureLayout() {
|
| - if (!needs_layout_)
|
| - return;
|
| - // TODO(msw): Skip complex processing if ScriptIsComplex returns false.
|
| - ItemizeLogicalText();
|
| - if (!runs_.empty())
|
| - LayoutVisualText();
|
| - needs_layout_ = false;
|
| -}
|
| -
|
| void RenderTextWin::ItemizeLogicalText() {
|
| STLDeleteContainerPointers(runs_.begin(), runs_.end());
|
| runs_.clear();
|
| @@ -690,82 +743,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;
|
| }
|
|
|