OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/i18n/break_iterator.h" | 9 #include "base/i18n/break_iterator.h" |
10 #include "base/i18n/rtl.h" | 10 #include "base/i18n/rtl.h" |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 visual_index += (direction == CURSOR_LEFT) ? -1 : 1; | 310 visual_index += (direction == CURSOR_LEFT) ? -1 : 1; |
311 if (visual_index < 0 || visual_index >= static_cast<int>(runs_.size())) | 311 if (visual_index < 0 || visual_index >= static_cast<int>(runs_.size())) |
312 return EdgeSelectionModel(direction); | 312 return EdgeSelectionModel(direction); |
313 run = runs_[visual_to_logical_[visual_index]]; | 313 run = runs_[visual_to_logical_[visual_index]]; |
314 } | 314 } |
315 bool forward_motion = run->script_analysis.fRTL == (direction == CURSOR_LEFT); | 315 bool forward_motion = run->script_analysis.fRTL == (direction == CURSOR_LEFT); |
316 return forward_motion ? FirstSelectionModelInsideRun(run) : | 316 return forward_motion ? FirstSelectionModelInsideRun(run) : |
317 LastSelectionModelInsideRun(run); | 317 LastSelectionModelInsideRun(run); |
318 } | 318 } |
319 | 319 |
320 // TODO(msw): Implement word breaking for Windows. | |
321 SelectionModel RenderTextWin::AdjacentWordSelectionModel( | |
322 const SelectionModel& selection, | |
323 VisualCursorDirection direction) { | |
324 if (obscured()) | |
325 return EdgeSelectionModel(direction); | |
326 | |
327 base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD); | |
328 bool success = iter.Init(); | |
329 DCHECK(success); | |
330 if (!success) | |
331 return selection; | |
332 | |
333 size_t pos; | |
334 if (direction == CURSOR_RIGHT) { | |
335 pos = std::min(selection.caret_pos() + 1, text().length()); | |
336 while (iter.Advance()) { | |
337 pos = iter.pos(); | |
338 if (iter.IsWord() && pos > selection.caret_pos()) | |
339 break; | |
340 } | |
341 } else { // direction == CURSOR_LEFT | |
342 // Notes: We always iterate words from the beginning. | |
343 // This is probably fast enough for our usage, but we may | |
344 // want to modify WordIterator so that it can start from the | |
345 // middle of string and advance backwards. | |
346 pos = std::max<int>(selection.caret_pos() - 1, 0); | |
347 while (iter.Advance()) { | |
348 if (iter.IsWord()) { | |
349 size_t begin = iter.pos() - iter.GetString().length(); | |
350 if (begin == selection.caret_pos()) { | |
351 // The cursor is at the beginning of a word. | |
352 // Move to previous word. | |
353 break; | |
354 } else if (iter.pos() >= selection.caret_pos()) { | |
355 // The cursor is in the middle or at the end of a word. | |
356 // Move to the top of current word. | |
357 pos = begin; | |
358 break; | |
359 } else { | |
360 pos = iter.pos() - iter.GetString().length(); | |
361 } | |
362 } | |
363 } | |
364 } | |
365 return SelectionModel(pos, CURSOR_FORWARD); | |
366 } | |
367 | |
368 ui::Range RenderTextWin::GetGlyphBounds(size_t index) { | 320 ui::Range RenderTextWin::GetGlyphBounds(size_t index) { |
369 const size_t run_index = | 321 const size_t run_index = |
370 GetRunContainingCaret(SelectionModel(index, CURSOR_FORWARD)); | 322 GetRunContainingCaret(SelectionModel(index, CURSOR_FORWARD)); |
371 // Return edge bounds if the index is invalid or beyond the layout text size. | 323 // Return edge bounds if the index is invalid or beyond the layout text size. |
372 if (run_index >= runs_.size()) | 324 if (run_index >= runs_.size()) |
373 return ui::Range(string_size_.width()); | 325 return ui::Range(string_size_.width()); |
374 internal::TextRun* run = runs_[run_index]; | 326 internal::TextRun* run = runs_[run_index]; |
375 const size_t layout_index = TextIndexToLayoutIndex(index); | 327 const size_t layout_index = TextIndexToLayoutIndex(index); |
376 return ui::Range(GetGlyphXBoundary(run, layout_index, false), | 328 return ui::Range(GetGlyphXBoundary(run, layout_index, false), |
377 GetGlyphXBoundary(run, layout_index, true)); | 329 GetGlyphXBoundary(run, layout_index, true)); |
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
889 size_t position = LayoutIndexToTextIndex(run->range.end()); | 841 size_t position = LayoutIndexToTextIndex(run->range.end()); |
890 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); | 842 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); |
891 return SelectionModel(position, CURSOR_FORWARD); | 843 return SelectionModel(position, CURSOR_FORWARD); |
892 } | 844 } |
893 | 845 |
894 RenderText* RenderText::CreateInstance() { | 846 RenderText* RenderText::CreateInstance() { |
895 return new RenderTextWin; | 847 return new RenderTextWin; |
896 } | 848 } |
897 | 849 |
898 } // namespace gfx | 850 } // namespace gfx |
OLD | NEW |