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" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
13 #include "base/threading/thread_restrictions.h" | 13 #include "base/threading/thread_restrictions.h" |
14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
15 #include "base/win/registry.h" | 15 #include "base/win/registry.h" |
16 #include "base/win/windows_version.h" | |
16 #include "ui/gfx/canvas.h" | 17 #include "ui/gfx/canvas.h" |
17 #include "ui/gfx/font_smoothing_win.h" | 18 #include "ui/gfx/font_smoothing_win.h" |
18 #include "ui/gfx/platform_font.h" | 19 #include "ui/gfx/platform_font.h" |
19 | 20 |
20 namespace { | 21 namespace { |
21 | 22 |
22 // The maximum supported number of Uniscribe runs; a SCRIPT_ITEM is 8 bytes. | 23 // The maximum supported number of Uniscribe runs; a SCRIPT_ITEM is 8 bytes. |
23 // TODO(msw): Review memory use/failure? Max string length? Alternate approach? | 24 // TODO(msw): Review memory use/failure? Max string length? Alternate approach? |
24 const int kGuessItems = 100; | 25 const int kGuessItems = 100; |
25 const int kMaxItems = 10000; | 26 const int kMaxItems = 10000; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 if ((index != string16::npos) && (index + 1 != values[i].length())) { | 110 if ((index != string16::npos) && (index + 1 != values[i].length())) { |
110 const std::string linked_name = UTF16ToUTF8(values[i].substr(index + 1)); | 111 const std::string linked_name = UTF16ToUTF8(values[i].substr(index + 1)); |
111 const gfx::Font linked_font(linked_name, font.GetFontSize()); | 112 const gfx::Font linked_font(linked_name, font.GetFontSize()); |
112 linked_fonts->push_back(linked_font); | 113 linked_fonts->push_back(linked_font); |
113 } | 114 } |
114 } | 115 } |
115 | 116 |
116 key.Close(); | 117 key.Close(); |
117 } | 118 } |
118 | 119 |
119 // Changes |font| to have the specified |font_size| and |font_style| if it does | 120 // Chooses the largest font size for |font| such that its height does not exceed |
msw
2012/04/25 22:07:31
Add a DCHECK at the bottom of the function to ensu
| |
120 // not already. Only considers bold and italic styles, since the underlined | 121 // |font_height|. |font_style| is used for the style when deriving the font. |
121 // style has no effect on glyph shaping. | 122 void DeriveFontWithHeight(int font_height, int font_style, gfx::Font* font) { |
msw
2012/04/25 22:07:31
This probably needs test coverage.
Alexei Svitkine (slow)
2012/04/25 23:19:31
Do you mean the function itself, or the whole Rend
msw
2012/04/25 23:35:41
I meant the CJK rendertext codepath, very sad that
| |
122 void DeriveFontIfNecessary(int font_size, int font_style, gfx::Font* font) { | 123 if (font->GetHeight() > font_height) { |
124 do { | |
125 *font = font->DeriveFont(-1, font_style); | |
126 } while (font->GetHeight() > font_height); | |
msw
2012/04/25 22:07:31
Only code trying to emulate MS APIs could be this
Alexei Svitkine (slow)
2012/04/25 23:19:31
DeriveFont() is not very expensive anymore (but no
msw
2012/04/25 23:35:41
Yeah, I'm dubious that it's worth your time/effort
| |
127 } else if (font->GetHeight() < font_height) { | |
128 gfx::Font larger_font = font->DeriveFont(1, font_style); | |
129 while (larger_font.GetHeight() < font_height) { | |
msw
2012/04/25 22:07:31
Shouldn't this be '<=' ? Otherwiset we'll miss whe
Alexei Svitkine (slow)
2012/04/25 23:19:31
You're absolutely right! I had this correct before
| |
130 *font = larger_font; | |
131 larger_font = larger_font.DeriveFont(1, font_style); | |
132 } | |
133 } | |
134 } | |
135 | |
136 // Changes |font| to have the specified |font_size| (or |font_height| on Windows | |
137 // XP) and |font_style| if it is not the case already. Only considers bold and | |
138 // italic styles, since the underlined style has no effect on glyph shaping. | |
139 void DeriveFontIfNecessary(int font_size, | |
140 int font_height, | |
141 int font_style, | |
142 gfx::Font* font) { | |
143 // On Windows XP, the font must be resized using |font_height| instead of | |
144 // |font_size| to match the GDI behavior. | |
msw
2012/04/25 22:07:31
grammar nit: nix 'the' -> "match GDI behavior"
| |
145 if (base::win::GetVersion() < base::win::VERSION_VISTA) { | |
146 DeriveFontWithHeight(font_height, font_style, font); | |
147 font_size = font->GetFontSize(); | |
148 } | |
149 | |
123 const int kStyleMask = (gfx::Font::BOLD | gfx::Font::ITALIC); | 150 const int kStyleMask = (gfx::Font::BOLD | gfx::Font::ITALIC); |
124 const int current_style = (font->GetStyle() & kStyleMask); | 151 const int current_style = (font->GetStyle() & kStyleMask); |
125 const int target_style = (font_style & kStyleMask); | 152 const int target_style = (font_style & kStyleMask); |
126 const int current_size = font->GetFontSize(); | 153 const int current_size = font->GetFontSize(); |
154 | |
127 if (current_style != target_style || current_size != font_size) | 155 if (current_style != target_style || current_size != font_size) |
128 *font = font->DeriveFont(font_size - current_size, font_style); | 156 *font = font->DeriveFont(font_size - current_size, font_style); |
129 } | 157 } |
130 | 158 |
131 } // namespace | 159 } // namespace |
132 | 160 |
133 namespace gfx { | 161 namespace gfx { |
134 | 162 |
135 namespace internal { | 163 namespace internal { |
136 | 164 |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
555 // TODO(msw): Only break for font changes, not color etc. See TextRun comment. | 583 // TODO(msw): Only break for font changes, not color etc. See TextRun comment. |
556 StyleRanges styles(style_ranges()); | 584 StyleRanges styles(style_ranges()); |
557 ApplyCompositionAndSelectionStyles(&styles); | 585 ApplyCompositionAndSelectionStyles(&styles); |
558 StyleRanges::const_iterator style = styles.begin(); | 586 StyleRanges::const_iterator style = styles.begin(); |
559 SCRIPT_ITEM* script_item = &script_items[0]; | 587 SCRIPT_ITEM* script_item = &script_items[0]; |
560 for (int run_break = 0; run_break < text_length;) { | 588 for (int run_break = 0; run_break < text_length;) { |
561 internal::TextRun* run = new internal::TextRun(); | 589 internal::TextRun* run = new internal::TextRun(); |
562 run->range.set_start(run_break); | 590 run->range.set_start(run_break); |
563 run->font = GetFont(); | 591 run->font = GetFont(); |
564 run->font_style = style->font_style; | 592 run->font_style = style->font_style; |
565 DeriveFontIfNecessary(run->font.GetFontSize(), run->font_style, &run->font); | 593 DeriveFontIfNecessary(run->font.GetFontSize(), run->font.GetHeight(), |
594 run->font_style, &run->font); | |
566 run->foreground = style->foreground; | 595 run->foreground = style->foreground; |
567 run->strike = style->strike; | 596 run->strike = style->strike; |
568 run->diagonal_strike = style->diagonal_strike; | 597 run->diagonal_strike = style->diagonal_strike; |
569 run->underline = style->underline; | 598 run->underline = style->underline; |
570 run->script_analysis = script_item->a; | 599 run->script_analysis = script_item->a; |
571 | 600 |
572 // Find the range end and advance the structures as needed. | 601 // Find the range end and advance the structures as needed. |
573 int script_item_end = (script_item + 1)->iCharPos; | 602 int script_item_end = (script_item + 1)->iCharPos; |
574 int style_range_end = style->range.end(); | 603 int style_range_end = style->range.end(); |
575 run_break = std::min(script_item_end, style_range_end); | 604 run_break = std::min(script_item_end, style_range_end); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
739 const ABC& abc = run->abc_widths; | 768 const ABC& abc = run->abc_widths; |
740 run->width = abc.abcA + abc.abcB + abc.abcC; | 769 run->width = abc.abcA + abc.abcB + abc.abcC; |
741 preceding_run_widths += run->width; | 770 preceding_run_widths += run->width; |
742 } | 771 } |
743 string_size_.set_width(preceding_run_widths); | 772 string_size_.set_width(preceding_run_widths); |
744 } | 773 } |
745 | 774 |
746 void RenderTextWin::ApplySubstituteFont(internal::TextRun* run, | 775 void RenderTextWin::ApplySubstituteFont(internal::TextRun* run, |
747 const Font& font) { | 776 const Font& font) { |
748 const int font_size = run->font.GetFontSize(); | 777 const int font_size = run->font.GetFontSize(); |
778 const int font_height = run->font.GetHeight(); | |
749 run->font = font; | 779 run->font = font; |
750 DeriveFontIfNecessary(font_size, run->font_style, &run->font); | 780 DeriveFontIfNecessary(font_size, font_height, run->font_style, &run->font); |
751 ScriptFreeCache(&run->script_cache); | 781 ScriptFreeCache(&run->script_cache); |
752 SelectObject(cached_hdc_, run->font.GetNativeFont()); | 782 SelectObject(cached_hdc_, run->font.GetNativeFont()); |
753 } | 783 } |
754 | 784 |
755 const std::vector<Font>* RenderTextWin::GetLinkedFonts(const Font& font) const { | 785 const std::vector<Font>* RenderTextWin::GetLinkedFonts(const Font& font) const { |
756 const std::string& font_name = font.GetFontName(); | 786 const std::string& font_name = font.GetFontName(); |
757 std::map<std::string, std::vector<Font> >::const_iterator it = | 787 std::map<std::string, std::vector<Font> >::const_iterator it = |
758 cached_linked_fonts_.find(font_name); | 788 cached_linked_fonts_.find(font_name); |
759 if (it != cached_linked_fonts_.end()) | 789 if (it != cached_linked_fonts_.end()) |
760 return &it->second; | 790 return &it->second; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
797 internal::TextRun* run) { | 827 internal::TextRun* run) { |
798 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), CURSOR_BACKWARD); | 828 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), CURSOR_BACKWARD); |
799 return SelectionModel(caret, CURSOR_FORWARD); | 829 return SelectionModel(caret, CURSOR_FORWARD); |
800 } | 830 } |
801 | 831 |
802 RenderText* RenderText::CreateRenderText() { | 832 RenderText* RenderText::CreateRenderText() { |
803 return new RenderTextWin; | 833 return new RenderTextWin; |
804 } | 834 } |
805 | 835 |
806 } // namespace gfx | 836 } // namespace gfx |
OLD | NEW |