diff options
Diffstat (limited to 'chromium/ui/gfx/render_text_harfbuzz.cc')
-rw-r--r-- | chromium/ui/gfx/render_text_harfbuzz.cc | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/chromium/ui/gfx/render_text_harfbuzz.cc b/chromium/ui/gfx/render_text_harfbuzz.cc index 2f0286217a5..07a4bbd44b0 100644 --- a/chromium/ui/gfx/render_text_harfbuzz.cc +++ b/chromium/ui/gfx/render_text_harfbuzz.cc @@ -15,6 +15,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/profiler/scoped_tracker.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/trace_event/trace_event.h" @@ -207,8 +208,9 @@ bool IsNewlineSegment(const base::string16& text, // Helper template function for |TextRunHarfBuzz::GetClusterAt()|. |Iterator| // can be a forward or reverse iterator type depending on the text direction. +// Returns true on success, or false if an error is encountered. template <class Iterator> -void GetClusterAtImpl(size_t pos, +bool GetClusterAtImpl(size_t pos, Range range, Iterator elements_begin, Iterator elements_end, @@ -216,10 +218,14 @@ void GetClusterAtImpl(size_t pos, Range* chars, Range* glyphs) { Iterator element = std::upper_bound(elements_begin, elements_end, pos); + if (element == elements_begin) { + *chars = range; + *glyphs = Range(); + return false; + } + chars->set_end(element == elements_end ? range.end() : *element); glyphs->set_end(reversed ? elements_end - element : element - elements_begin); - - DCHECK(element != elements_begin); while (--element != elements_begin && *element == *(element - 1)); chars->set_start(*element); glyphs->set_start( @@ -231,6 +237,7 @@ void GetClusterAtImpl(size_t pos, DCHECK(!chars->is_empty()); DCHECK(!glyphs->is_reversed()); DCHECK(!glyphs->is_empty()); + return true; } // Returns the line segment index for the |line|, |text_x| pair. |text_x| is @@ -680,24 +687,37 @@ size_t TextRunHarfBuzz::CountMissingGlyphs() const { void TextRunHarfBuzz::GetClusterAt(size_t pos, Range* chars, Range* glyphs) const { - DCHECK(range.Contains(Range(pos, pos + 1))); DCHECK(chars); DCHECK(glyphs); - if (glyph_count == 0) { + bool success = true; + if (glyph_count == 0 || !range.Contains(Range(pos, pos + 1))) { *chars = range; *glyphs = Range(); - return; + success = false; } if (is_rtl) { - GetClusterAtImpl(pos, range, glyph_to_char.rbegin(), glyph_to_char.rend(), - true, chars, glyphs); - return; + success &= GetClusterAtImpl(pos, range, glyph_to_char.rbegin(), + glyph_to_char.rend(), true, chars, glyphs); + } else { + success &= GetClusterAtImpl(pos, range, glyph_to_char.begin(), + glyph_to_char.end(), false, chars, glyphs); } - GetClusterAtImpl(pos, range, glyph_to_char.begin(), glyph_to_char.end(), - false, chars, glyphs); + if (!success) { + std::string glyph_to_char_string; + for (size_t i = 0; i < glyph_count && i < glyph_to_char.size(); ++i) { + glyph_to_char_string += base::SizeTToString(i) + "->" + + base::UintToString(glyph_to_char[i]) + ", "; + } + LOG(ERROR) << " TextRunHarfBuzz error, please report at crbug.com/724880:" + << " range: " << range.ToString() << ", rtl: " << is_rtl << "," + << " level: '" << level << "', script: " << script << "," + << " font: '" << font.GetActualFontNameForTesting() << "'," + << " glyph_count: " << glyph_count << ", pos: " << pos << "," + << " glyph_to_char: " << glyph_to_char_string; + } } RangeF TextRunHarfBuzz::GetGraphemeBounds(RenderTextHarfBuzz* render_text, |