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 |