OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gfx/render_text.h" | 5 #include "ui/gfx/render_text.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/i18n/break_iterator.h" | 9 #include "base/i18n/break_iterator.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
12 #include "third_party/skia/include/core/SkTypeface.h" | |
12 #include "ui/gfx/canvas.h" | 13 #include "ui/gfx/canvas.h" |
13 #include "ui/gfx/canvas_skia.h" | 14 #include "ui/gfx/canvas_skia.h" |
14 #include "unicode/uchar.h" | 15 #include "unicode/uchar.h" |
15 | 16 |
16 namespace { | 17 namespace { |
17 | 18 |
18 #ifndef NDEBUG | 19 #ifndef NDEBUG |
19 // Check StyleRanges invariant conditions: sorted and non-overlapping ranges. | 20 // Check StyleRanges invariant conditions: sorted and non-overlapping ranges. |
20 void CheckStyleRanges(const gfx::StyleRanges& style_ranges, size_t length) { | 21 void CheckStyleRanges(const gfx::StyleRanges& style_ranges, size_t length) { |
21 if (length == 0) { | 22 if (length == 0) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
71 NOTREACHED(); | 72 NOTREACHED(); |
72 } | 73 } |
73 // Add the new range in its sorted location. | 74 // Add the new range in its sorted location. |
74 style_ranges->insert(i, style_range); | 75 style_ranges->insert(i, style_range); |
75 } | 76 } |
76 | 77 |
77 } // namespace | 78 } // namespace |
78 | 79 |
79 namespace gfx { | 80 namespace gfx { |
80 | 81 |
82 namespace internal { | |
83 | |
84 SkiaTextRenderer::SkiaTextRenderer(Canvas* canvas) | |
85 : canvas_skia_(canvas->GetSkCanvas()) { | |
86 DCHECK(canvas_skia_); | |
87 paint_.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | |
88 paint_.setStyle(SkPaint::kFill_Style); | |
89 paint_.setAntiAlias(true); | |
90 paint_.setSubpixelText(true); | |
91 //paint_.setLCDRenderText(true); | |
msw
2011/12/08 19:40:27
Did you mean to comment this out?
| |
92 } | |
93 | |
94 SkiaTextRenderer::~SkiaTextRenderer() { | |
95 } | |
96 | |
97 void SkiaTextRenderer::SetFont(const gfx::Font& font) { | |
98 SkAutoTUnref<SkTypeface> typeface( | |
99 SkTypeface::CreateFromName(font.GetFontName().c_str(), | |
100 SkTypeface::kNormal)); | |
101 if (typeface.get()) { | |
102 // |paint_| adds its own ref. So don't |release()| it from the ref ptr here. | |
103 paint_.setTypeface(typeface.get()); | |
104 } | |
105 paint_.setTextSize(font.GetFontSize()); | |
106 } | |
107 | |
108 void SkiaTextRenderer::SetForegroundColor(SkColor foreground) { | |
109 paint_.setColor(foreground); | |
110 } | |
111 | |
112 void SkiaTextRenderer::DrawPosText(const SkPoint* pos, | |
113 const uint16* glyphs, | |
114 size_t glyph_count) { | |
115 size_t byte_length = glyph_count * sizeof(glyphs[0]); | |
116 canvas_skia_->drawPosText(&glyphs[0], byte_length, &pos[0], paint_); | |
117 } | |
118 | |
119 // Draw underline and strike through text decorations. | |
120 // Based on |SkCanvas::DrawTextDecorations()| and constants from: | |
121 // third_party/skia/src/core/SkTextFormatParams.h | |
122 void SkiaTextRenderer::DrawDecorations(int x, int y, int width, | |
123 bool underline, bool strike) { | |
124 // Fraction of the text size to lower a strike through below the baseline. | |
125 const SkScalar kStrikeThroughOffset = (-SK_Scalar1 * 6 / 21); | |
126 // Fraction of the text size to lower an underline below the baseline. | |
127 const SkScalar kUnderlineOffset = (SK_Scalar1 / 9); | |
128 // Fraction of the text size to use for a strike through or under-line. | |
129 const SkScalar kLineThickness = (SK_Scalar1 / 18); | |
130 | |
131 SkScalar text_size = paint_.getTextSize(); | |
132 SkScalar height = SkScalarMul(text_size, kLineThickness); | |
133 SkRect r; | |
134 | |
135 r.fLeft = x; | |
136 r.fRight = x + width; | |
137 | |
138 if (underline) { | |
139 SkScalar offset = SkScalarMulAdd(text_size, kUnderlineOffset, y); | |
140 r.fTop = offset; | |
141 r.fBottom = offset + height; | |
142 canvas_skia_->drawRect(r, paint_); | |
143 } | |
144 if (strike) { | |
145 SkScalar offset = SkScalarMulAdd(text_size, kStrikeThroughOffset, y); | |
146 r.fTop = offset; | |
147 r.fBottom = offset + height; | |
148 canvas_skia_->drawRect(r, paint_); | |
149 } | |
150 } | |
151 | |
152 } // namespace internal | |
153 | |
154 | |
81 StyleRange::StyleRange() | 155 StyleRange::StyleRange() |
82 : font(), | 156 : font(), |
83 foreground(SK_ColorBLACK), | 157 foreground(SK_ColorBLACK), |
84 strike(false), | 158 strike(false), |
85 underline(false), | 159 underline(false), |
86 range() { | 160 range() { |
87 } | 161 } |
88 | 162 |
89 RenderText::~RenderText() { | 163 RenderText::~RenderText() { |
90 } | 164 } |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
549 } | 623 } |
550 | 624 |
551 Point RenderText::ToViewPoint(const Point& point) { | 625 Point RenderText::ToViewPoint(const Point& point) { |
552 Point p(point.Add(display_rect().origin())); | 626 Point p(point.Add(display_rect().origin())); |
553 p = p.Add(GetUpdatedDisplayOffset()); | 627 p = p.Add(GetUpdatedDisplayOffset()); |
554 if (base::i18n::IsRTL()) | 628 if (base::i18n::IsRTL()) |
555 p.Offset(display_rect().width() - GetStringWidth() - 1, 0); | 629 p.Offset(display_rect().width() - GetStringWidth() - 1, 0); |
556 return p; | 630 return p; |
557 } | 631 } |
558 | 632 |
633 Point RenderText::GetOriginForSkiaDrawing() { | |
634 Point origin(ToViewPoint(Point())); | |
635 // TODO(msw): Establish a vertical baseline for strings of mixed font heights. | |
636 const Font& font = default_style().font; | |
637 size_t height = font.GetHeight(); | |
638 // Center the text vertically in the display area. | |
639 origin.Offset(0, (display_rect().height() - height) / 2); | |
640 // Offset by the font size to account for Skia expecting y to be the bottom. | |
641 origin.Offset(0, font.GetFontSize()); | |
642 return origin; | |
643 } | |
644 | |
559 void RenderText::MoveCursorTo(size_t position, bool select) { | 645 void RenderText::MoveCursorTo(size_t position, bool select) { |
560 size_t cursor = std::min(position, text().length()); | 646 size_t cursor = std::min(position, text().length()); |
561 size_t caret_pos = GetIndexOfPreviousGrapheme(cursor); | 647 size_t caret_pos = GetIndexOfPreviousGrapheme(cursor); |
562 SelectionModel::CaretPlacement placement = (caret_pos == cursor) ? | 648 SelectionModel::CaretPlacement placement = (caret_pos == cursor) ? |
563 SelectionModel::LEADING : SelectionModel::TRAILING; | 649 SelectionModel::LEADING : SelectionModel::TRAILING; |
564 size_t selection_start = select ? GetSelectionStart() : cursor; | 650 size_t selection_start = select ? GetSelectionStart() : cursor; |
565 if (IsCursorablePosition(cursor)) { | 651 if (IsCursorablePosition(cursor)) { |
566 SelectionModel sel(selection_start, cursor, caret_pos, placement); | 652 SelectionModel sel(selection_start, cursor, caret_pos, placement); |
567 SetSelectionModel(sel); | 653 SetSelectionModel(sel); |
568 } | 654 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
612 void RenderText::DrawCursor(Canvas* canvas) { | 698 void RenderText::DrawCursor(Canvas* canvas) { |
613 // Paint cursor. Replace cursor is drawn as rectangle for now. | 699 // Paint cursor. Replace cursor is drawn as rectangle for now. |
614 // TODO(msw): Draw a better cursor with a better indication of association. | 700 // TODO(msw): Draw a better cursor with a better indication of association. |
615 if (cursor_visible() && focused()) { | 701 if (cursor_visible() && focused()) { |
616 Rect r(GetUpdatedCursorBounds()); | 702 Rect r(GetUpdatedCursorBounds()); |
617 canvas->DrawRectInt(kCursorColor, r.x(), r.y(), r.width(), r.height()); | 703 canvas->DrawRectInt(kCursorColor, r.x(), r.y(), r.width(), r.height()); |
618 } | 704 } |
619 } | 705 } |
620 | 706 |
621 } // namespace gfx | 707 } // namespace gfx |
OLD | NEW |