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

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

Issue 7841056: fix know issues in RenderText (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: fix a capitalization in break_iterator.h Created 9 years, 3 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
« no previous file with comments | « ui/gfx/render_text_win.h ('k') | views/controls/textfield/native_textfield_views_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_win.h" 5 #include "ui/gfx/render_text_win.h"
6 6
7 #include "base/i18n/break_iterator.h" 7 #include "base/i18n/break_iterator.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 return SelectionModel(0, 0, SelectionModel::LEADING); 230 return SelectionModel(0, 0, SelectionModel::LEADING);
231 size_t cursor = base::i18n::IsRTL() ? 0 : text().length(); 231 size_t cursor = base::i18n::IsRTL() ? 0 : text().length();
232 internal::TextRun* run = runs_[visual_to_logical_[runs_.size() - 1]]; 232 internal::TextRun* run = runs_[visual_to_logical_[runs_.size() - 1]];
233 bool rtl = run->script_analysis.fRTL; 233 bool rtl = run->script_analysis.fRTL;
234 size_t caret = rtl ? run->range.start() : run->range.end() - 1; 234 size_t caret = rtl ? run->range.start() : run->range.end() - 1;
235 SelectionModel::CaretPlacement placement = 235 SelectionModel::CaretPlacement placement =
236 rtl ? SelectionModel::LEADING : SelectionModel::TRAILING; 236 rtl ? SelectionModel::LEADING : SelectionModel::TRAILING;
237 return SelectionModel(cursor, caret, placement); 237 return SelectionModel(cursor, caret, placement);
238 } 238 }
239 239
240 size_t RenderTextWin::GetIndexOfPreviousGrapheme(size_t position) {
241 return IndexOfAdjacentGrapheme(position, false);
242 }
243
244 std::vector<Rect> RenderTextWin::GetSubstringBounds(size_t from, size_t to) { 240 std::vector<Rect> RenderTextWin::GetSubstringBounds(size_t from, size_t to) {
245 ui::Range range(from, to); 241 ui::Range range(from, to);
246 DCHECK(ui::Range(0, text().length()).Contains(range)); 242 DCHECK(ui::Range(0, text().length()).Contains(range));
247 Point display_offset(GetUpdatedDisplayOffset()); 243 Point display_offset(GetUpdatedDisplayOffset());
248 std::vector<Rect> bounds; 244 std::vector<Rect> bounds;
249 HRESULT hr = 0; 245 HRESULT hr = 0;
250 246
251 // Add a Rect for each run/selection intersection. 247 // Add a Rect for each run/selection intersection.
252 // TODO(msw): The bounds should probably not always be leading the range ends. 248 // TODO(msw): The bounds should probably not always be leading the range ends.
253 for (size_t i = 0; i < runs_.size(); ++i) { 249 for (size_t i = 0; i < runs_.size(); ++i) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 if (!bounds.empty() && rect.SharesEdgeWith(bounds.back())) { 284 if (!bounds.empty() && rect.SharesEdgeWith(bounds.back())) {
289 rect = rect.Union(bounds.back()); 285 rect = rect.Union(bounds.back());
290 bounds.pop_back(); 286 bounds.pop_back();
291 } 287 }
292 bounds.push_back(rect); 288 bounds.push_back(rect);
293 } 289 }
294 } 290 }
295 return bounds; 291 return bounds;
296 } 292 }
297 293
294 bool RenderTextWin::IsCursorablePosition(size_t position) {
295 if (position == 0 || position == text().length())
296 return true;
297
298 size_t run_index = GetRunContainingPosition(position);
299 if (run_index >= runs_.size())
300 return false;
301
302 internal::TextRun* run = runs_[run_index];
303 size_t start = run->range.start();
304 if (position == start)
305 return true;
306 return run->logical_clusters[position - start] !=
307 run->logical_clusters[position - start - 1];
308 }
309
310 size_t RenderTextWin::IndexOfAdjacentGrapheme(size_t index, bool next) {
311 size_t run_index = GetRunContainingPosition(index);
312 internal::TextRun* run = run_index < runs_.size() ? runs_[run_index] : NULL;
313 long start = run ? run->range.start() : 0;
314 long length = run ? run->range.length() : text().length();
315 long ch = index - start;
316 WORD cluster = run ? run->logical_clusters[ch] : 0;
317
318 if (!next) {
319 do {
320 ch--;
321 } while (ch >= 0 && run && run->logical_clusters[ch] == cluster);
322 } else {
323 while (ch < length && run && run->logical_clusters[ch] == cluster)
324 ch++;
325 }
326 return std::max(static_cast<long>(std::min(ch, length) + start), 0L);
327 }
328
298 void RenderTextWin::ItemizeLogicalText() { 329 void RenderTextWin::ItemizeLogicalText() {
299 text_is_dirty_ = false; 330 text_is_dirty_ = false;
300 STLDeleteContainerPointers(runs_.begin(), runs_.end()); 331 STLDeleteContainerPointers(runs_.begin(), runs_.end());
301 runs_.clear(); 332 runs_.clear();
302 if (text().empty()) 333 if (text().empty())
303 return; 334 return;
304 335
305 const wchar_t* raw_text = text().c_str(); 336 const wchar_t* raw_text = text().c_str();
306 const int text_length = text().length(); 337 const int text_length = text().length();
307 338
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 size_t RenderTextWin::GetRunContainingPoint(const Point& point) const { 485 size_t RenderTextWin::GetRunContainingPoint(const Point& point) const {
455 // Find the text run containing the argument point (assumed already offset). 486 // Find the text run containing the argument point (assumed already offset).
456 size_t run = 0; 487 size_t run = 0;
457 for (; run < runs_.size(); ++run) 488 for (; run < runs_.size(); ++run)
458 if (runs_[run]->preceding_run_widths <= point.x() && 489 if (runs_[run]->preceding_run_widths <= point.x() &&
459 runs_[run]->preceding_run_widths + runs_[run]->width > point.x()) 490 runs_[run]->preceding_run_widths + runs_[run]->width > point.x())
460 break; 491 break;
461 return run; 492 return run;
462 } 493 }
463 494
464 size_t RenderTextWin::IndexOfAdjacentGrapheme(size_t index, bool next) const {
465 size_t run_index = GetRunContainingPosition(index);
466 internal::TextRun* run = run_index < runs_.size() ? runs_[run_index] : NULL;
467 long start = run ? run->range.start() : 0;
468 long length = run ? run->range.length() : text().length();
469 long ch = index - start;
470 WORD cluster = run ? run->logical_clusters[ch] : 0;
471
472 if (!next) {
473 do {
474 ch--;
475 } while (ch >= 0 && run && run->logical_clusters[ch] == cluster);
476 } else {
477 while (ch < length && run && run->logical_clusters[ch] == cluster)
478 ch++;
479 }
480 return std::max(static_cast<long>(std::min(ch, length) + start), 0L);
481 }
482 495
483 SelectionModel RenderTextWin::FirstSelectionModelInsideRun( 496 SelectionModel RenderTextWin::FirstSelectionModelInsideRun(
484 internal::TextRun* run) const { 497 internal::TextRun* run) {
485 size_t caret = run->range.start(); 498 size_t caret = run->range.start();
486 size_t cursor = IndexOfAdjacentGrapheme(caret, true); 499 size_t cursor = IndexOfAdjacentGrapheme(caret, true);
487 return SelectionModel(cursor, caret, SelectionModel::TRAILING); 500 return SelectionModel(cursor, caret, SelectionModel::TRAILING);
488 } 501 }
489 502
490 SelectionModel RenderTextWin::LastSelectionModelInsideRun( 503 SelectionModel RenderTextWin::LastSelectionModelInsideRun(
491 internal::TextRun* run) const { 504 internal::TextRun* run) {
492 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), false); 505 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), false);
493 return SelectionModel(caret, caret, SelectionModel::LEADING); 506 return SelectionModel(caret, caret, SelectionModel::LEADING);
494 } 507 }
495 508
496 SelectionModel RenderTextWin::LeftSelectionModel( 509 SelectionModel RenderTextWin::LeftSelectionModel(
497 const SelectionModel& selection) { 510 const SelectionModel& selection) {
498 size_t caret = selection.caret_pos(); 511 size_t caret = selection.caret_pos();
499 SelectionModel::CaretPlacement caret_placement = selection.caret_placement(); 512 SelectionModel::CaretPlacement caret_placement = selection.caret_placement();
500 size_t run_index = GetRunContainingPosition(caret); 513 size_t run_index = GetRunContainingPosition(caret);
501 DCHECK(run_index < runs_.size()); 514 DCHECK(run_index < runs_.size());
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 Rect r(GetUpdatedCursorBounds()); 662 Rect r(GetUpdatedCursorBounds());
650 canvas->DrawRectInt(kCursorColor, r.x(), r.y(), r.width(), r.height()); 663 canvas->DrawRectInt(kCursorColor, r.x(), r.y(), r.width(), r.height());
651 } 664 }
652 } 665 }
653 666
654 RenderText* RenderText::CreateRenderText() { 667 RenderText* RenderText::CreateRenderText() {
655 return new RenderTextWin; 668 return new RenderTextWin;
656 } 669 }
657 670
658 } // namespace gfx 671 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/render_text_win.h ('k') | views/controls/textfield/native_textfield_views_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698