Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Side by Side Diff: ui/gfx/render_text_harfbuzz.cc

Issue 924543004: adding baseline options for super/sub scripting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moved RestoreBreakList to file local function Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 } 468 }
469 469
470 TextRunHarfBuzz::TextRunHarfBuzz() 470 TextRunHarfBuzz::TextRunHarfBuzz()
471 : width(0.0f), 471 : width(0.0f),
472 preceding_run_widths(0.0f), 472 preceding_run_widths(0.0f),
473 is_rtl(false), 473 is_rtl(false),
474 level(0), 474 level(0),
475 script(USCRIPT_INVALID_CODE), 475 script(USCRIPT_INVALID_CODE),
476 glyph_count(static_cast<size_t>(-1)), 476 glyph_count(static_cast<size_t>(-1)),
477 font_size(0), 477 font_size(0),
478 baseline_offset(0),
479 baseline_type(0),
478 font_style(0), 480 font_style(0),
479 strike(false), 481 strike(false),
480 diagonal_strike(false), 482 diagonal_strike(false),
481 underline(false) {} 483 underline(false) {}
482 484
483 TextRunHarfBuzz::~TextRunHarfBuzz() {} 485 TextRunHarfBuzz::~TextRunHarfBuzz() {}
484 486
485 void TextRunHarfBuzz::GetClusterAt(size_t pos, 487 void TextRunHarfBuzz::GetClusterAt(size_t pos,
486 Range* chars, 488 Range* chars,
487 Range* glyphs) const { 489 Range* glyphs) const {
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 background_is_transparent()); 1014 background_is_transparent());
1013 Range glyphs_range = run.CharRangeToGlyphRange(segment.char_range); 1015 Range glyphs_range = run.CharRangeToGlyphRange(segment.char_range);
1014 scoped_ptr<SkPoint[]> positions(new SkPoint[glyphs_range.length()]); 1016 scoped_ptr<SkPoint[]> positions(new SkPoint[glyphs_range.length()]);
1015 SkScalar offset_x = 1017 SkScalar offset_x =
1016 preceding_segment_widths - run.positions[glyphs_range.start()].x(); 1018 preceding_segment_widths - run.positions[glyphs_range.start()].x();
1017 for (size_t j = 0; j < glyphs_range.length(); ++j) { 1019 for (size_t j = 0; j < glyphs_range.length(); ++j) {
1018 positions[j] = run.positions[(glyphs_range.is_reversed()) ? 1020 positions[j] = run.positions[(glyphs_range.is_reversed()) ?
1019 (glyphs_range.start() - j) : 1021 (glyphs_range.start() - j) :
1020 (glyphs_range.start() + j)]; 1022 (glyphs_range.start() + j)];
1021 positions[j].offset(SkIntToScalar(origin.x()) + offset_x, 1023 positions[j].offset(SkIntToScalar(origin.x()) + offset_x,
1022 SkIntToScalar(origin.y())); 1024 SkIntToScalar(origin.y() + run.baseline_offset));
1023 } 1025 }
1024 for (BreakList<SkColor>::const_iterator it = 1026 for (BreakList<SkColor>::const_iterator it =
1025 colors().GetBreak(segment.char_range.start()); 1027 colors().GetBreak(segment.char_range.start());
1026 it != colors().breaks().end() && 1028 it != colors().breaks().end() &&
1027 it->first < segment.char_range.end(); 1029 it->first < segment.char_range.end();
1028 ++it) { 1030 ++it) {
1029 const Range intersection = 1031 const Range intersection =
1030 colors().GetRange(it).Intersect(segment.char_range); 1032 colors().GetRange(it).Intersect(segment.char_range);
1031 const Range colored_glyphs = run.CharRangeToGlyphRange(intersection); 1033 const Range colored_glyphs = run.CharRangeToGlyphRange(intersection);
1032 // The range may be empty if a portion of a multi-character grapheme is 1034 // The range may be empty if a portion of a multi-character grapheme is
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz; 1123 internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz;
1122 run->range = Range(0, text.length()); 1124 run->range = Range(0, text.length());
1123 run_list_out->add(run); 1125 run_list_out->add(run);
1124 run_list_out->InitIndexMap(); 1126 run_list_out->InitIndexMap();
1125 return; 1127 return;
1126 } 1128 }
1127 1129
1128 // Temporarily apply composition underlines and selection colors. 1130 // Temporarily apply composition underlines and selection colors.
1129 ApplyCompositionAndSelectionStyles(); 1131 ApplyCompositionAndSelectionStyles();
1130 1132
1131 // Build the list of runs from the script items and ranged styles. Use an 1133 // Build the run list from the script items and ranges styles and baselines.
msw 2015/02/19 02:50:57 nit: d'oh sorry, s/ranges/ranged/... my fault!
dschuyler 2015/02/25 02:23:06 Done.
1132 // empty color BreakList to avoid breaking runs at color boundaries. 1134 // Use an empty color BreakList to avoid breaking runs at color boundaries.
1133 BreakList<SkColor> empty_colors; 1135 BreakList<SkColor> empty_colors;
1134 empty_colors.SetMax(text.length()); 1136 empty_colors.SetMax(text.length());
1135 internal::StyleIterator style(empty_colors, styles()); 1137 internal::StyleIterator style(empty_colors, baselines(), styles());
1136 1138
1137 for (size_t run_break = 0; run_break < text.length();) { 1139 for (size_t run_break = 0; run_break < text.length();) {
1138 internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz; 1140 internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz;
1139 run->range.set_start(run_break); 1141 run->range.set_start(run_break);
1140 run->font_style = (style.style(BOLD) ? Font::BOLD : 0) | 1142 run->font_style = (style.style(BOLD) ? Font::BOLD : 0) |
1141 (style.style(ITALIC) ? Font::ITALIC : 0); 1143 (style.style(ITALIC) ? Font::ITALIC : 0);
1144 run->baseline_type = style.baseline();
1142 run->strike = style.style(STRIKE); 1145 run->strike = style.style(STRIKE);
1143 run->diagonal_strike = style.style(DIAGONAL_STRIKE); 1146 run->diagonal_strike = style.style(DIAGONAL_STRIKE);
1144 run->underline = style.style(UNDERLINE); 1147 run->underline = style.style(UNDERLINE);
1145 int32 script_item_break = 0; 1148 int32 script_item_break = 0;
1146 bidi_iterator.GetLogicalRun(run_break, &script_item_break, &run->level); 1149 bidi_iterator.GetLogicalRun(run_break, &script_item_break, &run->level);
1147 // Odd BiDi embedding levels correspond to RTL runs. 1150 // Odd BiDi embedding levels correspond to RTL runs.
1148 run->is_rtl = (run->level % 2) == 1; 1151 run->is_rtl = (run->level % 2) == 1;
1149 // Find the length and script of this script run. 1152 // Find the length and script of this script run.
1150 script_item_break = ScriptInterval(text, run_break, 1153 script_item_break = ScriptInterval(text, run_break,
1151 script_item_break - run_break, &run->script) + run_break; 1154 script_item_break - run_break, &run->script) + run_break;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 for (auto* run : run_list->runs()) 1203 for (auto* run : run_list->runs())
1201 ShapeRun(text, run); 1204 ShapeRun(text, run);
1202 run_list->ComputePrecedingRunWidths(); 1205 run_list->ComputePrecedingRunWidths();
1203 } 1206 }
1204 1207
1205 void RenderTextHarfBuzz::ShapeRun(const base::string16& text, 1208 void RenderTextHarfBuzz::ShapeRun(const base::string16& text,
1206 internal::TextRunHarfBuzz* run) { 1209 internal::TextRunHarfBuzz* run) {
1207 const Font& primary_font = font_list().GetPrimaryFont(); 1210 const Font& primary_font = font_list().GetPrimaryFont();
1208 const std::string primary_family = primary_font.GetFontName(); 1211 const std::string primary_family = primary_font.GetFontName();
1209 run->font_size = primary_font.GetFontSize(); 1212 run->font_size = primary_font.GetFontSize();
1213 run->baseline_offset = 0;
1214 if (run->baseline_type != NORMAL_BASELINE) {
1215 // Calculate a slightly smaller font. The ratio here is somewhat arbitrary.
1216 // Proportions from 5/9 to 5/7 all look pretty good.
1217 const float ratio = 5.0f / 9.0f;
1218 run->font_size = std::round(primary_font.GetFontSize() * ratio);
1219 switch (run->baseline_type) {
1220 case SUPERSCRIPT:
1221 run->baseline_offset =
1222 primary_font.GetCapHeight() - primary_font.GetHeight();
1223 break;
1224 case SUPERIOR:
1225 run->baseline_offset = std::round(primary_font.GetCapHeight() * ratio) -
1226 primary_font.GetCapHeight();
1227 break;
1228 case SUBSCRIPT:
1229 run->baseline_offset =
1230 primary_font.GetHeight() - primary_font.GetBaseline();
1231 break;
1232 case INFERIOR: // Fall through.
1233 default:
1234 break;
1235 }
1236 }
1210 1237
1211 std::string best_family; 1238 std::string best_family;
1212 FontRenderParams best_render_params; 1239 FontRenderParams best_render_params;
1213 size_t best_missing_glyphs = std::numeric_limits<size_t>::max(); 1240 size_t best_missing_glyphs = std::numeric_limits<size_t>::max();
1214 1241
1215 for (const Font& font : font_list().GetFonts()) { 1242 for (const Font& font : font_list().GetFonts()) {
1216 if (CompareFamily(text, font.GetFontName(), font.GetFontRenderParams(), 1243 if (CompareFamily(text, font.GetFontName(), font.GetFontRenderParams(),
1217 run, &best_family, &best_render_params, 1244 run, &best_family, &best_render_params,
1218 &best_missing_glyphs)) 1245 &best_missing_glyphs))
1219 return; 1246 return;
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1457 DCHECK(!update_layout_run_list_); 1484 DCHECK(!update_layout_run_list_);
1458 DCHECK(!update_display_run_list_); 1485 DCHECK(!update_display_run_list_);
1459 return text_elided() ? display_run_list_.get() : &layout_run_list_; 1486 return text_elided() ? display_run_list_.get() : &layout_run_list_;
1460 } 1487 }
1461 1488
1462 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const { 1489 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const {
1463 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList(); 1490 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList();
1464 } 1491 }
1465 1492
1466 } // namespace gfx 1493 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698