| 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 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/i18n/bidi_line_iterator.h" | 10 #include "base/i18n/bidi_line_iterator.h" |
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 #if !defined(OS_MACOSX) | 570 #if !defined(OS_MACOSX) |
| 571 sk_sp<SkTypeface> CreateSkiaTypeface(const gfx::Font& font, int style) { | 571 sk_sp<SkTypeface> CreateSkiaTypeface(const gfx::Font& font, int style) { |
| 572 int skia_style = SkTypeface::kNormal; | 572 int skia_style = SkTypeface::kNormal; |
| 573 skia_style |= (style & Font::BOLD) ? SkTypeface::kBold : 0; | 573 skia_style |= (style & Font::BOLD) ? SkTypeface::kBold : 0; |
| 574 skia_style |= (style & Font::ITALIC) ? SkTypeface::kItalic : 0; | 574 skia_style |= (style & Font::ITALIC) ? SkTypeface::kItalic : 0; |
| 575 return sk_sp<SkTypeface>(SkTypeface::CreateFromName( | 575 return sk_sp<SkTypeface>(SkTypeface::CreateFromName( |
| 576 font.GetFontName().c_str(), static_cast<SkTypeface::Style>(skia_style))); | 576 font.GetFontName().c_str(), static_cast<SkTypeface::Style>(skia_style))); |
| 577 } | 577 } |
| 578 #endif | 578 #endif |
| 579 | 579 |
| 580 TextRunHarfBuzz::TextRunHarfBuzz() | 580 TextRunHarfBuzz::TextRunHarfBuzz(const gfx::Font& template_font) |
| 581 : width(0.0f), | 581 : width(0.0f), |
| 582 preceding_run_widths(0.0f), | 582 preceding_run_widths(0.0f), |
| 583 is_rtl(false), | 583 is_rtl(false), |
| 584 level(0), | 584 level(0), |
| 585 script(USCRIPT_INVALID_CODE), | 585 script(USCRIPT_INVALID_CODE), |
| 586 glyph_count(static_cast<size_t>(-1)), | 586 glyph_count(static_cast<size_t>(-1)), |
| 587 font(template_font), |
| 587 font_size(0), | 588 font_size(0), |
| 588 baseline_offset(0), | 589 baseline_offset(0), |
| 589 baseline_type(0), | 590 baseline_type(0), |
| 590 font_style(0), | 591 font_style(0), |
| 591 strike(false), | 592 strike(false), |
| 592 diagonal_strike(false), | 593 diagonal_strike(false), |
| 593 underline(false) { | 594 underline(false) {} |
| 594 } | |
| 595 | 595 |
| 596 TextRunHarfBuzz::~TextRunHarfBuzz() {} | 596 TextRunHarfBuzz::~TextRunHarfBuzz() {} |
| 597 | 597 |
| 598 Range TextRunHarfBuzz::CharRangeToGlyphRange(const Range& char_range) const { | 598 Range TextRunHarfBuzz::CharRangeToGlyphRange(const Range& char_range) const { |
| 599 DCHECK(range.Contains(char_range)); | 599 DCHECK(range.Contains(char_range)); |
| 600 DCHECK(!char_range.is_reversed()); | 600 DCHECK(!char_range.is_reversed()); |
| 601 DCHECK(!char_range.is_empty()); | 601 DCHECK(!char_range.is_empty()); |
| 602 | 602 |
| 603 Range start_glyphs; | 603 Range start_glyphs; |
| 604 Range end_glyphs; | 604 Range end_glyphs; |
| (...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1248 void RenderTextHarfBuzz::ItemizeTextToRuns( | 1248 void RenderTextHarfBuzz::ItemizeTextToRuns( |
| 1249 const base::string16& text, | 1249 const base::string16& text, |
| 1250 internal::TextRunList* run_list_out) { | 1250 internal::TextRunList* run_list_out) { |
| 1251 DCHECK_NE(0U, text.length()); | 1251 DCHECK_NE(0U, text.length()); |
| 1252 | 1252 |
| 1253 // If ICU fails to itemize the text, we create a run that spans the entire | 1253 // If ICU fails to itemize the text, we create a run that spans the entire |
| 1254 // text. This is needed because leaving the runs set empty causes some clients | 1254 // text. This is needed because leaving the runs set empty causes some clients |
| 1255 // to misbehave since they expect non-zero text metrics from a non-empty text. | 1255 // to misbehave since they expect non-zero text metrics from a non-empty text. |
| 1256 base::i18n::BiDiLineIterator bidi_iterator; | 1256 base::i18n::BiDiLineIterator bidi_iterator; |
| 1257 if (!bidi_iterator.Open(text, GetTextDirection(text))) { | 1257 if (!bidi_iterator.Open(text, GetTextDirection(text))) { |
| 1258 internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz; | 1258 internal::TextRunHarfBuzz* run = |
| 1259 new internal::TextRunHarfBuzz(font_list().GetPrimaryFont()); |
| 1259 run->range = Range(0, text.length()); | 1260 run->range = Range(0, text.length()); |
| 1260 run_list_out->add(run); | 1261 run_list_out->add(run); |
| 1261 run_list_out->InitIndexMap(); | 1262 run_list_out->InitIndexMap(); |
| 1262 return; | 1263 return; |
| 1263 } | 1264 } |
| 1264 | 1265 |
| 1265 // Temporarily apply composition underlines and selection colors. | 1266 // Temporarily apply composition underlines and selection colors. |
| 1266 ApplyCompositionAndSelectionStyles(); | 1267 ApplyCompositionAndSelectionStyles(); |
| 1267 | 1268 |
| 1268 // Build the run list from the script items and ranged styles and baselines. | 1269 // Build the run list from the script items and ranged styles and baselines. |
| 1269 // Use an empty color BreakList to avoid breaking runs at color boundaries. | 1270 // Use an empty color BreakList to avoid breaking runs at color boundaries. |
| 1270 BreakList<SkColor> empty_colors; | 1271 BreakList<SkColor> empty_colors; |
| 1271 empty_colors.SetMax(text.length()); | 1272 empty_colors.SetMax(text.length()); |
| 1272 DCHECK_LE(text.size(), baselines().max()); | 1273 DCHECK_LE(text.size(), baselines().max()); |
| 1273 for (const BreakList<bool>& style : styles()) | 1274 for (const BreakList<bool>& style : styles()) |
| 1274 DCHECK_LE(text.size(), style.max()); | 1275 DCHECK_LE(text.size(), style.max()); |
| 1275 internal::StyleIterator style(empty_colors, baselines(), styles()); | 1276 internal::StyleIterator style(empty_colors, baselines(), styles()); |
| 1276 | 1277 |
| 1277 for (size_t run_break = 0; run_break < text.length();) { | 1278 for (size_t run_break = 0; run_break < text.length();) { |
| 1278 internal::TextRunHarfBuzz* run = new internal::TextRunHarfBuzz; | 1279 internal::TextRunHarfBuzz* run = |
| 1280 new internal::TextRunHarfBuzz(font_list().GetPrimaryFont()); |
| 1279 run->range.set_start(run_break); | 1281 run->range.set_start(run_break); |
| 1280 run->font_style = (style.style(BOLD) ? Font::BOLD : 0) | | 1282 run->font_style = (style.style(BOLD) ? Font::BOLD : 0) | |
| 1281 (style.style(ITALIC) ? Font::ITALIC : 0); | 1283 (style.style(ITALIC) ? Font::ITALIC : 0); |
| 1282 run->baseline_type = style.baseline(); | 1284 run->baseline_type = style.baseline(); |
| 1283 run->strike = style.style(STRIKE); | 1285 run->strike = style.style(STRIKE); |
| 1284 run->diagonal_strike = style.style(DIAGONAL_STRIKE); | 1286 run->diagonal_strike = style.style(DIAGONAL_STRIKE); |
| 1285 run->underline = style.style(UNDERLINE); | 1287 run->underline = style.style(UNDERLINE); |
| 1286 int32_t script_item_break = 0; | 1288 int32_t script_item_break = 0; |
| 1287 bidi_iterator.GetLogicalRun(run_break, &script_item_break, &run->level); | 1289 bidi_iterator.GetLogicalRun(run_break, &script_item_break, &run->level); |
| 1288 CHECK_GT(static_cast<size_t>(script_item_break), run_break); | 1290 CHECK_GT(static_cast<size_t>(script_item_break), run_break); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1371 case SUBSCRIPT: | 1373 case SUBSCRIPT: |
| 1372 run->baseline_offset = | 1374 run->baseline_offset = |
| 1373 primary_font.GetHeight() - primary_font.GetBaseline(); | 1375 primary_font.GetHeight() - primary_font.GetBaseline(); |
| 1374 break; | 1376 break; |
| 1375 case INFERIOR: // Fall through. | 1377 case INFERIOR: // Fall through. |
| 1376 default: | 1378 default: |
| 1377 break; | 1379 break; |
| 1378 } | 1380 } |
| 1379 } | 1381 } |
| 1380 | 1382 |
| 1381 Font best_font; | 1383 Font best_font(primary_font); |
| 1382 FontRenderParams best_render_params; | 1384 FontRenderParams best_render_params; |
| 1383 size_t best_missing_glyphs = std::numeric_limits<size_t>::max(); | 1385 size_t best_missing_glyphs = std::numeric_limits<size_t>::max(); |
| 1384 | 1386 |
| 1385 for (const Font& font : font_list().GetFonts()) { | 1387 for (const Font& font : font_list().GetFonts()) { |
| 1386 if (CompareFamily(text, font, font.GetFontRenderParams(), run, &best_font, | 1388 if (CompareFamily(text, font, font.GetFontRenderParams(), run, &best_font, |
| 1387 &best_render_params, &best_missing_glyphs)) | 1389 &best_render_params, &best_missing_glyphs)) |
| 1388 return; | 1390 return; |
| 1389 } | 1391 } |
| 1390 | 1392 |
| 1391 #if defined(OS_WIN) | 1393 #if defined(OS_WIN) |
| 1392 Font uniscribe_font; | 1394 Font uniscribe_font(primary_font); |
| 1393 std::string uniscribe_family; | 1395 std::string uniscribe_family; |
| 1394 const base::char16* run_text = &(text[run->range.start()]); | 1396 const base::char16* run_text = &(text[run->range.start()]); |
| 1395 if (GetUniscribeFallbackFont(primary_font, run_text, run->range.length(), | 1397 if (GetUniscribeFallbackFont(primary_font, run_text, run->range.length(), |
| 1396 &uniscribe_font)) { | 1398 &uniscribe_font)) { |
| 1397 uniscribe_family = uniscribe_font.GetFontName(); | 1399 uniscribe_family = uniscribe_font.GetFontName(); |
| 1398 if (CompareFamily(text, uniscribe_font, | 1400 if (CompareFamily(text, uniscribe_font, |
| 1399 uniscribe_font.GetFontRenderParams(), run, | 1401 uniscribe_font.GetFontRenderParams(), run, |
| 1400 &best_font, &best_render_params, &best_missing_glyphs)) | 1402 &best_font, &best_render_params, &best_missing_glyphs)) |
| 1401 return; | 1403 return; |
| 1402 } | 1404 } |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1580 DCHECK(!update_layout_run_list_); | 1582 DCHECK(!update_layout_run_list_); |
| 1581 DCHECK(!update_display_run_list_); | 1583 DCHECK(!update_display_run_list_); |
| 1582 return text_elided() ? display_run_list_.get() : &layout_run_list_; | 1584 return text_elided() ? display_run_list_.get() : &layout_run_list_; |
| 1583 } | 1585 } |
| 1584 | 1586 |
| 1585 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const { | 1587 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const { |
| 1586 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList(); | 1588 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList(); |
| 1587 } | 1589 } |
| 1588 | 1590 |
| 1589 } // namespace gfx | 1591 } // namespace gfx |
| OLD | NEW |