| 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 <map> | 7 #include <map> |
| 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 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 strike(false), | 386 strike(false), |
| 387 diagonal_strike(false), | 387 diagonal_strike(false), |
| 388 underline(false) {} | 388 underline(false) {} |
| 389 | 389 |
| 390 TextRunHarfBuzz::~TextRunHarfBuzz() {} | 390 TextRunHarfBuzz::~TextRunHarfBuzz() {} |
| 391 | 391 |
| 392 size_t TextRunHarfBuzz::CharToGlyph(size_t pos) const { | 392 size_t TextRunHarfBuzz::CharToGlyph(size_t pos) const { |
| 393 DCHECK(range.start() <= pos && pos < range.end()); | 393 DCHECK(range.start() <= pos && pos < range.end()); |
| 394 | 394 |
| 395 if (!is_rtl) { | 395 if (!is_rtl) { |
| 396 for (size_t i = 0; i < glyph_count - 1; ++i) { | 396 size_t cluster_start = 0; |
| 397 if (pos < glyph_to_char[i + 1]) | 397 for (size_t i = 1; i < glyph_count && pos >= glyph_to_char[i]; ++i) |
| 398 return i; | 398 if (glyph_to_char[i] != glyph_to_char[i - 1]) |
| 399 } | 399 cluster_start = i; |
| 400 return glyph_count - 1; | 400 return cluster_start; |
| 401 } | 401 } |
| 402 | 402 |
| 403 for (size_t i = 0; i < glyph_count; ++i) { | 403 for (size_t i = 0; i < glyph_count; ++i) { |
| 404 if (pos >= glyph_to_char[i]) | 404 if (pos >= glyph_to_char[i]) |
| 405 return i; | 405 return i; |
| 406 } | 406 } |
| 407 NOTREACHED(); | 407 NOTREACHED(); |
| 408 return 0; | 408 return 0; |
| 409 } | 409 } |
| 410 | 410 |
| 411 Range TextRunHarfBuzz::CharRangeToGlyphRange(const Range& range) const { | 411 Range TextRunHarfBuzz::CharRangeToGlyphRange(const Range& char_range) const { |
| 412 DCHECK(range.Contains(range)); | 412 DCHECK(range.Contains(char_range)); |
| 413 DCHECK(!range.is_reversed()); | 413 DCHECK(!char_range.is_reversed()); |
| 414 DCHECK(!range.is_empty()); | 414 DCHECK(!char_range.is_empty()); |
| 415 | 415 |
| 416 const size_t first = CharToGlyph(range.start()); | 416 size_t first = 0; |
| 417 const size_t last = CharToGlyph(range.end() - 1); | 417 size_t last = 0; |
| 418 // TODO(ckocagil): What happens when the character has zero or multiple | 418 |
| 419 // glyphs? Is the "+ 1" below correct then? | 419 if (is_rtl) { |
| 420 return Range(std::min(first, last), std::max(first, last) + 1); | 420 // For RTL runs, we subtract 1 from |char_range| to get the leading edges. |
| 421 last = CharToGlyph(char_range.end() - 1); |
| 422 // Loop until we find a non-empty glyph range. For multi-character clusters, |
| 423 // the loop is needed to find the cluster end. Do the same for LTR below. |
| 424 for (size_t i = char_range.start(); i > range.start(); --i) { |
| 425 first = CharToGlyph(i - 1); |
| 426 if (first != last) |
| 427 return Range(last, first); |
| 428 } |
| 429 return Range(last, glyph_count); |
| 430 } |
| 431 |
| 432 first = CharToGlyph(char_range.start()); |
| 433 for (size_t i = char_range.end(); i < range.end(); ++i) { |
| 434 last = CharToGlyph(i); |
| 435 if (first != last) |
| 436 return Range(first, last); |
| 437 } |
| 438 return Range(first, glyph_count); |
| 421 } | 439 } |
| 422 | 440 |
| 423 // Returns whether the given shaped run contains any missing glyphs. | 441 // Returns whether the given shaped run contains any missing glyphs. |
| 424 bool TextRunHarfBuzz::HasMissingGlyphs() const { | 442 bool TextRunHarfBuzz::HasMissingGlyphs() const { |
| 425 static const int kMissingGlyphId = 0; | 443 static const int kMissingGlyphId = 0; |
| 426 for (size_t i = 0; i < glyph_count; ++i) { | 444 for (size_t i = 0; i < glyph_count; ++i) { |
| 427 if (glyphs[i] == kMissingGlyphId) | 445 if (glyphs[i] == kMissingGlyphId) |
| 428 return true; | 446 return true; |
| 429 } | 447 } |
| 430 return false; | 448 return false; |
| (...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 run->positions[i].set(run->width + x_offset, y_offset); | 990 run->positions[i].set(run->width + x_offset, y_offset); |
| 973 run->width += | 991 run->width += |
| 974 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].x_advance)); | 992 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].x_advance)); |
| 975 } | 993 } |
| 976 | 994 |
| 977 hb_buffer_destroy(buffer); | 995 hb_buffer_destroy(buffer); |
| 978 hb_font_destroy(harfbuzz_font); | 996 hb_font_destroy(harfbuzz_font); |
| 979 } | 997 } |
| 980 | 998 |
| 981 } // namespace gfx | 999 } // namespace gfx |
| OLD | NEW |