Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_harfbuzz.h" | 5 #include "ui/gfx/render_text_harfbuzz.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/i18n/bidi_line_iterator.h" | 9 #include "base/i18n/bidi_line_iterator.h" |
| 10 #include "base/i18n/break_iterator.h" | 10 #include "base/i18n/break_iterator.h" |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 466 } | 466 } |
| 467 | 467 |
| 468 TextRunHarfBuzz::TextRunHarfBuzz() | 468 TextRunHarfBuzz::TextRunHarfBuzz() |
| 469 : width(0.0f), | 469 : width(0.0f), |
| 470 preceding_run_widths(0.0f), | 470 preceding_run_widths(0.0f), |
| 471 is_rtl(false), | 471 is_rtl(false), |
| 472 level(0), | 472 level(0), |
| 473 script(USCRIPT_INVALID_CODE), | 473 script(USCRIPT_INVALID_CODE), |
| 474 glyph_count(static_cast<size_t>(-1)), | 474 glyph_count(static_cast<size_t>(-1)), |
| 475 font_size(0), | 475 font_size(0), |
| 476 baseline_offset(0), | |
| 477 baseline_type(0), | |
| 476 font_style(0), | 478 font_style(0), |
| 477 strike(false), | 479 strike(false), |
| 478 diagonal_strike(false), | 480 diagonal_strike(false), |
| 479 underline(false) {} | 481 underline(false) {} |
| 480 | 482 |
| 481 TextRunHarfBuzz::~TextRunHarfBuzz() {} | 483 TextRunHarfBuzz::~TextRunHarfBuzz() {} |
| 482 | 484 |
| 483 void TextRunHarfBuzz::GetClusterAt(size_t pos, | 485 void TextRunHarfBuzz::GetClusterAt(size_t pos, |
| 484 Range* chars, | 486 Range* chars, |
| 485 Range* glyphs) const { | 487 Range* glyphs) const { |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 960 background_is_transparent()); | 962 background_is_transparent()); |
| 961 Range glyphs_range = run.CharRangeToGlyphRange(segment.char_range); | 963 Range glyphs_range = run.CharRangeToGlyphRange(segment.char_range); |
| 962 scoped_ptr<SkPoint[]> positions(new SkPoint[glyphs_range.length()]); | 964 scoped_ptr<SkPoint[]> positions(new SkPoint[glyphs_range.length()]); |
| 963 SkScalar offset_x = | 965 SkScalar offset_x = |
| 964 preceding_segment_widths - run.positions[glyphs_range.start()].x(); | 966 preceding_segment_widths - run.positions[glyphs_range.start()].x(); |
| 965 for (size_t j = 0; j < glyphs_range.length(); ++j) { | 967 for (size_t j = 0; j < glyphs_range.length(); ++j) { |
| 966 positions[j] = run.positions[(glyphs_range.is_reversed()) ? | 968 positions[j] = run.positions[(glyphs_range.is_reversed()) ? |
| 967 (glyphs_range.start() - j) : | 969 (glyphs_range.start() - j) : |
| 968 (glyphs_range.start() + j)]; | 970 (glyphs_range.start() + j)]; |
| 969 positions[j].offset(SkIntToScalar(origin.x()) + offset_x, | 971 positions[j].offset(SkIntToScalar(origin.x()) + offset_x, |
| 970 SkIntToScalar(origin.y())); | 972 SkIntToScalar(origin.y() + run.baseline_offset)); |
| 971 } | 973 } |
| 972 for (BreakList<SkColor>::const_iterator it = | 974 for (BreakList<SkColor>::const_iterator it = |
| 973 colors().GetBreak(segment.char_range.start()); | 975 colors().GetBreak(segment.char_range.start()); |
| 974 it != colors().breaks().end() && | 976 it != colors().breaks().end() && |
| 975 it->first < segment.char_range.end(); | 977 it->first < segment.char_range.end(); |
| 976 ++it) { | 978 ++it) { |
| 977 const Range intersection = | 979 const Range intersection = |
| 978 colors().GetRange(it).Intersect(segment.char_range); | 980 colors().GetRange(it).Intersect(segment.char_range); |
| 979 const Range colored_glyphs = run.CharRangeToGlyphRange(intersection); | 981 const Range colored_glyphs = run.CharRangeToGlyphRange(intersection); |
| 980 // The range may be empty if a portion of a multi-character grapheme is | 982 // The range may be empty if a portion of a multi-character grapheme is |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1076 // empty color BreakList to avoid breaking runs at color boundaries. | 1078 // empty color BreakList to avoid breaking runs at color boundaries. |
| 1077 BreakList<SkColor> empty_colors; | 1079 BreakList<SkColor> empty_colors; |
| 1078 empty_colors.SetMax(text.length()); | 1080 empty_colors.SetMax(text.length()); |
| 1079 internal::StyleIterator style(empty_colors, styles()); | 1081 internal::StyleIterator style(empty_colors, styles()); |
| 1080 | 1082 |
| 1081 for (size_t run_break = 0; run_break < text.length();) { | 1083 for (size_t run_break = 0; run_break < text.length();) { |
| 1082 internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz; | 1084 internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz; |
| 1083 run->range.set_start(run_break); | 1085 run->range.set_start(run_break); |
| 1084 run->font_style = (style.style(BOLD) ? Font::BOLD : 0) | | 1086 run->font_style = (style.style(BOLD) ? Font::BOLD : 0) | |
| 1085 (style.style(ITALIC) ? Font::ITALIC : 0); | 1087 (style.style(ITALIC) ? Font::ITALIC : 0); |
| 1088 if (style.style(SUPERSCRIPT)) { | |
| 1089 run->baseline_type = SUPERSCRIPT; | |
| 1090 } | |
| 1091 if (style.style(SUPERIOR)) { | |
| 1092 run->baseline_type = SUPERIOR; | |
| 1093 } | |
| 1094 if (style.style(INFERIOR)) { | |
| 1095 run->baseline_type = INFERIOR; | |
| 1096 } | |
| 1097 if (style.style(SUBSCRIPT)) { | |
| 1098 run->baseline_type = SUBSCRIPT; | |
| 1099 } | |
| 1086 run->strike = style.style(STRIKE); | 1100 run->strike = style.style(STRIKE); |
| 1087 run->diagonal_strike = style.style(DIAGONAL_STRIKE); | 1101 run->diagonal_strike = style.style(DIAGONAL_STRIKE); |
| 1088 run->underline = style.style(UNDERLINE); | 1102 run->underline = style.style(UNDERLINE); |
| 1089 | 1103 |
| 1090 int32 script_item_break = 0; | 1104 int32 script_item_break = 0; |
| 1091 bidi_iterator.GetLogicalRun(run_break, &script_item_break, &run->level); | 1105 bidi_iterator.GetLogicalRun(run_break, &script_item_break, &run->level); |
| 1092 // Odd BiDi embedding levels correspond to RTL runs. | 1106 // Odd BiDi embedding levels correspond to RTL runs. |
| 1093 run->is_rtl = (run->level % 2) == 1; | 1107 run->is_rtl = (run->level % 2) == 1; |
| 1094 // Find the length and script of this script run. | 1108 // Find the length and script of this script run. |
| 1095 script_item_break = ScriptInterval(text, run_break, | 1109 script_item_break = ScriptInterval(text, run_break, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1142 *best_render_params = render_params; | 1156 *best_render_params = render_params; |
| 1143 *best_missing_glyphs = missing_glyphs; | 1157 *best_missing_glyphs = missing_glyphs; |
| 1144 } | 1158 } |
| 1145 return missing_glyphs == 0; | 1159 return missing_glyphs == 0; |
| 1146 } | 1160 } |
| 1147 | 1161 |
| 1148 void RenderTextHarfBuzz::ShapeRun(internal::TextRunHarfBuzz* run) { | 1162 void RenderTextHarfBuzz::ShapeRun(internal::TextRunHarfBuzz* run) { |
| 1149 const Font& primary_font = font_list().GetPrimaryFont(); | 1163 const Font& primary_font = font_list().GetPrimaryFont(); |
| 1150 const std::string primary_family = primary_font.GetFontName(); | 1164 const std::string primary_family = primary_font.GetFontName(); |
| 1151 run->font_size = primary_font.GetFontSize(); | 1165 run->font_size = primary_font.GetFontSize(); |
| 1166 if (run->baseline_type) { | |
| 1167 // Calculate a slightly smaller font. | |
|
msw
2015/02/17 23:32:06
nit: remove the line break in the comment.
dschuyler
2015/02/18 01:37:27
Done.
| |
| 1168 // The ratio here is somewhat arbitrary. Proportions from 5/9 to 5/7 all | |
| 1169 // look pretty good. Feel free to change this if someone on the UX team | |
|
msw
2015/02/17 23:32:06
nit: omit the "Feel free" sentence.
dschuyler
2015/02/18 01:37:27
Done.
| |
| 1170 // feels that the smaller script should be slightly different. | |
| 1171 const float ratio = 5.0f / 9.0f; | |
| 1172 run->font_size = round(primary_font.GetFontSize() * ratio); | |
| 1173 int cap_height = round(primary_font.GetCapHeight() * ratio); | |
| 1174 switch (run->baseline_type) { | |
| 1175 case SUPERSCRIPT: | |
| 1176 run->baseline_offset = | |
| 1177 primary_font.GetCapHeight() - primary_font.GetHeight(); | |
| 1178 break; | |
| 1179 case SUPERIOR: | |
| 1180 run->baseline_offset = cap_height - primary_font.GetCapHeight(); | |
| 1181 break; | |
| 1182 case INFERIOR: | |
| 1183 run->baseline_offset = 0; | |
| 1184 break; | |
| 1185 case SUBSCRIPT: | |
| 1186 run->baseline_offset = | |
| 1187 primary_font.GetHeight() - primary_font.GetBaseline(); | |
| 1188 break; | |
| 1189 } | |
| 1190 } | |
| 1152 | 1191 |
| 1153 std::string best_family; | 1192 std::string best_family; |
| 1154 FontRenderParams best_render_params; | 1193 FontRenderParams best_render_params; |
| 1155 size_t best_missing_glyphs = std::numeric_limits<size_t>::max(); | 1194 size_t best_missing_glyphs = std::numeric_limits<size_t>::max(); |
| 1156 | 1195 |
| 1157 for (const Font& font : font_list().GetFonts()) { | 1196 for (const Font& font : font_list().GetFonts()) { |
| 1158 if (CompareFamily(run, font.GetFontName(), font.GetFontRenderParams(), | 1197 if (CompareFamily(run, font.GetFontName(), font.GetFontRenderParams(), |
| 1159 &best_family, &best_render_params, &best_missing_glyphs)) | 1198 &best_family, &best_render_params, &best_missing_glyphs)) |
| 1160 return; | 1199 return; |
| 1161 } | 1200 } |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1324 if (!run->render_params.subpixel_positioning) | 1363 if (!run->render_params.subpixel_positioning) |
| 1325 run->width = std::floor(run->width + 0.5f); | 1364 run->width = std::floor(run->width + 0.5f); |
| 1326 } | 1365 } |
| 1327 | 1366 |
| 1328 hb_buffer_destroy(buffer); | 1367 hb_buffer_destroy(buffer); |
| 1329 hb_font_destroy(harfbuzz_font); | 1368 hb_font_destroy(harfbuzz_font); |
| 1330 return true; | 1369 return true; |
| 1331 } | 1370 } |
| 1332 | 1371 |
| 1333 } // namespace gfx | 1372 } // namespace gfx |
| OLD | NEW |