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

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 Win test failure 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
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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 size_t RenderTextWin::GetRunContainingPoint(const Point& point) const { 473 size_t RenderTextWin::GetRunContainingPoint(const Point& point) const {
443 // Find the text run containing the argument point (assumed already offset). 474 // Find the text run containing the argument point (assumed already offset).
444 size_t run = 0; 475 size_t run = 0;
445 for (; run < runs_.size(); ++run) 476 for (; run < runs_.size(); ++run)
446 if (runs_[run]->preceding_run_widths <= point.x() && 477 if (runs_[run]->preceding_run_widths <= point.x() &&
447 runs_[run]->preceding_run_widths + runs_[run]->width > point.x()) 478 runs_[run]->preceding_run_widths + runs_[run]->width > point.x())
448 break; 479 break;
449 return run; 480 return run;
450 } 481 }
451 482
452 size_t RenderTextWin::IndexOfAdjacentGrapheme(size_t index, bool next) const {
453 size_t run_index = GetRunContainingPosition(index);
454 internal::TextRun* run = run_index < runs_.size() ? runs_[run_index] : NULL;
455 long start = run ? run->range.start() : 0;
456 long length = run ? run->range.length() : text().length();
457 long ch = index - start;
458 WORD cluster = run ? run->logical_clusters[ch] : 0;
459
460 if (!next) {
461 do {
462 ch--;
463 } while (ch >= 0 && run && run->logical_clusters[ch] == cluster);
464 } else {
465 while (ch < length && run && run->logical_clusters[ch] == cluster)
466 ch++;
467 }
468 return std::max(static_cast<long>(std::min(ch, length) + start), 0L);
469 }
470 483
471 SelectionModel RenderTextWin::FirstSelectionModelInsideRun( 484 SelectionModel RenderTextWin::FirstSelectionModelInsideRun(
472 internal::TextRun* run) const { 485 internal::TextRun* run) {
473 size_t caret = run->range.start(); 486 size_t caret = run->range.start();
474 size_t cursor = IndexOfAdjacentGrapheme(caret, true); 487 size_t cursor = IndexOfAdjacentGrapheme(caret, true);
475 return SelectionModel(cursor, caret, SelectionModel::TRAILING); 488 return SelectionModel(cursor, caret, SelectionModel::TRAILING);
476 } 489 }
477 490
478 SelectionModel RenderTextWin::LastSelectionModelInsideRun( 491 SelectionModel RenderTextWin::LastSelectionModelInsideRun(
479 internal::TextRun* run) const { 492 internal::TextRun* run) {
480 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), false); 493 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), false);
481 return SelectionModel(caret, caret, SelectionModel::LEADING); 494 return SelectionModel(caret, caret, SelectionModel::LEADING);
482 } 495 }
483 496
484 SelectionModel RenderTextWin::LeftSelectionModel( 497 SelectionModel RenderTextWin::LeftSelectionModel(
485 const SelectionModel& selection) { 498 const SelectionModel& selection) {
486 size_t caret = selection.caret_pos(); 499 size_t caret = selection.caret_pos();
487 SelectionModel::CaretPlacement caret_placement = selection.caret_placement(); 500 SelectionModel::CaretPlacement caret_placement = selection.caret_placement();
488 size_t run_index = GetRunContainingPosition(caret); 501 size_t run_index = GetRunContainingPosition(caret);
489 DCHECK(run_index < runs_.size()); 502 DCHECK(run_index < runs_.size());
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 Rect r(GetUpdatedCursorBounds()); 650 Rect r(GetUpdatedCursorBounds());
638 canvas->DrawRectInt(kCursorColor, r.x(), r.y(), r.width(), r.height()); 651 canvas->DrawRectInt(kCursorColor, r.x(), r.y(), r.width(), r.height());
639 } 652 }
640 } 653 }
641 654
642 RenderText* RenderText::CreateRenderText() { 655 RenderText* RenderText::CreateRenderText() {
643 return new RenderTextWin; 656 return new RenderTextWin;
644 } 657 }
645 658
646 } // namespace gfx 659 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698