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

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

Issue 300623003: Fix the Char to Glyph mapping logic in RenderTextHarfBuzz (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add tests, fix implementation Created 6 years, 6 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 | Annotate | Revision Log
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 <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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698