Chromium Code Reviews| 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 EnsureLayout(); |
| 306 // replaced by a correct Windows implementation. | 307 return (script_state_.uBidiLevel == 0) ? |
| 307 if (base::i18n::IsRTL()) | 308 base::i18n::LEFT_TO_RIGHT : base::i18n::RIGHT_TO_LEFT; |
| 308 return base::i18n::RIGHT_TO_LEFT; | |
| 309 return base::i18n::LEFT_TO_RIGHT; | |
| 310 } | 309 } |
| 311 | 310 |
| 312 Size RenderTextWin::GetStringSize() { | 311 Size RenderTextWin::GetStringSize() { |
| 313 EnsureLayout(); | 312 EnsureLayout(); |
| 314 return string_size_; | 313 return string_size_; |
| 315 } | 314 } |
| 316 | 315 |
| 317 int RenderTextWin::GetBaseline() { | 316 int RenderTextWin::GetBaseline() { |
| 318 EnsureLayout(); | 317 EnsureLayout(); |
| 319 return common_baseline_; | 318 return common_baseline_; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 358 | 357 |
| 359 return spans; | 358 return spans; |
| 360 } | 359 } |
| 361 | 360 |
| 362 SelectionModel RenderTextWin::AdjacentCharSelectionModel( | 361 SelectionModel RenderTextWin::AdjacentCharSelectionModel( |
| 363 const SelectionModel& selection, | 362 const SelectionModel& selection, |
| 364 VisualCursorDirection direction) { | 363 VisualCursorDirection direction) { |
| 365 DCHECK(!needs_layout_); | 364 DCHECK(!needs_layout_); |
| 366 internal::TextRun* run; | 365 internal::TextRun* run; |
| 367 size_t run_index = GetRunContainingCaret(selection); | 366 size_t run_index = GetRunContainingCaret(selection); |
| 368 if (run_index == runs_.size()) { | 367 if (run_index >= runs_.size()) { |
| 369 // The cursor is not in any run: we're at the visual and logical edge. | 368 // The cursor is not in any run: we're at the visual and logical edge. |
| 370 SelectionModel edge = EdgeSelectionModel(direction); | 369 SelectionModel edge = EdgeSelectionModel(direction); |
| 371 if (edge.caret_pos() == selection.caret_pos()) | 370 if (edge.caret_pos() == selection.caret_pos()) |
| 372 return edge; | 371 return edge; |
| 373 run = direction == CURSOR_RIGHT ? runs_.front() : runs_.back(); | 372 int visual_index = (direction == CURSOR_RIGHT) ? 0 : runs_.size() - 1; |
| 373 run = runs_[visual_to_logical_[visual_index]]; | |
| 374 } else { | 374 } else { |
| 375 // If the cursor is moving within the current run, just move it by one | 375 // If the cursor is moving within the current run, just move it by one |
| 376 // grapheme in the appropriate direction. | 376 // grapheme in the appropriate direction. |
| 377 run = runs_[run_index]; | 377 run = runs_[run_index]; |
| 378 size_t caret = selection.caret_pos(); | 378 size_t caret = selection.caret_pos(); |
| 379 bool forward_motion = | 379 bool forward_motion = |
| 380 run->script_analysis.fRTL == (direction == CURSOR_LEFT); | 380 run->script_analysis.fRTL == (direction == CURSOR_LEFT); |
| 381 if (forward_motion) { | 381 if (forward_motion) { |
| 382 if (caret < run->range.end()) { | 382 if (caret < run->range.end()) { |
| 383 caret = IndexOfAdjacentGrapheme(caret, CURSOR_FORWARD); | 383 caret = IndexOfAdjacentGrapheme(caret, CURSOR_FORWARD); |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 589 renderer.DrawDecorations(x, y, run->width, style); | 589 renderer.DrawDecorations(x, y, run->width, style); |
| 590 | 590 |
| 591 x = glyph_x; | 591 x = glyph_x; |
| 592 } | 592 } |
| 593 } | 593 } |
| 594 | 594 |
| 595 void RenderTextWin::ItemizeLogicalText() { | 595 void RenderTextWin::ItemizeLogicalText() { |
| 596 runs_.reset(); | 596 runs_.reset(); |
| 597 string_size_ = Size(0, GetFont().GetHeight()); | 597 string_size_ = Size(0, GetFont().GetHeight()); |
| 598 common_baseline_ = 0; | 598 common_baseline_ = 0; |
| 599 script_state_.uBidiLevel = 0; | |
|
Alexei Svitkine (slow)
2012/07/03 18:37:57
Can you add a case to your test that would fail if
msw
2012/07/03 22:34:04
I adjusted the logic and added a test.
| |
| 599 if (text().empty()) | 600 if (text().empty()) |
| 600 return; | 601 return; |
| 601 | 602 |
| 602 const wchar_t* raw_text = text().c_str(); | 603 const wchar_t* raw_text = text().c_str(); |
| 603 const int text_length = text().length(); | 604 const int text_length = text().length(); |
| 604 | 605 |
| 606 // Initialize the base direction of the text. | |
| 607 if (base::i18n::GetFirstStrongCharacterDirection(text()) == | |
| 608 base::i18n::RIGHT_TO_LEFT) { | |
|
Alexei Svitkine (slow)
2012/07/03 18:37:57
Nit: Indent 4 more spaces since it's breaking on a
msw
2012/07/03 22:34:04
Moot.
| |
| 609 script_state_.uBidiLevel = 1; | |
| 610 } | |
| 611 | |
| 605 HRESULT hr = E_OUTOFMEMORY; | 612 HRESULT hr = E_OUTOFMEMORY; |
| 606 int script_items_count = 0; | 613 int script_items_count = 0; |
| 607 std::vector<SCRIPT_ITEM> script_items; | 614 std::vector<SCRIPT_ITEM> script_items; |
| 608 for (size_t n = kGuessItems; hr == E_OUTOFMEMORY && n < kMaxItems; n *= 2) { | 615 for (size_t n = kGuessItems; hr == E_OUTOFMEMORY && n < kMaxItems; n *= 2) { |
| 609 // Derive the array of Uniscribe script items from the logical text. | 616 // 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 | 617 // 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. | 618 // last item can be derived from the terminal SCRIPT_ITEM::iCharPos. |
| 612 script_items.resize(n); | 619 script_items.resize(n); |
| 613 hr = ScriptItemize(raw_text, | 620 hr = ScriptItemize(raw_text, |
| 614 text_length, | 621 text_length, |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 909 const internal::TextRun* run) { | 916 const internal::TextRun* run) { |
| 910 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), CURSOR_BACKWARD); | 917 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), CURSOR_BACKWARD); |
| 911 return SelectionModel(caret, CURSOR_FORWARD); | 918 return SelectionModel(caret, CURSOR_FORWARD); |
| 912 } | 919 } |
| 913 | 920 |
| 914 RenderText* RenderText::CreateRenderText() { | 921 RenderText* RenderText::CreateRenderText() { |
| 915 return new RenderTextWin; | 922 return new RenderTextWin; |
| 916 } | 923 } |
| 917 | 924 |
| 918 } // namespace gfx | 925 } // namespace gfx |
| OLD | NEW |