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; |
msw
2014/06/06 02:00:42
Q: Should RTL find the cluster start too?
ckocagil
2014/06/07 05:40:33
It already returns the cluster start without any s
| |
397 if (pos < glyph_to_char[i + 1]) | 397 for (size_t i = 1; i < glyph_count; ++i) { |
398 return i; | 398 if (pos < glyph_to_char[i]) |
msw
2014/06/06 02:00:42
nit: make this part of the loop's terminating cond
ckocagil
2014/06/07 05:40:33
Done.
| |
399 break; | |
400 if (glyph_to_char[i] != glyph_to_char[i - 1]) | |
401 cluster_start = i; | |
399 } | 402 } |
400 return glyph_count - 1; | 403 return cluster_start; |
401 } | 404 } |
402 | 405 |
403 for (size_t i = 0; i < glyph_count; ++i) { | 406 for (size_t i = 0; i < glyph_count; ++i) { |
404 if (pos >= glyph_to_char[i]) | 407 if (pos >= glyph_to_char[i]) |
405 return i; | 408 return i; |
406 } | 409 } |
407 NOTREACHED(); | 410 NOTREACHED(); |
408 return 0; | 411 return 0; |
409 } | 412 } |
410 | 413 |
411 Range TextRunHarfBuzz::CharRangeToGlyphRange(const Range& range) const { | 414 Range TextRunHarfBuzz::CharRangeToGlyphRange(const Range& char_range) const { |
412 DCHECK(range.Contains(range)); | 415 DCHECK(range.Contains(char_range)); |
413 DCHECK(!range.is_reversed()); | 416 DCHECK(!char_range.is_reversed()); |
414 DCHECK(!range.is_empty()); | 417 DCHECK(!char_range.is_empty()); |
415 | 418 |
416 const size_t first = CharToGlyph(range.start()); | 419 size_t first = 0; |
417 const size_t last = CharToGlyph(range.end() - 1); | 420 size_t last = 0; |
418 // TODO(ckocagil): What happens when the character has zero or multiple | 421 |
419 // glyphs? Is the "+ 1" below correct then? | 422 if (is_rtl) { |
420 return Range(std::min(first, last), std::max(first, last) + 1); | 423 // For RTL runs, we subtract 1 from |char_range| to get the leading edges. |
424 last = CharToGlyph(char_range.end() - 1); | |
425 for (size_t i = char_range.start(); i > range.start(); --i) { | |
msw
2014/06/06 02:00:42
Why do we need these loops now? Maybe add a commen
ckocagil
2014/06/07 05:40:33
Every cluster has a non-empty set of glyphs. CharT
msw
2014/06/08 00:10:17
Hmm, okay I suppose. Can you give me an example wh
ckocagil
2014/06/08 01:30:07
The loops are needed for glyphs that correspond to
msw
2014/06/08 01:58:14
Great explanation, thank you! (it might almost be
ckocagil
2014/06/08 03:15:30
Expanded the comment a bit without getting too det
| |
426 first = CharToGlyph(i - 1); | |
427 if (first != last) | |
428 return Range(last, first); | |
429 } | |
430 return Range(last, glyph_count); | |
431 } | |
432 | |
433 first = CharToGlyph(char_range.start()); | |
434 for (size_t i = char_range.end(); i < range.end(); ++i) { | |
435 last = CharToGlyph(i); | |
436 if (first != last) | |
437 return Range(first, last); | |
438 } | |
439 return Range(first, glyph_count); | |
421 } | 440 } |
422 | 441 |
423 // Returns whether the given shaped run contains any missing glyphs. | 442 // Returns whether the given shaped run contains any missing glyphs. |
424 bool TextRunHarfBuzz::HasMissingGlyphs() const { | 443 bool TextRunHarfBuzz::HasMissingGlyphs() const { |
425 static const int kMissingGlyphId = 0; | 444 static const int kMissingGlyphId = 0; |
426 for (size_t i = 0; i < glyph_count; ++i) { | 445 for (size_t i = 0; i < glyph_count; ++i) { |
427 if (glyphs[i] == kMissingGlyphId) | 446 if (glyphs[i] == kMissingGlyphId) |
428 return true; | 447 return true; |
429 } | 448 } |
430 return false; | 449 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); | 991 run->positions[i].set(run->width + x_offset, y_offset); |
973 run->width += | 992 run->width += |
974 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].x_advance)); | 993 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].x_advance)); |
975 } | 994 } |
976 | 995 |
977 hb_buffer_destroy(buffer); | 996 hb_buffer_destroy(buffer); |
978 hb_font_destroy(harfbuzz_font); | 997 hb_font_destroy(harfbuzz_font); |
979 } | 998 } |
980 | 999 |
981 } // namespace gfx | 1000 } // namespace gfx |
OLD | NEW |