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

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: Refined DoesntClip and DoesClip tests Created 5 years, 9 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"
11 #include "base/i18n/char_iterator.h" 11 #include "base/i18n/char_iterator.h"
12 #include "base/profiler/scoped_tracker.h" 12 #include "base/profiler/scoped_tracker.h"
13 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
14 #include "base/trace_event/trace_event.h" 14 #include "base/trace_event/trace_event.h"
15 #include "third_party/harfbuzz-ng/src/hb.h" 15 #include "third_party/harfbuzz-ng/src/hb.h"
16 #include "third_party/icu/source/common/unicode/ubidi.h" 16 #include "third_party/icu/source/common/unicode/ubidi.h"
17 #include "third_party/skia/include/core/SkColor.h" 17 #include "third_party/skia/include/core/SkColor.h"
18 #include "third_party/skia/include/core/SkTypeface.h" 18 #include "third_party/skia/include/core/SkTypeface.h"
19 #include "ui/gfx/canvas.h" 19 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/font_fallback.h" 20 #include "ui/gfx/font_fallback.h"
21 #include "ui/gfx/font_render_params.h" 21 #include "ui/gfx/font_render_params.h"
22 #include "ui/gfx/geometry/safe_integer_conversions.h"
22 #include "ui/gfx/harfbuzz_font_skia.h" 23 #include "ui/gfx/harfbuzz_font_skia.h"
23 #include "ui/gfx/range/range_f.h" 24 #include "ui/gfx/range/range_f.h"
24 #include "ui/gfx/utf16_indexing.h" 25 #include "ui/gfx/utf16_indexing.h"
25 26
26 #if defined(OS_WIN) 27 #if defined(OS_WIN)
27 #include "ui/gfx/font_fallback_win.h" 28 #include "ui/gfx/font_fallback_win.h"
28 #endif 29 #endif
29 30
30 using gfx::internal::RoundRangeF; 31 using gfx::internal::RoundRangeF;
31 32
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 } 475 }
475 476
476 TextRunHarfBuzz::TextRunHarfBuzz() 477 TextRunHarfBuzz::TextRunHarfBuzz()
477 : width(0.0f), 478 : width(0.0f),
478 preceding_run_widths(0.0f), 479 preceding_run_widths(0.0f),
479 is_rtl(false), 480 is_rtl(false),
480 level(0), 481 level(0),
481 script(USCRIPT_INVALID_CODE), 482 script(USCRIPT_INVALID_CODE),
482 glyph_count(static_cast<size_t>(-1)), 483 glyph_count(static_cast<size_t>(-1)),
483 font_size(0), 484 font_size(0),
485 baseline_offset(0),
486 baseline_type(0),
484 font_style(0), 487 font_style(0),
485 strike(false), 488 strike(false),
486 diagonal_strike(false), 489 diagonal_strike(false),
487 underline(false) {} 490 underline(false) {
491 }
488 492
489 TextRunHarfBuzz::~TextRunHarfBuzz() {} 493 TextRunHarfBuzz::~TextRunHarfBuzz() {}
490 494
491 void TextRunHarfBuzz::GetClusterAt(size_t pos, 495 void TextRunHarfBuzz::GetClusterAt(size_t pos,
492 Range* chars, 496 Range* chars,
493 Range* glyphs) const { 497 Range* glyphs) const {
494 DCHECK(range.Contains(Range(pos, pos + 1))); 498 DCHECK(range.Contains(Range(pos, pos + 1)));
495 DCHECK(chars); 499 DCHECK(chars);
496 DCHECK(glyphs); 500 DCHECK(glyphs);
497 501
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 scoped_ptr<SkPoint[]> positions(new SkPoint[glyphs_range.length()]); 1027 scoped_ptr<SkPoint[]> positions(new SkPoint[glyphs_range.length()]);
1024 SkScalar offset_x = preceding_segment_widths - 1028 SkScalar offset_x = preceding_segment_widths -
1025 ((glyphs_range.GetMin() != 0) 1029 ((glyphs_range.GetMin() != 0)
1026 ? run.positions[glyphs_range.GetMin()].x() 1030 ? run.positions[glyphs_range.GetMin()].x()
1027 : 0); 1031 : 0);
1028 for (size_t j = 0; j < glyphs_range.length(); ++j) { 1032 for (size_t j = 0; j < glyphs_range.length(); ++j) {
1029 positions[j] = run.positions[(glyphs_range.is_reversed()) ? 1033 positions[j] = run.positions[(glyphs_range.is_reversed()) ?
1030 (glyphs_range.start() - j) : 1034 (glyphs_range.start() - j) :
1031 (glyphs_range.start() + j)]; 1035 (glyphs_range.start() + j)];
1032 positions[j].offset(SkIntToScalar(origin.x()) + offset_x, 1036 positions[j].offset(SkIntToScalar(origin.x()) + offset_x,
1033 SkIntToScalar(origin.y())); 1037 SkIntToScalar(origin.y() + run.baseline_offset));
1034 } 1038 }
1035 for (BreakList<SkColor>::const_iterator it = 1039 for (BreakList<SkColor>::const_iterator it =
1036 colors().GetBreak(segment.char_range.start()); 1040 colors().GetBreak(segment.char_range.start());
1037 it != colors().breaks().end() && 1041 it != colors().breaks().end() &&
1038 it->first < segment.char_range.end(); 1042 it->first < segment.char_range.end();
1039 ++it) { 1043 ++it) {
1040 const Range intersection = 1044 const Range intersection =
1041 colors().GetRange(it).Intersect(segment.char_range); 1045 colors().GetRange(it).Intersect(segment.char_range);
1042 const Range colored_glyphs = run.CharRangeToGlyphRange(intersection); 1046 const Range colored_glyphs = run.CharRangeToGlyphRange(intersection);
1043 // The range may be empty if a portion of a multi-character grapheme is 1047 // 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
1132 internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz; 1136 internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz;
1133 run->range = Range(0, text.length()); 1137 run->range = Range(0, text.length());
1134 run_list_out->add(run); 1138 run_list_out->add(run);
1135 run_list_out->InitIndexMap(); 1139 run_list_out->InitIndexMap();
1136 return; 1140 return;
1137 } 1141 }
1138 1142
1139 // Temporarily apply composition underlines and selection colors. 1143 // Temporarily apply composition underlines and selection colors.
1140 ApplyCompositionAndSelectionStyles(); 1144 ApplyCompositionAndSelectionStyles();
1141 1145
1142 // Build the list of runs from the script items and ranged styles. Use an 1146 // Build the run list from the script items and ranged styles and baselines.
1143 // empty color BreakList to avoid breaking runs at color boundaries. 1147 // Use an empty color BreakList to avoid breaking runs at color boundaries.
1144 BreakList<SkColor> empty_colors; 1148 BreakList<SkColor> empty_colors;
1145 empty_colors.SetMax(text.length()); 1149 empty_colors.SetMax(text.length());
1146 internal::StyleIterator style(empty_colors, styles()); 1150 internal::StyleIterator style(empty_colors, baselines(), styles());
1147 1151
1148 for (size_t run_break = 0; run_break < text.length();) { 1152 for (size_t run_break = 0; run_break < text.length();) {
1149 internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz; 1153 internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz;
1150 run->range.set_start(run_break); 1154 run->range.set_start(run_break);
1151 run->font_style = (style.style(BOLD) ? Font::BOLD : 0) | 1155 run->font_style = (style.style(BOLD) ? Font::BOLD : 0) |
1152 (style.style(ITALIC) ? Font::ITALIC : 0); 1156 (style.style(ITALIC) ? Font::ITALIC : 0);
1157 run->baseline_type = style.baseline();
1153 run->strike = style.style(STRIKE); 1158 run->strike = style.style(STRIKE);
1154 run->diagonal_strike = style.style(DIAGONAL_STRIKE); 1159 run->diagonal_strike = style.style(DIAGONAL_STRIKE);
1155 run->underline = style.style(UNDERLINE); 1160 run->underline = style.style(UNDERLINE);
1156 int32 script_item_break = 0; 1161 int32 script_item_break = 0;
1157 bidi_iterator.GetLogicalRun(run_break, &script_item_break, &run->level); 1162 bidi_iterator.GetLogicalRun(run_break, &script_item_break, &run->level);
1158 // Odd BiDi embedding levels correspond to RTL runs. 1163 // Odd BiDi embedding levels correspond to RTL runs.
1159 run->is_rtl = (run->level % 2) == 1; 1164 run->is_rtl = (run->level % 2) == 1;
1160 // Find the length and script of this script run. 1165 // Find the length and script of this script run.
1161 script_item_break = ScriptInterval(text, run_break, 1166 script_item_break = ScriptInterval(text, run_break,
1162 script_item_break - run_break, &run->script) + run_break; 1167 script_item_break - run_break, &run->script) + run_break;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1211 for (auto* run : run_list->runs()) 1216 for (auto* run : run_list->runs())
1212 ShapeRun(text, run); 1217 ShapeRun(text, run);
1213 run_list->ComputePrecedingRunWidths(); 1218 run_list->ComputePrecedingRunWidths();
1214 } 1219 }
1215 1220
1216 void RenderTextHarfBuzz::ShapeRun(const base::string16& text, 1221 void RenderTextHarfBuzz::ShapeRun(const base::string16& text,
1217 internal::TextRunHarfBuzz* run) { 1222 internal::TextRunHarfBuzz* run) {
1218 const Font& primary_font = font_list().GetPrimaryFont(); 1223 const Font& primary_font = font_list().GetPrimaryFont();
1219 const std::string primary_family = primary_font.GetFontName(); 1224 const std::string primary_family = primary_font.GetFontName();
1220 run->font_size = primary_font.GetFontSize(); 1225 run->font_size = primary_font.GetFontSize();
1226 run->baseline_offset = 0;
1227 if (run->baseline_type != NORMAL_BASELINE) {
1228 // Calculate a slightly smaller font. The ratio here is somewhat arbitrary.
1229 // Proportions from 5/9 to 5/7 all look pretty good.
1230 const float ratio = 5.0f / 9.0f;
1231 run->font_size = gfx::ToRoundedInt(primary_font.GetFontSize() * ratio);
1232 switch (run->baseline_type) {
1233 case SUPERSCRIPT:
1234 run->baseline_offset =
1235 primary_font.GetCapHeight() - primary_font.GetHeight();
1236 break;
1237 case SUPERIOR:
1238 run->baseline_offset =
1239 gfx::ToRoundedInt(primary_font.GetCapHeight() * ratio) -
1240 primary_font.GetCapHeight();
1241 break;
1242 case SUBSCRIPT:
1243 run->baseline_offset =
1244 primary_font.GetHeight() - primary_font.GetBaseline();
1245 break;
1246 case INFERIOR: // Fall through.
1247 default:
1248 break;
1249 }
1250 }
1221 1251
1222 std::string best_family; 1252 std::string best_family;
1223 FontRenderParams best_render_params; 1253 FontRenderParams best_render_params;
1224 size_t best_missing_glyphs = std::numeric_limits<size_t>::max(); 1254 size_t best_missing_glyphs = std::numeric_limits<size_t>::max();
1225 1255
1226 for (const Font& font : font_list().GetFonts()) { 1256 for (const Font& font : font_list().GetFonts()) {
1227 if (CompareFamily(text, font.GetFontName(), font.GetFontRenderParams(), 1257 if (CompareFamily(text, font.GetFontName(), font.GetFontRenderParams(),
1228 run, &best_family, &best_render_params, 1258 run, &best_family, &best_render_params,
1229 &best_missing_glyphs)) 1259 &best_missing_glyphs))
1230 return; 1260 return;
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 DCHECK(!update_layout_run_list_); 1498 DCHECK(!update_layout_run_list_);
1469 DCHECK(!update_display_run_list_); 1499 DCHECK(!update_display_run_list_);
1470 return text_elided() ? display_run_list_.get() : &layout_run_list_; 1500 return text_elided() ? display_run_list_.get() : &layout_run_list_;
1471 } 1501 }
1472 1502
1473 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const { 1503 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const {
1474 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList(); 1504 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList();
1475 } 1505 }
1476 1506
1477 } // namespace gfx 1507 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698