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 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 | 590 |
591 HRESULT hr = E_FAIL; | 591 HRESULT hr = E_FAIL; |
592 string_size_.set_height(0); | 592 string_size_.set_height(0); |
593 for (size_t i = 0; i < runs_.size(); ++i) { | 593 for (size_t i = 0; i < runs_.size(); ++i) { |
594 internal::TextRun* run = runs_[i]; | 594 internal::TextRun* run = runs_[i]; |
595 size_t run_length = run->range.length(); | 595 size_t run_length = run->range.length(); |
596 const wchar_t* run_text = &(text()[run->range.start()]); | 596 const wchar_t* run_text = &(text()[run->range.start()]); |
597 bool tried_fallback = false; | 597 bool tried_fallback = false; |
598 size_t linked_font_index = 0; | 598 size_t linked_font_index = 0; |
599 const std::vector<Font>* linked_fonts = NULL; | 599 const std::vector<Font>* linked_fonts = NULL; |
| 600 Font original_font = run->font; |
600 | 601 |
601 // Select the font desired for glyph generation. | 602 // Select the font desired for glyph generation. |
602 SelectObject(cached_hdc_, run->font.GetNativeFont()); | 603 SelectObject(cached_hdc_, run->font.GetNativeFont()); |
603 | 604 |
604 SCRIPT_FONTPROPERTIES properties; | 605 SCRIPT_FONTPROPERTIES properties; |
605 memset(&properties, 0, sizeof(properties)); | 606 memset(&properties, 0, sizeof(properties)); |
606 properties.cBytes = sizeof(properties); | 607 properties.cBytes = sizeof(properties); |
607 | 608 |
608 run->logical_clusters.reset(new WORD[run_length]); | 609 run->logical_clusters.reset(new WORD[run_length]); |
609 run->glyph_count = 0; | 610 run->glyph_count = 0; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 Font fallback_font; | 655 Font fallback_font; |
655 if (ChooseFallbackFont(cached_hdc_, run->font, run_text, run_length, | 656 if (ChooseFallbackFont(cached_hdc_, run->font, run_text, run_length, |
656 &fallback_font)) { | 657 &fallback_font)) { |
657 ApplySubstituteFont(run, fallback_font); | 658 ApplySubstituteFont(run, fallback_font); |
658 continue; | 659 continue; |
659 } | 660 } |
660 } | 661 } |
661 | 662 |
662 // The meta file approach did not yield a replacement font, try to find | 663 // The meta file approach did not yield a replacement font, try to find |
663 // one using font linking. First time through, get the linked fonts list. | 664 // one using font linking. First time through, get the linked fonts list. |
664 if (linked_fonts == NULL) | 665 if (linked_fonts == NULL) { |
665 linked_fonts = GetLinkedFonts(run->font); | 666 // First, try to get the list for the original font. |
| 667 linked_fonts = GetLinkedFonts(original_font); |
| 668 |
| 669 // If there are no linked fonts for the original font, try querying the |
| 670 // ones for the Uniscribe fallback font. This may happen if the first |
| 671 // font is a custom font that has no linked fonts in the Registry. |
| 672 // |
| 673 // Note: One possibility would be to always merge both lists of fonts, |
| 674 // but it is not clear whether there are any real world scenarios |
| 675 // where this would actually help. |
| 676 if (linked_fonts->empty()) |
| 677 linked_fonts = GetLinkedFonts(run->font); |
| 678 } |
666 | 679 |
667 // None of the linked fonts worked, break out of the loop. | 680 // None of the linked fonts worked, break out of the loop. |
668 if (linked_font_index == linked_fonts->size()) { | 681 if (linked_font_index == linked_fonts->size()) { |
669 // TODO(msw): Don't use SCRIPT_UNDEFINED. Apparently Uniscribe can | 682 // TODO(msw): Don't use SCRIPT_UNDEFINED. Apparently Uniscribe can |
670 // crash on certain surrogate pairs with SCRIPT_UNDEFINED. | 683 // crash on certain surrogate pairs with SCRIPT_UNDEFINED. |
671 // See https://bugzilla.mozilla.org/show_bug.cgi?id=341500 | 684 // See https://bugzilla.mozilla.org/show_bug.cgi?id=341500 |
672 // And http://maxradi.us/documents/uniscribe/ | 685 // And http://maxradi.us/documents/uniscribe/ |
673 run->script_analysis.eScript = SCRIPT_UNDEFINED; | 686 run->script_analysis.eScript = SCRIPT_UNDEFINED; |
674 // Reset |hr| to 0 to not trigger the DCHECK() below when a font is | 687 // Reset |hr| to 0 to not trigger the DCHECK() below when a font is |
675 // not found that can display the text. This is expected behavior | 688 // not found that can display the text. This is expected behavior |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 internal::TextRun* run) { | 797 internal::TextRun* run) { |
785 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), CURSOR_BACKWARD); | 798 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), CURSOR_BACKWARD); |
786 return SelectionModel(caret, CURSOR_FORWARD); | 799 return SelectionModel(caret, CURSOR_FORWARD); |
787 } | 800 } |
788 | 801 |
789 RenderText* RenderText::CreateRenderText() { | 802 RenderText* RenderText::CreateRenderText() { |
790 return new RenderTextWin; | 803 return new RenderTextWin; |
791 } | 804 } |
792 | 805 |
793 } // namespace gfx | 806 } // namespace gfx |
OLD | NEW |