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

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: compile fix 2 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
« no previous file with comments | « ui/gfx/render_text_harfbuzz.h ('k') | ui/gfx/render_text_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
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
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
OLDNEW
« no previous file with comments | « ui/gfx/render_text_harfbuzz.h ('k') | ui/gfx/render_text_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698