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

Unified Diff: ui/gfx/render_text_harfbuzz.cc

Issue 299313005: Replace bare ICU run iterator with base::i18n::BiDiLineIterator (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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/gfx/render_text_harfbuzz.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/render_text_harfbuzz.cc
diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc
index 10e7a1a5276931a44ad6e8ff6643d5a03bba9ed9..7fc5ef65abf31e6d71e693acb8910b24d663fa2e 100644
--- a/ui/gfx/render_text_harfbuzz.cc
+++ b/ui/gfx/render_text_harfbuzz.cc
@@ -6,6 +6,7 @@
#include <map>
+#include "base/i18n/bidi_line_iterator.h"
#include "base/i18n/break_iterator.h"
#include "base/i18n/char_iterator.h"
#include "third_party/harfbuzz-ng/src/hb.h"
@@ -328,7 +329,7 @@ namespace internal {
TextRunHarfBuzz::TextRunHarfBuzz()
: width(0),
preceding_run_widths(0),
- direction(UBIDI_LTR),
+ is_rtl(false),
level(0),
script(USCRIPT_INVALID_CODE),
glyph_count(-1),
@@ -343,7 +344,7 @@ TextRunHarfBuzz::~TextRunHarfBuzz() {}
size_t TextRunHarfBuzz::CharToGlyph(size_t pos) const {
DCHECK(range.start() <= pos && pos < range.end());
- if (direction == UBIDI_LTR) {
+ if (!is_rtl) {
for (size_t i = 0; i < glyph_count - 1; ++i) {
if (pos < glyph_to_char[i + 1])
return i;
@@ -386,14 +387,13 @@ int TextRunHarfBuzz::GetGlyphXBoundary(size_t text_index, bool trailing) const {
Range glyph_range;
if (text_index == range.end()) {
trailing = true;
- glyph_range = direction == UBIDI_LTR ?
- Range(glyph_count - 1, glyph_count) : Range(0, 1);
+ glyph_range = is_rtl ? Range(0, 1) : Range(glyph_count - 1, glyph_count);
} else {
glyph_range = CharRangeToGlyphRange(Range(text_index, text_index + 1));
}
const int trailing_step = trailing ? 1 : 0;
- const size_t glyph_pos = glyph_range.start() +
- (direction == UBIDI_LTR ? trailing_step : (1 - trailing_step));
+ const size_t glyph_pos =
+ glyph_range.start() + (is_rtl ? (1 - trailing_step) : trailing_step);
x += glyph_pos < glyph_count ?
SkScalarRoundToInt(positions[glyph_pos].x()) : width;
return x;
@@ -426,16 +426,16 @@ SelectionModel RenderTextHarfBuzz::FindCursorPosition(const Point& point) {
const SkScalar end =
i + 1 == run.glyph_count ? run.width : run.positions[i + 1].x();
const SkScalar middle = (end + run.positions[i].x()) / 2;
- const bool is_rtl = run.direction == UBIDI_RTL;
+
if (offset < middle) {
return SelectionModel(LayoutIndexToTextIndex(
- run.glyph_to_char[i] + (is_rtl ? 1 : 0)),
- (is_rtl ? CURSOR_BACKWARD : CURSOR_FORWARD));
+ run.glyph_to_char[i] + (run.is_rtl ? 1 : 0)),
+ (run.is_rtl ? CURSOR_BACKWARD : CURSOR_FORWARD));
}
if (offset < end) {
return SelectionModel(LayoutIndexToTextIndex(
- run.glyph_to_char[i] + (is_rtl ? 0 : 1)),
- (is_rtl ? CURSOR_FORWARD : CURSOR_BACKWARD));
+ run.glyph_to_char[i] + (run.is_rtl ? 0 : 1)),
+ (run.is_rtl ? CURSOR_FORWARD : CURSOR_BACKWARD));
}
}
return EdgeSelectionModel(CURSOR_RIGHT);
@@ -469,8 +469,7 @@ SelectionModel RenderTextHarfBuzz::AdjacentCharSelectionModel(
// grapheme in the appropriate direction.
run = runs_[run_index];
size_t caret = selection.caret_pos();
- bool forward_motion =
- (run->direction == UBIDI_RTL) == (direction == CURSOR_LEFT);
+ bool forward_motion = run->is_rtl == (direction == CURSOR_LEFT);
if (forward_motion) {
if (caret < LayoutIndexToTextIndex(run->range.end())) {
caret = IndexOfAdjacentGrapheme(caret, CURSOR_FORWARD);
@@ -489,8 +488,7 @@ SelectionModel RenderTextHarfBuzz::AdjacentCharSelectionModel(
return EdgeSelectionModel(direction);
run = runs_[visual_to_logical_[visual_index]];
}
- bool forward_motion =
- (run->direction == UBIDI_RTL) == (direction == CURSOR_LEFT);
+ bool forward_motion = run->is_rtl == (direction == CURSOR_LEFT);
return forward_motion ? FirstSelectionModelInsideRun(run) :
LastSelectionModelInsideRun(run);
}
@@ -794,29 +792,15 @@ SelectionModel RenderTextHarfBuzz::LastSelectionModelInsideRun(
void RenderTextHarfBuzz::ItemizeText() {
const base::string16& text = GetLayoutText();
- const bool is_rtl = GetTextDirection() == base::i18n::RIGHT_TO_LEFT;
+ const bool is_text_rtl = GetTextDirection() == base::i18n::RIGHT_TO_LEFT;
DCHECK_NE(0U, text.length());
// If ICU fails to itemize the text, we set |fake_runs| and create a run that
// spans the entire text. This is needed because early returning and leaving
// the runs set empty causes some clients to crash/misbehave since they expect
// non-zero text metrics from a non-empty text.
- bool fake_runs = false;
- UErrorCode result = U_ZERO_ERROR;
-
- UBiDi* line = ubidi_openSized(text.length(), 0, &result);
- if (U_FAILURE(result)) {
- NOTREACHED();
- fake_runs = true;
- } else {
- ubidi_setPara(line, text.c_str(), text.length(),
- is_rtl ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR, NULL,
- &result);
- if (U_FAILURE(result)) {
- NOTREACHED();
- fake_runs = true;
- }
- }
+ base::i18n::BiDiLineIterator bidi_iterator;
+ bool fake_runs = !bidi_iterator.Open(text, is_text_rtl, false);
// Temporarily apply composition underlines and selection colors.
ApplyCompositionAndSelectionStyles();
@@ -840,7 +824,7 @@ void RenderTextHarfBuzz::ItemizeText() {
run_break = text.length();
} else {
int32 script_item_break = 0;
- ubidi_getLogicalRun(line, run_break, &script_item_break, &run->level);
+ bidi_iterator.GetLogicalRun(run_break, &script_item_break, &run->level);
// Find the length and script of this script run.
script_item_break = ScriptInterval(text, run_break,
script_item_break - run_break, &run->script) + run_break;
@@ -873,18 +857,15 @@ void RenderTextHarfBuzz::ItemizeText() {
DCHECK(IsValidCodePointIndex(text, run_break));
style.UpdatePosition(LayoutIndexToTextIndex(run_break));
run->range.set_end(run_break);
- const UChar* uchar_start = ubidi_getText(line);
- // TODO(ckocagil): Add |ubidi_getBaseDirection| to i18n::BiDiLineIterator
- // and remove the bare ICU use here.
- run->direction = ubidi_getBaseDirection(uchar_start + run->range.start(),
- run->range.length());
- if (run->direction == UBIDI_NEUTRAL)
- run->direction = is_rtl ? UBIDI_RTL : UBIDI_LTR;
+ UBiDiDirection direction = ubidi_getBaseDirection(
+ text.c_str() + run->range.start(), run->range.length());
+ if (direction == UBIDI_NEUTRAL)
+ run->is_rtl = is_text_rtl;
+ else
+ run->is_rtl = direction == UBIDI_RTL;
runs_.push_back(run);
}
- ubidi_close(line);
-
// Undo the temporarily applied composition underlines and selection colors.
UndoCompositionAndSelectionStyles();
@@ -917,7 +898,7 @@ void RenderTextHarfBuzz::ShapeRun(internal::TextRunHarfBuzz* run) {
text.length(), run->range.start(), run->range.length());
hb_buffer_set_script(buffer, ICUScriptToHBScript(run->script));
hb_buffer_set_direction(buffer,
- run->direction == UBIDI_LTR ? HB_DIRECTION_LTR : HB_DIRECTION_RTL);
+ run->is_rtl ? HB_DIRECTION_RTL : HB_DIRECTION_LTR);
// TODO(ckocagil): Should we determine the actual language?
hb_buffer_set_language(buffer, hb_language_get_default());
« no previous file with comments | « ui/gfx/render_text_harfbuzz.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698