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

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: Created 6 years, 7 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 | « no previous file | no next file » | 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/break_iterator.h" 9 #include "base/i18n/break_iterator.h"
10 #include "base/i18n/char_iterator.h" 10 #include "base/i18n/char_iterator.h"
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 diagonal_strike(false), 338 diagonal_strike(false),
339 underline(false) {} 339 underline(false) {}
340 340
341 TextRunHarfBuzz::~TextRunHarfBuzz() {} 341 TextRunHarfBuzz::~TextRunHarfBuzz() {}
342 342
343 size_t TextRunHarfBuzz::CharToGlyph(size_t pos) const { 343 size_t TextRunHarfBuzz::CharToGlyph(size_t pos) const {
344 DCHECK(range.start() <= pos && pos < range.end()); 344 DCHECK(range.start() <= pos && pos < range.end());
345 345
346 if (direction == UBIDI_LTR) { 346 if (direction == UBIDI_LTR) {
347 for (size_t i = 0; i < glyph_count - 1; ++i) { 347 for (size_t i = 0; i < glyph_count - 1; ++i) {
348 if (pos < glyph_to_char[i + 1]) 348 if (pos < glyph_to_char[i + 1])
msw 2014/06/02 19:37:58 For logical LTR string "a" that yields two glyphs
msw 2014/06/03 22:32:09 What about this? LMK if I'm wrong or how we should
ckocagil 2014/06/05 06:51:59 This should be fixed now.
349 return i; 349 return i;
350 } 350 }
351 return glyph_count - 1; 351 return glyph_count - 1;
352 } 352 }
353 353
354 for (size_t i = 0; i < glyph_count; ++i) { 354 for (size_t i = 0; i < glyph_count; ++i) {
355 if (pos >= glyph_to_char[i]) 355 if (pos >= glyph_to_char[i])
356 return i; 356 return i;
357 } 357 }
358 NOTREACHED(); 358 NOTREACHED();
359 return 0; 359 return 0;
360 } 360 }
361 361
362 Range TextRunHarfBuzz::CharRangeToGlyphRange(const Range& range) const { 362 Range TextRunHarfBuzz::CharRangeToGlyphRange(const Range& char_range) const {
363 DCHECK(range.Contains(range)); 363 DCHECK(range.Contains(char_range));
364 DCHECK(!range.is_reversed()); 364 DCHECK(!char_range.is_reversed());
365 DCHECK(!range.is_empty()); 365 DCHECK(!char_range.is_empty());
366 366
367 const size_t first = CharToGlyph(range.start()); 367 size_t first = 0;
368 const size_t last = CharToGlyph(range.end() - 1); 368 size_t last = 0;
369 // TODO(ckocagil): What happens when the character has zero or multiple 369
370 // glyphs? Is the "+ 1" below correct then? 370 if (direction == UBIDI_RTL) {
371 return Range(std::min(first, last), std::max(first, last) + 1); 371 // For RTL runs, we subtract 1 from |char_range| to get the trailing edges.
msw 2014/05/28 01:18:30 nit: the meaning of "to get the trailing edges" is
ckocagil 2014/06/02 02:57:42 I tried to find a better way to explain this, but
msw 2014/06/02 19:37:58 So a char range of [1,2) would yield "[c)ba" witho
ckocagil 2014/06/03 22:25:17 What I mean by trailing is: imagine if CharToGlyph
372 first = char_range.start() == range.start() ?
373 glyph_count : CharToGlyph(char_range.start() - 1);
374 last = CharToGlyph(char_range.end() - 1);
375 } else {
376 first = CharToGlyph(char_range.start());
377 last = char_range.end() == range.end() ?
378 glyph_count : CharToGlyph(char_range.end());
msw 2014/05/28 00:52:33 This doesn't seem right. It seems like if the end
ckocagil 2014/05/28 01:02:02 |char_range.end() == range.end()| doesn't mean "la
msw 2014/05/28 01:18:30 Ah, that makes more way more sense.
379 }
380 return Range(std::min(first, last), std::max(first, last));
372 } 381 }
373 382
374 // Returns whether the given shaped run contains any missing glyphs. 383 // Returns whether the given shaped run contains any missing glyphs.
375 bool TextRunHarfBuzz::HasMissingGlyphs() const { 384 bool TextRunHarfBuzz::HasMissingGlyphs() const {
376 static const int kMissingGlyphId = 0; 385 static const int kMissingGlyphId = 0;
377 for (size_t i = 0; i < glyph_count; ++i) { 386 for (size_t i = 0; i < glyph_count; ++i) {
378 if (glyphs[i] == kMissingGlyphId) 387 if (glyphs[i] == kMissingGlyphId)
379 return true; 388 return true;
380 } 389 }
381 return false; 390 return false;
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 // Shape the text. 933 // Shape the text.
925 hb_shape(harfbuzz_font, buffer, NULL, 0); 934 hb_shape(harfbuzz_font, buffer, NULL, 0);
926 935
927 // Populate the run fields with the resulting glyph data in the buffer. 936 // Populate the run fields with the resulting glyph data in the buffer.
928 unsigned int glyph_count = 0; 937 unsigned int glyph_count = 0;
929 hb_glyph_info_t* infos = hb_buffer_get_glyph_infos(buffer, &glyph_count); 938 hb_glyph_info_t* infos = hb_buffer_get_glyph_infos(buffer, &glyph_count);
930 hb_glyph_position_t* hb_positions = hb_buffer_get_glyph_positions(buffer, 939 hb_glyph_position_t* hb_positions = hb_buffer_get_glyph_positions(buffer,
931 NULL); 940 NULL);
932 run->glyph_count = glyph_count; 941 run->glyph_count = glyph_count;
933 run->glyphs.reset(new uint16[run->glyph_count]); 942 run->glyphs.reset(new uint16[run->glyph_count]);
934 run->glyph_to_char.reset(new uint32[run->glyph_count]); 943 run->glyph_to_char.reset(new uint32[run->glyph_count]);
msw 2014/06/06 02:00:42 Would it be helpful and prudent to make a similar
ckocagil 2014/06/07 05:40:33 It would be helpful, but this is a trade off betwe
935 run->positions.reset(new SkPoint[run->glyph_count]); 944 run->positions.reset(new SkPoint[run->glyph_count]);
936 for (size_t i = 0; i < run->glyph_count; ++i) { 945 for (size_t i = 0; i < run->glyph_count; ++i) {
937 run->glyphs[i] = infos[i].codepoint; 946 run->glyphs[i] = infos[i].codepoint;
938 run->glyph_to_char[i] = infos[i].cluster; 947 run->glyph_to_char[i] = infos[i].cluster;
939 const int x_offset = 948 const int x_offset =
940 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].x_offset)); 949 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].x_offset));
941 const int y_offset = 950 const int y_offset =
942 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].y_offset)); 951 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].y_offset));
943 run->positions[i].set(run->width + x_offset, y_offset); 952 run->positions[i].set(run->width + x_offset, y_offset);
944 run->width += 953 run->width +=
945 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].x_advance)); 954 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].x_advance));
946 } 955 }
947 956
948 hb_buffer_destroy(buffer); 957 hb_buffer_destroy(buffer);
949 hb_font_destroy(harfbuzz_font); 958 hb_font_destroy(harfbuzz_font);
950 } 959 }
951 960
952 } // namespace gfx 961 } // namespace gfx
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698