summaryrefslogtreecommitdiffstats
path: root/ui/gfx/render_text.cc
diff options
context:
space:
mode:
authorxji@chromium.org <xji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-30 10:18:42 +0000
committerxji@chromium.org <xji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-30 10:18:42 +0000
commit6002a4f38fa52c3d5ffafff7af5c80b3620f2b69 (patch)
tree55db03775c4538e277df212413f6acce28513c8d /ui/gfx/render_text.cc
parentcb66c5afe08ffd1bc5e5a3602e14bad192d79c31 (diff)
downloadchromium_src-6002a4f38fa52c3d5ffafff7af5c80b3620f2b69.zip
chromium_src-6002a4f38fa52c3d5ffafff7af5c80b3620f2b69.tar.gz
chromium_src-6002a4f38fa52c3d5ffafff7af5c80b3620f2b69.tar.bz2
Separate selection highlight from pango layout, highlight selection using skia.
Cache substring bounds to avoid unnecessary g_free. Consolidate drawing functions with RenderTextWin. Remove UpdateLayout() from RenderText::SetSelectionModel(). BUG=103647 TEST=TextfieldViewModelTest; Manual test selection highlight on bidi text. (Do not really know how to test "fi" ligature part. But since the selection highlight is not done by using pango attribute, I would assume that solves the problem). Review URL: http://codereview.chromium.org/8536047 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112188 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gfx/render_text.cc')
-rw-r--r--ui/gfx/render_text.cc121
1 files changed, 37 insertions, 84 deletions
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
index c3d9b6f..696a4f0 100644
--- a/ui/gfx/render_text.cc
+++ b/ui/gfx/render_text.cc
@@ -123,6 +123,8 @@ void RenderText::SetText(const string16& text) {
// Reset selection model. SetText should always followed by SetSelectionModel
// or SetCursorPosition in upper layer.
SetSelectionModel(SelectionModel(0, 0, SelectionModel::LEADING));
+
+ UpdateLayout();
}
void RenderText::ToggleInsertMode() {
@@ -344,57 +346,13 @@ int RenderText::GetStringWidth() {
}
void RenderText::Draw(Canvas* canvas) {
- // Clip the canvas to the text display area.
- canvas->ClipRect(display_rect_);
-
- // Draw the selection.
- std::vector<Rect> selection(GetSubstringBounds(GetSelectionStart(),
- GetCursorPosition()));
- SkColor selection_color =
- focused() ? kFocusedSelectionColor : kUnfocusedSelectionColor;
- for (std::vector<Rect>::const_iterator i = selection.begin();
- i < selection.end(); ++i) {
- Rect r(*i);
- canvas->FillRect(selection_color, r);
- }
-
- // Create a temporary copy of the style ranges for composition and selection.
- StyleRanges style_ranges(style_ranges_);
- ApplyCompositionAndSelectionStyles(&style_ranges);
-
- // Draw the text.
- Rect bounds(display_rect_);
- bounds.Offset(GetUpdatedDisplayOffset());
- for (StyleRanges::const_iterator i = style_ranges.begin();
- i < style_ranges.end(); ++i) {
- const Font& font = !i->underline ? i->font :
- i->font.DeriveFont(0, i->font.GetStyle() | Font::UNDERLINED);
- string16 text = text_.substr(i->range.start(), i->range.length());
- bounds.set_width(font.GetStringWidth(text));
- canvas->DrawStringInt(text, font, i->foreground, bounds);
-
- // Draw the strikethrough.
- if (i->strike) {
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setStyle(SkPaint::kFill_Style);
- paint.setColor(i->foreground);
- paint.setStrokeWidth(kStrikeWidth);
- canvas->GetSkCanvas()->drawLine(SkIntToScalar(bounds.x()),
- SkIntToScalar(bounds.bottom()),
- SkIntToScalar(bounds.right()),
- SkIntToScalar(bounds.y()),
- paint);
- }
+ EnsureLayout();
- bounds.set_x(bounds.x() + bounds.width());
+ if (!text().empty()) {
+ DrawSelection(canvas);
+ DrawVisualText(canvas);
}
-
- // Paint cursor. Replace cursor is drawn as rectangle for now.
- Rect cursor(GetUpdatedCursorBounds());
- if (cursor_visible() && focused())
- canvas->DrawRectInt(kCursorColor, cursor.x(), cursor.y(),
- cursor.width(), cursor.height());
+ DrawCursor(canvas);
}
SelectionModel RenderText::FindCursorPosition(const Point& point) {
@@ -426,13 +384,6 @@ SelectionModel RenderText::FindCursorPosition(const Point& point) {
return SelectionModel(left_pos);
}
-Rect RenderText::GetCursorBounds(const SelectionModel& selection,
- bool insert_mode) {
- size_t from = selection.selection_end();
- size_t to = insert_mode ? from : std::min(text_.length(), from + 1);
- return GetSubstringBounds(from, to)[0];
-}
-
const Rect& RenderText::GetUpdatedCursorBounds() {
UpdateCachedBoundsAndOffset();
return cursor_bounds_;
@@ -549,22 +500,21 @@ SelectionModel RenderText::RightEndSelectionModel() {
return SelectionModel(cursor, caret_pos, placement);
}
-size_t RenderText::GetIndexOfPreviousGrapheme(size_t position) {
- return IndexOfAdjacentGrapheme(position, false);
+void RenderText::SetSelectionModel(const SelectionModel& model) {
+ DCHECK_LE(model.selection_start(), text().length());
+ selection_model_.set_selection_start(model.selection_start());
+ DCHECK_LE(model.selection_end(), text().length());
+ selection_model_.set_selection_end(model.selection_end());
+ DCHECK_LT(model.caret_pos(),
+ std::max(text().length(), static_cast<size_t>(1)));
+ selection_model_.set_caret_pos(model.caret_pos());
+ selection_model_.set_caret_placement(model.caret_placement());
+
+ cached_bounds_and_offset_valid_ = false;
}
-std::vector<Rect> RenderText::GetSubstringBounds(size_t from, size_t to) {
- size_t start = std::min(from, to);
- size_t end = std::max(from, to);
- const Font& font = default_style_.font;
- int start_x = font.GetStringWidth(text().substr(0, start));
- int end_x = font.GetStringWidth(text().substr(0, end));
- Rect rect(start_x, 0, end_x - start_x, font.GetHeight());
- rect.Offset(display_rect_.origin());
- rect.Offset(GetUpdatedDisplayOffset());
- // Center the rect vertically in |display_rect_|.
- rect.Offset(Point(0, (display_rect_.height() - rect.height()) / 2));
- return std::vector<Rect>(1, rect);
+size_t RenderText::GetIndexOfPreviousGrapheme(size_t position) {
+ return IndexOfAdjacentGrapheme(position, false);
}
void RenderText::ApplyCompositionAndSelectionStyles(
@@ -605,20 +555,6 @@ Point RenderText::ToViewPoint(const Point& point) {
return p;
}
-void RenderText::SetSelectionModel(const SelectionModel& selection_model) {
- DCHECK_LE(selection_model.selection_start(), text().length());
- selection_model_.set_selection_start(selection_model.selection_start());
- DCHECK_LE(selection_model.selection_end(), text().length());
- selection_model_.set_selection_end(selection_model.selection_end());
- DCHECK_LT(selection_model.caret_pos(),
- std::max(text().length(), static_cast<size_t>(1)));
- selection_model_.set_caret_pos(selection_model.caret_pos());
- selection_model_.set_caret_placement(selection_model.caret_placement());
-
- cached_bounds_and_offset_valid_ = false;
- UpdateLayout();
-}
-
void RenderText::MoveCursorTo(size_t position, bool select) {
size_t cursor = std::min(position, text().length());
size_t caret_pos = GetIndexOfPreviousGrapheme(cursor);
@@ -664,4 +600,21 @@ void RenderText::UpdateCachedBoundsAndOffset() {
cursor_bounds_.Offset(delta_offset, 0);
}
+void RenderText::DrawSelection(Canvas* canvas) {
+ std::vector<Rect> sel;
+ GetSubstringBounds(GetSelectionStart(), GetCursorPosition(), &sel);
+ SkColor color = focused() ? kFocusedSelectionColor : kUnfocusedSelectionColor;
+ for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i)
+ canvas->FillRect(color, *i);
+}
+
+void RenderText::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());
+ }
+}
+
} // namespace gfx