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/char_iterator.h" | 10 #include "base/i18n/char_iterator.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 const size_t kMaxUniscribeTextLength = 10000; | 31 const size_t kMaxUniscribeTextLength = 10000; |
32 | 32 |
33 // The initial guess and maximum supported number of runs; arbitrary values. | 33 // The initial guess and maximum supported number of runs; arbitrary values. |
34 // TODO(msw): Support more runs, determine a better initial guess, etc. | 34 // TODO(msw): Support more runs, determine a better initial guess, etc. |
35 const int kGuessRuns = 100; | 35 const int kGuessRuns = 100; |
36 const size_t kMaxRuns = 10000; | 36 const size_t kMaxRuns = 10000; |
37 | 37 |
38 // The maximum number of glyphs per run; ScriptShape fails on larger values. | 38 // The maximum number of glyphs per run; ScriptShape fails on larger values. |
39 const size_t kMaxGlyphs = 65535; | 39 const size_t kMaxGlyphs = 65535; |
40 | 40 |
41 // Changes |font| to have the specified |font_size| (or |font_height| on Windows | 41 // Changes |font| to the specified |font_height| and bold/italic |font_style|. |
42 // XP) and |font_style| if it is not the case already. Only considers bold and | 42 // Underlined styling is not considered, as it has no effect on glyph shaping. |
43 // italic styles, since the underlined style has no effect on glyph shaping. | 43 void DeriveFontIfNecessary(int height, int style, Font* font) { |
44 void DeriveFontIfNecessary(int font_size, | |
45 int font_height, | |
46 int font_style, | |
47 Font* font) { | |
48 const int kStyleMask = (Font::BOLD | Font::ITALIC); | 44 const int kStyleMask = (Font::BOLD | Font::ITALIC); |
49 const int target_style = (font_style & kStyleMask); | 45 PlatformFontWin* platform_font = |
50 | 46 static_cast<PlatformFontWin*>(font->platform_font()); |
51 // On Windows XP, the font must be resized using |font_height| instead of | 47 *font = platform_font->DeriveFontWithHeight(height, style & kStyleMask); |
52 // |font_size| to match GDI behavior. | |
53 if (base::win::GetVersion() < base::win::VERSION_VISTA) { | |
54 PlatformFontWin* platform_font = | |
55 static_cast<PlatformFontWin*>(font->platform_font()); | |
56 *font = platform_font->DeriveFontWithHeight(font_height, target_style); | |
57 return; | |
58 } | |
59 | |
60 const int current_style = (font->GetStyle() & kStyleMask); | |
61 const int current_size = font->GetFontSize(); | |
62 if (current_style != target_style || current_size != font_size) | |
63 *font = font->Derive(font_size - current_size, target_style); | |
64 } | 48 } |
65 | 49 |
66 // Returns true if |c| is a Unicode BiDi control character. | 50 // Returns true if |c| is a Unicode BiDi control character. |
67 bool IsUnicodeBidiControlCharacter(base::char16 c) { | 51 bool IsUnicodeBidiControlCharacter(base::char16 c) { |
68 return c == base::i18n::kRightToLeftMark || | 52 return c == base::i18n::kRightToLeftMark || |
69 c == base::i18n::kLeftToRightMark || | 53 c == base::i18n::kLeftToRightMark || |
70 c == base::i18n::kLeftToRightEmbeddingMark || | 54 c == base::i18n::kLeftToRightEmbeddingMark || |
71 c == base::i18n::kRightToLeftEmbeddingMark || | 55 c == base::i18n::kRightToLeftEmbeddingMark || |
72 c == base::i18n::kPopDirectionalFormatting || | 56 c == base::i18n::kPopDirectionalFormatting || |
73 c == base::i18n::kLeftToRightOverride || | 57 c == base::i18n::kLeftToRightOverride || |
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
884 empty_colors.SetMax(layout_text_length); | 868 empty_colors.SetMax(layout_text_length); |
885 internal::StyleIterator style(empty_colors, styles()); | 869 internal::StyleIterator style(empty_colors, styles()); |
886 SCRIPT_ITEM* script_item = &script_items[0]; | 870 SCRIPT_ITEM* script_item = &script_items[0]; |
887 const size_t max_run_length = kMaxGlyphs / 2; | 871 const size_t max_run_length = kMaxGlyphs / 2; |
888 for (size_t run_break = 0; run_break < layout_text_length;) { | 872 for (size_t run_break = 0; run_break < layout_text_length;) { |
889 internal::TextRun* run = new internal::TextRun(); | 873 internal::TextRun* run = new internal::TextRun(); |
890 run->range.set_start(run_break); | 874 run->range.set_start(run_break); |
891 run->font = font_list().GetPrimaryFont(); | 875 run->font = font_list().GetPrimaryFont(); |
892 run->font_style = (style.style(BOLD) ? Font::BOLD : 0) | | 876 run->font_style = (style.style(BOLD) ? Font::BOLD : 0) | |
893 (style.style(ITALIC) ? Font::ITALIC : 0); | 877 (style.style(ITALIC) ? Font::ITALIC : 0); |
894 DeriveFontIfNecessary(run->font.GetFontSize(), run->font.GetHeight(), | 878 DeriveFontIfNecessary(run->font.GetHeight(), run->font_style, &run->font); |
895 run->font_style, &run->font); | |
896 run->strike = style.style(STRIKE); | 879 run->strike = style.style(STRIKE); |
897 run->diagonal_strike = style.style(DIAGONAL_STRIKE); | 880 run->diagonal_strike = style.style(DIAGONAL_STRIKE); |
898 run->underline = style.style(UNDERLINE); | 881 run->underline = style.style(UNDERLINE); |
899 run->script_analysis = script_item->a; | 882 run->script_analysis = script_item->a; |
900 | 883 |
901 // Find the next break and advance the iterators as needed. | 884 // Find the next break and advance the iterators as needed. |
902 const size_t script_item_break = (script_item + 1)->iCharPos; | 885 const size_t script_item_break = (script_item + 1)->iCharPos; |
903 run_break = std::min(script_item_break, | 886 run_break = std::min(script_item_break, |
904 TextIndexToLayoutIndex(style.GetRange().end())); | 887 TextIndexToLayoutIndex(style.GetRange().end())); |
905 | 888 |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1112 // See https://bugzilla.mozilla.org/show_bug.cgi?id=341500 | 1095 // See https://bugzilla.mozilla.org/show_bug.cgi?id=341500 |
1113 // And http://maxradi.us/documents/uniscribe/ | 1096 // And http://maxradi.us/documents/uniscribe/ |
1114 run->script_analysis.eScript = SCRIPT_UNDEFINED; | 1097 run->script_analysis.eScript = SCRIPT_UNDEFINED; |
1115 } | 1098 } |
1116 | 1099 |
1117 HRESULT RenderTextWin::ShapeTextRunWithFont(internal::TextRun* run, | 1100 HRESULT RenderTextWin::ShapeTextRunWithFont(internal::TextRun* run, |
1118 const Font& font) { | 1101 const Font& font) { |
1119 // Update the run's font only if necessary. If the two fonts wrap the same | 1102 // Update the run's font only if necessary. If the two fonts wrap the same |
1120 // PlatformFontWin object, their native fonts will have the same value. | 1103 // PlatformFontWin object, their native fonts will have the same value. |
1121 if (run->font.GetNativeFont() != font.GetNativeFont()) { | 1104 if (run->font.GetNativeFont() != font.GetNativeFont()) { |
1122 const int font_size = run->font.GetFontSize(); | 1105 const int original_height = run->font.GetHeight(); |
1123 const int font_height = run->font.GetHeight(); | |
1124 run->font = font; | 1106 run->font = font; |
1125 DeriveFontIfNecessary(font_size, font_height, run->font_style, &run->font); | 1107 DeriveFontIfNecessary(original_height, run->font_style, &run->font); |
1126 ScriptFreeCache(&run->script_cache); | 1108 ScriptFreeCache(&run->script_cache); |
1127 } | 1109 } |
1128 | 1110 |
1129 // Select the font desired for glyph generation. | 1111 // Select the font desired for glyph generation. |
1130 SelectObject(cached_hdc_, run->font.GetNativeFont()); | 1112 SelectObject(cached_hdc_, run->font.GetNativeFont()); |
1131 | 1113 |
1132 HRESULT hr = E_OUTOFMEMORY; | 1114 HRESULT hr = E_OUTOFMEMORY; |
1133 const size_t run_length = run->range.length(); | 1115 const size_t run_length = run->range.length(); |
1134 const wchar_t* run_text = &(GetLayoutText()[run->range.start()]); | 1116 const wchar_t* run_text = &(GetLayoutText()[run->range.start()]); |
1135 // Guess the expected number of glyphs from the length of the run. | 1117 // Guess the expected number of glyphs from the length of the run. |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1224 size_t position = LayoutIndexToTextIndex(run->range.end()); | 1206 size_t position = LayoutIndexToTextIndex(run->range.end()); |
1225 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); | 1207 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); |
1226 return SelectionModel(position, CURSOR_FORWARD); | 1208 return SelectionModel(position, CURSOR_FORWARD); |
1227 } | 1209 } |
1228 | 1210 |
1229 RenderText* RenderText::CreateNativeInstance() { | 1211 RenderText* RenderText::CreateNativeInstance() { |
1230 return new RenderTextWin; | 1212 return new RenderTextWin; |
1231 } | 1213 } |
1232 | 1214 |
1233 } // namespace gfx | 1215 } // namespace gfx |
OLD | NEW |