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/logging.h" | 11 #include "base/logging.h" |
11 #include "base/string_split.h" | 12 #include "base/string_split.h" |
12 #include "base/string_util.h" | 13 #include "base/string_util.h" |
13 #include "base/threading/thread_restrictions.h" | 14 #include "base/threading/thread_restrictions.h" |
14 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
15 #include "base/win/registry.h" | 16 #include "base/win/registry.h" |
16 #include "base/win/windows_version.h" | 17 #include "base/win/windows_version.h" |
17 #include "ui/gfx/canvas.h" | 18 #include "ui/gfx/canvas.h" |
18 #include "ui/gfx/font_smoothing_win.h" | 19 #include "ui/gfx/font_smoothing_win.h" |
19 #include "ui/gfx/platform_font_win.h" | 20 #include "ui/gfx/platform_font_win.h" |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 memset(&script_control_, 0, sizeof(script_control_)); | 296 memset(&script_control_, 0, sizeof(script_control_)); |
296 memset(&script_state_, 0, sizeof(script_state_)); | 297 memset(&script_state_, 0, sizeof(script_state_)); |
297 | 298 |
298 MoveCursorTo(EdgeSelectionModel(CURSOR_LEFT)); | 299 MoveCursorTo(EdgeSelectionModel(CURSOR_LEFT)); |
299 } | 300 } |
300 | 301 |
301 RenderTextWin::~RenderTextWin() { | 302 RenderTextWin::~RenderTextWin() { |
302 } | 303 } |
303 | 304 |
304 base::i18n::TextDirection RenderTextWin::GetTextDirection() { | 305 base::i18n::TextDirection RenderTextWin::GetTextDirection() { |
305 // TODO(benrg): Code moved from RenderText::GetTextDirection. Needs to be | 306 return base::i18n::GetFirstStrongCharacterDirection(text()); |
Alexei Svitkine (slow)
2012/07/02 16:21:11
What do you think of making this depend on EnsureL
msw
2012/07/02 19:54:49
Done.
| |
306 // replaced by a correct Windows implementation. | |
307 if (base::i18n::IsRTL()) | |
308 return base::i18n::RIGHT_TO_LEFT; | |
309 return base::i18n::LEFT_TO_RIGHT; | |
310 } | 307 } |
311 | 308 |
312 Size RenderTextWin::GetStringSize() { | 309 Size RenderTextWin::GetStringSize() { |
313 EnsureLayout(); | 310 EnsureLayout(); |
314 return string_size_; | 311 return string_size_; |
315 } | 312 } |
316 | 313 |
317 int RenderTextWin::GetBaseline() { | 314 int RenderTextWin::GetBaseline() { |
318 EnsureLayout(); | 315 EnsureLayout(); |
319 return common_baseline_; | 316 return common_baseline_; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
358 | 355 |
359 return spans; | 356 return spans; |
360 } | 357 } |
361 | 358 |
362 SelectionModel RenderTextWin::AdjacentCharSelectionModel( | 359 SelectionModel RenderTextWin::AdjacentCharSelectionModel( |
363 const SelectionModel& selection, | 360 const SelectionModel& selection, |
364 VisualCursorDirection direction) { | 361 VisualCursorDirection direction) { |
365 DCHECK(!needs_layout_); | 362 DCHECK(!needs_layout_); |
366 internal::TextRun* run; | 363 internal::TextRun* run; |
367 size_t run_index = GetRunContainingCaret(selection); | 364 size_t run_index = GetRunContainingCaret(selection); |
368 if (run_index == runs_.size()) { | 365 if (run_index >= runs_.size()) { |
369 // The cursor is not in any run: we're at the visual and logical edge. | 366 // The cursor is not in any run: we're at the visual and logical edge. |
370 SelectionModel edge = EdgeSelectionModel(direction); | 367 SelectionModel edge = EdgeSelectionModel(direction); |
371 if (edge.caret_pos() == selection.caret_pos()) | 368 if (edge.caret_pos() == selection.caret_pos()) |
372 return edge; | 369 return edge; |
373 run = direction == CURSOR_RIGHT ? runs_.front() : runs_.back(); | 370 int visual_index = (direction == CURSOR_RIGHT) ? 0 : runs_.size() - 1; |
371 run = runs_[visual_to_logical_[visual_index]]; | |
374 } else { | 372 } else { |
375 // If the cursor is moving within the current run, just move it by one | 373 // If the cursor is moving within the current run, just move it by one |
376 // grapheme in the appropriate direction. | 374 // grapheme in the appropriate direction. |
377 run = runs_[run_index]; | 375 run = runs_[run_index]; |
378 size_t caret = selection.caret_pos(); | 376 size_t caret = selection.caret_pos(); |
379 bool forward_motion = | 377 bool forward_motion = |
380 run->script_analysis.fRTL == (direction == CURSOR_LEFT); | 378 run->script_analysis.fRTL == (direction == CURSOR_LEFT); |
381 if (forward_motion) { | 379 if (forward_motion) { |
382 if (caret < run->range.end()) { | 380 if (caret < run->range.end()) { |
383 caret = IndexOfAdjacentGrapheme(caret, CURSOR_FORWARD); | 381 caret = IndexOfAdjacentGrapheme(caret, CURSOR_FORWARD); |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
595 void RenderTextWin::ItemizeLogicalText() { | 593 void RenderTextWin::ItemizeLogicalText() { |
596 runs_.reset(); | 594 runs_.reset(); |
597 string_size_ = Size(0, GetFont().GetHeight()); | 595 string_size_ = Size(0, GetFont().GetHeight()); |
598 common_baseline_ = 0; | 596 common_baseline_ = 0; |
599 if (text().empty()) | 597 if (text().empty()) |
600 return; | 598 return; |
601 | 599 |
602 const wchar_t* raw_text = text().c_str(); | 600 const wchar_t* raw_text = text().c_str(); |
603 const int text_length = text().length(); | 601 const int text_length = text().length(); |
604 | 602 |
603 // Initialize the base direction of the text. | |
604 script_state_.uBidiLevel = | |
Alexei Svitkine (slow)
2012/07/02 16:21:11
Can you clear uBidiLevel to 0 above the early retu
msw
2012/07/02 19:54:49
Done.
| |
605 (GetTextDirection() == base::i18n::LEFT_TO_RIGHT) ? 0 : 1; | |
606 | |
605 HRESULT hr = E_OUTOFMEMORY; | 607 HRESULT hr = E_OUTOFMEMORY; |
606 int script_items_count = 0; | 608 int script_items_count = 0; |
607 std::vector<SCRIPT_ITEM> script_items; | 609 std::vector<SCRIPT_ITEM> script_items; |
608 for (size_t n = kGuessItems; hr == E_OUTOFMEMORY && n < kMaxItems; n *= 2) { | 610 for (size_t n = kGuessItems; hr == E_OUTOFMEMORY && n < kMaxItems; n *= 2) { |
609 // Derive the array of Uniscribe script items from the logical text. | 611 // Derive the array of Uniscribe script items from the logical text. |
610 // ScriptItemize always adds a terminal array item so that the length of the | 612 // ScriptItemize always adds a terminal array item so that the length of the |
611 // last item can be derived from the terminal SCRIPT_ITEM::iCharPos. | 613 // last item can be derived from the terminal SCRIPT_ITEM::iCharPos. |
612 script_items.resize(n); | 614 script_items.resize(n); |
613 hr = ScriptItemize(raw_text, | 615 hr = ScriptItemize(raw_text, |
614 text_length, | 616 text_length, |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
909 const internal::TextRun* run) { | 911 const internal::TextRun* run) { |
910 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), CURSOR_BACKWARD); | 912 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), CURSOR_BACKWARD); |
911 return SelectionModel(caret, CURSOR_FORWARD); | 913 return SelectionModel(caret, CURSOR_FORWARD); |
912 } | 914 } |
913 | 915 |
914 RenderText* RenderText::CreateRenderText() { | 916 RenderText* RenderText::CreateRenderText() { |
915 return new RenderTextWin; | 917 return new RenderTextWin; |
916 } | 918 } |
917 | 919 |
918 } // namespace gfx | 920 } // namespace gfx |
OLD | NEW |