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 |