Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(345)

Side by Side Diff: ui/gfx/render_text.cc

Issue 7458014: Implement Uniscribe RenderText for Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments, re-layout on SetDisplayRect and ApplyDefaultStyle. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 size_t start = sel.selection_start(); 168 size_t start = sel.selection_start();
169 size_t end = sel.selection_end(); 169 size_t end = sel.selection_end();
170 selection_model_.set_selection_start(std::min(start, text().length())); 170 selection_model_.set_selection_start(std::min(start, text().length()));
171 selection_model_.set_selection_end(std::min(end, text().length())); 171 selection_model_.set_selection_end(std::min(end, text().length()));
172 selection_model_.set_caret_pos(std::min(sel.caret_pos(), text().length())); 172 selection_model_.set_caret_pos(std::min(sel.caret_pos(), text().length()));
173 selection_model_.set_caret_placement(sel.caret_placement()); 173 selection_model_.set_caret_placement(sel.caret_placement());
174 174
175 cached_bounds_and_offset_valid_ = false; 175 cached_bounds_and_offset_valid_ = false;
176 } 176 }
177 177
178 void RenderText::ToggleInsertMode() {
179 insert_mode_ = !insert_mode_;
180 cached_bounds_and_offset_valid_ = false;
181 }
182
178 void RenderText::SetDisplayRect(const Rect& r) { 183 void RenderText::SetDisplayRect(const Rect& r) {
179 display_rect_ = r; 184 display_rect_ = r;
180 cached_bounds_and_offset_valid_ = false; 185 cached_bounds_and_offset_valid_ = false;
181 } 186 }
182 187
183 size_t RenderText::GetCursorPosition() const { 188 size_t RenderText::GetCursorPosition() const {
184 return selection_model_.selection_end(); 189 return selection_model_.selection_end();
185 } 190 }
186 191
187 void RenderText::SetCursorPosition(const size_t position) { 192 void RenderText::SetCursorPosition(size_t position) {
188 SelectionModel sel(selection_model()); 193 MoveCursorTo(position, false);
189 sel.set_selection_start(position);
190 sel.set_selection_end(position);
191 sel.set_caret_pos(GetIndexOfPreviousGrapheme(position));
192 sel.set_caret_placement(SelectionModel::TRAILING);
193 SetSelectionModel(sel);
194 } 194 }
195 195
196 void RenderText::MoveCursorLeft(BreakType break_type, bool select) { 196 void RenderText::MoveCursorLeft(BreakType break_type, bool select) {
197 SelectionModel position(selection_model()); 197 SelectionModel position(selection_model());
198 position.set_selection_start(GetCursorPosition()); 198 position.set_selection_start(GetCursorPosition());
199 // Cancelling a selection moves to the edge of the selection. 199 // Cancelling a selection moves to the edge of the selection.
200 if (break_type != LINE_BREAK && !EmptySelection() && !select) { 200 if (break_type != LINE_BREAK && !EmptySelection() && !select) {
201 // Use the selection start if it is left of the selection end. 201 // Use the selection start if it is left of the selection end.
202 SelectionModel selection_start(GetSelectionStart(), GetSelectionStart(), 202 SelectionModel selection_start(GetSelectionStart(), GetSelectionStart(),
203 SelectionModel::LEADING); 203 SelectionModel::LEADING);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 } 244 }
245 245
246 bool RenderText::MoveCursorTo(const Point& point, bool select) { 246 bool RenderText::MoveCursorTo(const Point& point, bool select) {
247 SelectionModel selection = FindCursorPosition(point); 247 SelectionModel selection = FindCursorPosition(point);
248 if (select) 248 if (select)
249 selection.set_selection_start(GetSelectionStart()); 249 selection.set_selection_start(GetSelectionStart());
250 return MoveCursorTo(selection); 250 return MoveCursorTo(selection);
251 } 251 }
252 252
253 bool RenderText::IsPointInSelection(const Point& point) { 253 bool RenderText::IsPointInSelection(const Point& point) {
254 if (EmptySelection())
255 return false;
254 // TODO(xji): should this check whether the point is inside the visual 256 // TODO(xji): should this check whether the point is inside the visual
255 // selection bounds? In case of "abcFED", if "ED" is selected, |point| points 257 // selection bounds? In case of "abcFED", if "ED" is selected, |point| points
256 // to the right half of 'c', is the point in selection? 258 // to the right half of 'c', is the point in selection?
257 size_t pos = FindCursorPosition(point).selection_end(); 259 size_t pos = FindCursorPosition(point).selection_end();
258 return (pos >= MinOfSelection() && pos < MaxOfSelection()); 260 return (pos >= MinOfSelection() && pos < MaxOfSelection());
259 } 261 }
260 262
261 void RenderText::ClearSelection() { 263 void RenderText::ClearSelection() {
262 SelectionModel sel(selection_model()); 264 SelectionModel sel(selection_model());
263 sel.set_selection_start(GetCursorPosition()); 265 sel.set_selection_start(GetCursorPosition());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 } 303 }
302 304
303 // Now we move selection_end_ to end of selection. Selection boundary 305 // Now we move selection_end_ to end of selection. Selection boundary
304 // is defined as the position where we have alpha-num character on one side 306 // is defined as the position where we have alpha-num character on one side
305 // and non-alpha-num char on the other side. 307 // and non-alpha-num char on the other side.
306 for (; cursor_position < text().length(); cursor_position++) { 308 for (; cursor_position < text().length(); cursor_position++) {
307 if (IsPositionAtWordSelectionBoundary(cursor_position)) 309 if (IsPositionAtWordSelectionBoundary(cursor_position))
308 break; 310 break;
309 } 311 }
310 312
311 SelectionModel sel(selection_model()); 313 MoveCursorTo(selection_start, false);
312 sel.set_selection_start(selection_start); 314 MoveCursorTo(cursor_position, true);
313 sel.set_selection_end(cursor_position);
314 sel.set_caret_pos(GetIndexOfPreviousGrapheme(cursor_position));
315 sel.set_caret_placement(SelectionModel::TRAILING);
316 SetSelectionModel(sel);
317 } 315 }
318 316
319 const ui::Range& RenderText::GetCompositionRange() const { 317 const ui::Range& RenderText::GetCompositionRange() const {
320 return composition_range_; 318 return composition_range_;
321 } 319 }
322 320
323 void RenderText::SetCompositionRange(const ui::Range& composition_range) { 321 void RenderText::SetCompositionRange(const ui::Range& composition_range) {
324 CHECK(!composition_range.IsValid() || 322 CHECK(!composition_range.IsValid() ||
325 ui::Range(0, text_.length()).Contains(composition_range)); 323 ui::Range(0, text_.length()).Contains(composition_range));
326 composition_range_.set_end(composition_range.end()); 324 composition_range_.set_end(composition_range.end());
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 // Apply a selection style override to a copy of the style ranges. 567 // Apply a selection style override to a copy of the style ranges.
570 if (!EmptySelection()) { 568 if (!EmptySelection()) {
571 StyleRange selection_style(default_style_); 569 StyleRange selection_style(default_style_);
572 selection_style.foreground = kSelectedTextColor; 570 selection_style.foreground = kSelectedTextColor;
573 selection_style.range.set_start(MinOfSelection()); 571 selection_style.range.set_start(MinOfSelection());
574 selection_style.range.set_end(MaxOfSelection()); 572 selection_style.range.set_end(MaxOfSelection());
575 ApplyStyleRangeImpl(style_ranges, selection_style); 573 ApplyStyleRangeImpl(style_ranges, selection_style);
576 } 574 }
577 } 575 }
578 576
577 void RenderText::MoveCursorTo(size_t position, bool select) {
578 size_t caret_pos = GetIndexOfPreviousGrapheme(position);
579 SelectionModel::CaretPlacement placement = (caret_pos == position) ?
580 SelectionModel::LEADING : SelectionModel::TRAILING;
581 size_t selection_start = select ? GetSelectionStart() : position;
582 SelectionModel sel(selection_start, position, caret_pos, placement);
583 SetSelectionModel(sel);
584 }
585
579 bool RenderText::IsPositionAtWordSelectionBoundary(size_t pos) { 586 bool RenderText::IsPositionAtWordSelectionBoundary(size_t pos) {
580 return pos == 0 || (u_isalnum(text()[pos - 1]) && !u_isalnum(text()[pos])) || 587 return pos == 0 || (u_isalnum(text()[pos - 1]) && !u_isalnum(text()[pos])) ||
581 (!u_isalnum(text()[pos - 1]) && u_isalnum(text()[pos])); 588 (!u_isalnum(text()[pos - 1]) && u_isalnum(text()[pos]));
582 } 589 }
583 590
584 void RenderText::UpdateCachedBoundsAndOffset() { 591 void RenderText::UpdateCachedBoundsAndOffset() {
585 if (cached_bounds_and_offset_valid_) 592 if (cached_bounds_and_offset_valid_)
586 return; 593 return;
587 // First, set the valid flag true to calculate the current cursor bounds using 594 // First, set the valid flag true to calculate the current cursor bounds using
588 // the stale |display_offset_|. Applying |delta_offset| at the end of this 595 // the stale |display_offset_|. Applying |delta_offset| at the end of this
589 // function will set |cursor_bounds_| and |display_offset_| to correct values. 596 // function will set |cursor_bounds_| and |display_offset_| to correct values.
590 cached_bounds_and_offset_valid_ = true; 597 cached_bounds_and_offset_valid_ = true;
591 cursor_bounds_ = GetCursorBounds(selection_model_, insert_mode_); 598 cursor_bounds_ = GetCursorBounds(selection_model_, insert_mode_);
592 cursor_bounds_.set_width(std::max(cursor_bounds_.width(), 1));
593 // Update |display_offset_| to ensure the current cursor is visible. 599 // Update |display_offset_| to ensure the current cursor is visible.
594 int display_width = display_rect_.width(); 600 int display_width = display_rect_.width();
595 int string_width = GetStringWidth(); 601 int string_width = GetStringWidth();
596 int delta_offset = 0; 602 int delta_offset = 0;
597 if (string_width < display_width) { 603 if (string_width < display_width) {
598 // Show all text whenever the text fits to the size. 604 // Show all text whenever the text fits to the size.
599 delta_offset = -display_offset_.x(); 605 delta_offset = -display_offset_.x();
600 } else if (cursor_bounds_.right() > display_rect_.right()) { 606 } else if (cursor_bounds_.right() > display_rect_.right()) {
601 // Pan to show the cursor when it overflows to the right, 607 // Pan to show the cursor when it overflows to the right,
602 delta_offset = display_rect_.right() - cursor_bounds_.right(); 608 delta_offset = display_rect_.right() - cursor_bounds_.right();
603 } else if (cursor_bounds_.x() < display_rect_.x()) { 609 } else if (cursor_bounds_.x() < display_rect_.x()) {
604 // Pan to show the cursor when it overflows to the left. 610 // Pan to show the cursor when it overflows to the left.
605 delta_offset = display_rect_.x() - cursor_bounds_.x(); 611 delta_offset = display_rect_.x() - cursor_bounds_.x();
606 } 612 }
607 display_offset_.Offset(delta_offset, 0); 613 display_offset_.Offset(delta_offset, 0);
608 cursor_bounds_.Offset(delta_offset, 0); 614 cursor_bounds_.Offset(delta_offset, 0);
609 } 615 }
610 616
611 } // namespace gfx 617 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698