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

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

Issue 988763005: Change for Win XP (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: test 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
« no previous file with comments | « ui/gfx/render_text_harfbuzz.h ('k') | ui/gfx/render_text_mac.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 line->segments.push_back(segment); 415 line->segments.push_back(segment);
415 416
416 SkPaint paint; 417 SkPaint paint;
417 paint.setTypeface(run.skia_face.get()); 418 paint.setTypeface(run.skia_face.get());
418 paint.setTextSize(SkIntToScalar(run.font_size)); 419 paint.setTextSize(SkIntToScalar(run.font_size));
419 paint.setAntiAlias(run.render_params.antialiasing); 420 paint.setAntiAlias(run.render_params.antialiasing);
420 SkPaint::FontMetrics metrics; 421 SkPaint::FontMetrics metrics;
421 paint.getFontMetrics(&metrics); 422 paint.getFontMetrics(&metrics);
422 423
423 line->size.set_width(line->size.width() + width); 424 line->size.set_width(line->size.width() + width);
425 // TODO(dschuyler): Account for stylized baselines in string sizing.
424 max_descent_ = std::max(max_descent_, metrics.fDescent); 426 max_descent_ = std::max(max_descent_, metrics.fDescent);
425 // fAscent is always negative. 427 // fAscent is always negative.
426 max_ascent_ = std::max(max_ascent_, -metrics.fAscent); 428 max_ascent_ = std::max(max_ascent_, -metrics.fAscent);
427 429
428 if (run.is_rtl) { 430 if (run.is_rtl) {
429 rtl_segments_.push_back( 431 rtl_segments_.push_back(
430 SegmentHandle(lines_.size() - 1, line->segments.size() - 1)); 432 SegmentHandle(lines_.size() - 1, line->segments.size() - 1));
431 // If this is the last segment of an RTL run, reprocess the text-space x 433 // If this is the last segment of an RTL run, reprocess the text-space x
432 // ranges of all segments from the run. 434 // ranges of all segments from the run.
433 if (char_range.end() == run.range.end()) 435 if (char_range.end() == run.range.end())
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 } 476 }
475 477
476 TextRunHarfBuzz::TextRunHarfBuzz() 478 TextRunHarfBuzz::TextRunHarfBuzz()
477 : width(0.0f), 479 : width(0.0f),
478 preceding_run_widths(0.0f), 480 preceding_run_widths(0.0f),
479 is_rtl(false), 481 is_rtl(false),
480 level(0), 482 level(0),
481 script(USCRIPT_INVALID_CODE), 483 script(USCRIPT_INVALID_CODE),
482 glyph_count(static_cast<size_t>(-1)), 484 glyph_count(static_cast<size_t>(-1)),
483 font_size(0), 485 font_size(0),
486 baseline_offset(0),
487 baseline_type(0),
484 font_style(0), 488 font_style(0),
485 strike(false), 489 strike(false),
486 diagonal_strike(false), 490 diagonal_strike(false),
487 underline(false) {} 491 underline(false) {
492 }
488 493
489 TextRunHarfBuzz::~TextRunHarfBuzz() {} 494 TextRunHarfBuzz::~TextRunHarfBuzz() {}
490 495
491 void TextRunHarfBuzz::GetClusterAt(size_t pos, 496 void TextRunHarfBuzz::GetClusterAt(size_t pos,
492 Range* chars, 497 Range* chars,
493 Range* glyphs) const { 498 Range* glyphs) const {
494 DCHECK(range.Contains(Range(pos, pos + 1))); 499 DCHECK(range.Contains(Range(pos, pos + 1)));
495 DCHECK(chars); 500 DCHECK(chars);
496 DCHECK(glyphs); 501 DCHECK(glyphs);
497 502
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 scoped_ptr<SkPoint[]> positions(new SkPoint[glyphs_range.length()]); 1028 scoped_ptr<SkPoint[]> positions(new SkPoint[glyphs_range.length()]);
1024 SkScalar offset_x = preceding_segment_widths - 1029 SkScalar offset_x = preceding_segment_widths -
1025 ((glyphs_range.GetMin() != 0) 1030 ((glyphs_range.GetMin() != 0)
1026 ? run.positions[glyphs_range.GetMin()].x() 1031 ? run.positions[glyphs_range.GetMin()].x()
1027 : 0); 1032 : 0);
1028 for (size_t j = 0; j < glyphs_range.length(); ++j) { 1033 for (size_t j = 0; j < glyphs_range.length(); ++j) {
1029 positions[j] = run.positions[(glyphs_range.is_reversed()) ? 1034 positions[j] = run.positions[(glyphs_range.is_reversed()) ?
1030 (glyphs_range.start() - j) : 1035 (glyphs_range.start() - j) :
1031 (glyphs_range.start() + j)]; 1036 (glyphs_range.start() + j)];
1032 positions[j].offset(SkIntToScalar(origin.x()) + offset_x, 1037 positions[j].offset(SkIntToScalar(origin.x()) + offset_x,
1033 SkIntToScalar(origin.y())); 1038 SkIntToScalar(origin.y() + run.baseline_offset));
1034 } 1039 }
1035 for (BreakList<SkColor>::const_iterator it = 1040 for (BreakList<SkColor>::const_iterator it =
1036 colors().GetBreak(segment.char_range.start()); 1041 colors().GetBreak(segment.char_range.start());
1037 it != colors().breaks().end() && 1042 it != colors().breaks().end() &&
1038 it->first < segment.char_range.end(); 1043 it->first < segment.char_range.end();
1039 ++it) { 1044 ++it) {
1040 const Range intersection = 1045 const Range intersection =
1041 colors().GetRange(it).Intersect(segment.char_range); 1046 colors().GetRange(it).Intersect(segment.char_range);
1042 const Range colored_glyphs = run.CharRangeToGlyphRange(intersection); 1047 const Range colored_glyphs = run.CharRangeToGlyphRange(intersection);
1043 // The range may be empty if a portion of a multi-character grapheme is 1048 // 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; 1137 internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz;
1133 run->range = Range(0, text.length()); 1138 run->range = Range(0, text.length());
1134 run_list_out->add(run); 1139 run_list_out->add(run);
1135 run_list_out->InitIndexMap(); 1140 run_list_out->InitIndexMap();
1136 return; 1141 return;
1137 } 1142 }
1138 1143
1139 // Temporarily apply composition underlines and selection colors. 1144 // Temporarily apply composition underlines and selection colors.
1140 ApplyCompositionAndSelectionStyles(); 1145 ApplyCompositionAndSelectionStyles();
1141 1146
1142 // Build the list of runs from the script items and ranged styles. Use an 1147 // Build the run list from the script items and ranged styles and baselines.
1143 // empty color BreakList to avoid breaking runs at color boundaries. 1148 // Use an empty color BreakList to avoid breaking runs at color boundaries.
1144 BreakList<SkColor> empty_colors; 1149 BreakList<SkColor> empty_colors;
1145 empty_colors.SetMax(text.length()); 1150 empty_colors.SetMax(text.length());
1146 internal::StyleIterator style(empty_colors, styles()); 1151 internal::StyleIterator style(empty_colors, baselines(), styles());
1147 1152
1148 for (size_t run_break = 0; run_break < text.length();) { 1153 for (size_t run_break = 0; run_break < text.length();) {
1149 internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz; 1154 internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz;
1150 run->range.set_start(run_break); 1155 run->range.set_start(run_break);
1151 run->font_style = (style.style(BOLD) ? Font::BOLD : 0) | 1156 run->font_style = (style.style(BOLD) ? Font::BOLD : 0) |
1152 (style.style(ITALIC) ? Font::ITALIC : 0); 1157 (style.style(ITALIC) ? Font::ITALIC : 0);
1158 run->baseline_type = style.baseline();
1153 run->strike = style.style(STRIKE); 1159 run->strike = style.style(STRIKE);
1154 run->diagonal_strike = style.style(DIAGONAL_STRIKE); 1160 run->diagonal_strike = style.style(DIAGONAL_STRIKE);
1155 run->underline = style.style(UNDERLINE); 1161 run->underline = style.style(UNDERLINE);
1156 int32 script_item_break = 0; 1162 int32 script_item_break = 0;
1157 bidi_iterator.GetLogicalRun(run_break, &script_item_break, &run->level); 1163 bidi_iterator.GetLogicalRun(run_break, &script_item_break, &run->level);
1158 // Odd BiDi embedding levels correspond to RTL runs. 1164 // Odd BiDi embedding levels correspond to RTL runs.
1159 run->is_rtl = (run->level % 2) == 1; 1165 run->is_rtl = (run->level % 2) == 1;
1160 // Find the length and script of this script run. 1166 // Find the length and script of this script run.
1161 script_item_break = ScriptInterval(text, run_break, 1167 script_item_break = ScriptInterval(text, run_break,
1162 script_item_break - run_break, &run->script) + run_break; 1168 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()) 1217 for (auto* run : run_list->runs())
1212 ShapeRun(text, run); 1218 ShapeRun(text, run);
1213 run_list->ComputePrecedingRunWidths(); 1219 run_list->ComputePrecedingRunWidths();
1214 } 1220 }
1215 1221
1216 void RenderTextHarfBuzz::ShapeRun(const base::string16& text, 1222 void RenderTextHarfBuzz::ShapeRun(const base::string16& text,
1217 internal::TextRunHarfBuzz* run) { 1223 internal::TextRunHarfBuzz* run) {
1218 const Font& primary_font = font_list().GetPrimaryFont(); 1224 const Font& primary_font = font_list().GetPrimaryFont();
1219 const std::string primary_family = primary_font.GetFontName(); 1225 const std::string primary_family = primary_font.GetFontName();
1220 run->font_size = primary_font.GetFontSize(); 1226 run->font_size = primary_font.GetFontSize();
1227 run->baseline_offset = 0;
1228 if (run->baseline_type != NORMAL_BASELINE) {
1229 // Calculate a slightly smaller font. The ratio here is somewhat arbitrary.
1230 // Proportions from 5/9 to 5/7 all look pretty good.
1231 const float ratio = 5.0f / 9.0f;
1232 run->font_size = gfx::ToRoundedInt(primary_font.GetFontSize() * ratio);
1233 switch (run->baseline_type) {
1234 case SUPERSCRIPT:
1235 run->baseline_offset =
1236 primary_font.GetCapHeight() - primary_font.GetHeight();
1237 break;
1238 case SUPERIOR:
1239 run->baseline_offset =
1240 gfx::ToRoundedInt(primary_font.GetCapHeight() * ratio) -
1241 primary_font.GetCapHeight();
1242 break;
1243 case SUBSCRIPT:
1244 run->baseline_offset =
1245 primary_font.GetHeight() - primary_font.GetBaseline();
1246 break;
1247 case INFERIOR: // Fall through.
1248 default:
1249 break;
1250 }
1251 }
1221 1252
1222 std::string best_family; 1253 std::string best_family;
1223 FontRenderParams best_render_params; 1254 FontRenderParams best_render_params;
1224 size_t best_missing_glyphs = std::numeric_limits<size_t>::max(); 1255 size_t best_missing_glyphs = std::numeric_limits<size_t>::max();
1225 1256
1226 for (const Font& font : font_list().GetFonts()) { 1257 for (const Font& font : font_list().GetFonts()) {
1227 if (CompareFamily(text, font.GetFontName(), font.GetFontRenderParams(), 1258 if (CompareFamily(text, font.GetFontName(), font.GetFontRenderParams(),
1228 run, &best_family, &best_render_params, 1259 run, &best_family, &best_render_params,
1229 &best_missing_glyphs)) 1260 &best_missing_glyphs))
1230 return; 1261 return;
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 DCHECK(!update_layout_run_list_); 1499 DCHECK(!update_layout_run_list_);
1469 DCHECK(!update_display_run_list_); 1500 DCHECK(!update_display_run_list_);
1470 return text_elided() ? display_run_list_.get() : &layout_run_list_; 1501 return text_elided() ? display_run_list_.get() : &layout_run_list_;
1471 } 1502 }
1472 1503
1473 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const { 1504 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const {
1474 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList(); 1505 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList();
1475 } 1506 }
1476 1507
1477 } // namespace gfx 1508 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/render_text_harfbuzz.h ('k') | ui/gfx/render_text_mac.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698