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/logging.h" | 10 #include "base/logging.h" |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 646 glyphs_missing = true; | 646 glyphs_missing = true; |
| 647 } else if (hr == S_OK) { | 647 } else if (hr == S_OK) { |
| 648 // If |hr| is S_OK, there could still be missing glyphs in the output, | 648 // If |hr| is S_OK, there could still be missing glyphs in the output, |
| 649 // see: http://msdn.microsoft.com/en-us/library/windows/desktop/dd368564 .aspx | 649 // see: http://msdn.microsoft.com/en-us/library/windows/desktop/dd368564 .aspx |
| 650 ScriptGetFontProperties(cached_hdc_, &run->script_cache, &properties); | 650 ScriptGetFontProperties(cached_hdc_, &run->script_cache, &properties); |
| 651 for (int i = 0; i < run->glyph_count; ++i) { | 651 for (int i = 0; i < run->glyph_count; ++i) { |
| 652 if (run->glyphs[i] == properties.wgDefault) { | 652 if (run->glyphs[i] == properties.wgDefault) { |
| 653 glyphs_missing = true; | 653 glyphs_missing = true; |
| 654 break; | 654 break; |
| 655 } | 655 } |
| 656 | |
| 657 // On Vista, when trying to draw Simplified Chinese via font linking, | |
|
msw
2012/05/02 22:19:09
Perhaps generalize this comment if there may be ot
Alexei Svitkine (slow)
2012/05/03 14:37:20
Done.
| |
| 658 // missing glyphs in the Meiryo font are returned as wgBlank instead | |
| 659 // of wgDefault, with fZeroWidth set. | |
| 660 if (run->glyphs[i] == properties.wgBlank && | |
| 661 run->visible_attributes[i].fZeroWidth) { | |
| 662 // Check whether this glyph corresponds entirely to whitespace. If | |
| 663 // it doesn't, assume there are missing glyphs. | |
| 664 const ui::Range range = GetTextRangeForRunGlyph(run, i); | |
| 665 DCHECK_NE(0U, range.length()); | |
|
msw
2012/05/02 22:19:09
Use DCHECK_GT? Also DCHECK_LT/LE(range.end(), run-
| |
| 666 | |
| 667 const string16 glyph_text(&run_text[range.start()], range.length()); | |
| 668 if (!ContainsOnlyWhitespace(glyph_text)) { | |
| 669 glyphs_missing = true; | |
| 670 break; | |
| 671 } | |
| 672 } | |
| 656 } | 673 } |
| 657 } | 674 } |
| 658 | 675 |
| 659 // Skip font substitution if there are no missing glyphs. | 676 // Skip font substitution if there are no missing glyphs. |
| 660 if (!glyphs_missing) | 677 if (!glyphs_missing) |
| 661 break; | 678 break; |
| 662 | 679 |
| 663 // If there are missing glyphs, first try finding a fallback font using a | 680 // If there are missing glyphs, first try finding a fallback font using a |
| 664 // meta file, if it hasn't yet been attempted for this run. | 681 // meta file, if it hasn't yet been attempted for this run. |
| 665 // TODO(msw|asvitkine): Support RenderText's font_list()? | 682 // TODO(msw|asvitkine): Support RenderText's font_list()? |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 797 // Find the text run containing the argument point (assumed already offset). | 814 // Find the text run containing the argument point (assumed already offset). |
| 798 size_t run = 0; | 815 size_t run = 0; |
| 799 for (; run < runs_.size(); ++run) | 816 for (; run < runs_.size(); ++run) |
| 800 if (runs_[run]->preceding_run_widths <= point.x() && | 817 if (runs_[run]->preceding_run_widths <= point.x() && |
| 801 runs_[run]->preceding_run_widths + runs_[run]->width > point.x()) | 818 runs_[run]->preceding_run_widths + runs_[run]->width > point.x()) |
| 802 break; | 819 break; |
| 803 return run; | 820 return run; |
| 804 } | 821 } |
| 805 | 822 |
| 806 SelectionModel RenderTextWin::FirstSelectionModelInsideRun( | 823 SelectionModel RenderTextWin::FirstSelectionModelInsideRun( |
| 807 internal::TextRun* run) { | 824 const internal::TextRun* run) { |
| 808 size_t cursor = IndexOfAdjacentGrapheme(run->range.start(), CURSOR_FORWARD); | 825 size_t cursor = IndexOfAdjacentGrapheme(run->range.start(), CURSOR_FORWARD); |
| 809 return SelectionModel(cursor, CURSOR_BACKWARD); | 826 return SelectionModel(cursor, CURSOR_BACKWARD); |
| 810 } | 827 } |
| 811 | 828 |
| 812 SelectionModel RenderTextWin::LastSelectionModelInsideRun( | 829 SelectionModel RenderTextWin::LastSelectionModelInsideRun( |
| 813 internal::TextRun* run) { | 830 const internal::TextRun* run) { |
| 814 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), CURSOR_BACKWARD); | 831 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), CURSOR_BACKWARD); |
| 815 return SelectionModel(caret, CURSOR_FORWARD); | 832 return SelectionModel(caret, CURSOR_FORWARD); |
| 816 } | 833 } |
| 817 | 834 |
| 835 ui::Range RenderTextWin::GetTextRangeForRunGlyph(const internal::TextRun* run, | |
| 836 size_t glyph_index) const { | |
| 837 int first_seen = -1; | |
| 838 int last_seen = -1; | |
| 839 for (size_t char_index = 0; char_index < run->range.length(); ++char_index) { | |
| 840 if (run->logical_clusters[char_index] == glyph_index) { | |
| 841 last_seen = char_index; | |
| 842 if (first_seen == -1) | |
| 843 first_seen = char_index; | |
| 844 } | |
| 845 } | |
| 846 DCHECK_NE(first_seen, -1); | |
| 847 return ui::Range(first_seen, last_seen + 1); | |
| 848 } | |
| 849 | |
| 818 RenderText* RenderText::CreateRenderText() { | 850 RenderText* RenderText::CreateRenderText() { |
| 819 return new RenderTextWin; | 851 return new RenderTextWin; |
| 820 } | 852 } |
| 821 | 853 |
| 822 } // namespace gfx | 854 } // namespace gfx |
| OLD | NEW |