Commit a60d02d9 authored by ckocagil@chromium.org's avatar ckocagil@chromium.org

Move unusual character block logic to a helper function

BUG=
NOTRY=true
R=msw

Review URL: https://codereview.chromium.org/324983002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276776 0039d316-1c4b-4281-b951-d872f2087c98
parent 0e648562
...@@ -281,6 +281,26 @@ bool IsUnusualBlockCode(UBlockCode block_code) { ...@@ -281,6 +281,26 @@ bool IsUnusualBlockCode(UBlockCode block_code) {
block_code == UBLOCK_MISCELLANEOUS_SYMBOLS; block_code == UBLOCK_MISCELLANEOUS_SYMBOLS;
} }
// Returns the index of the first unusual character after a usual character or
// vice versa. Unusual characters are defined by |IsUnusualBlockCode|.
size_t FindUnusualCharacter(const base::string16& text,
size_t run_start,
size_t run_break) {
const int32 run_length = static_cast<int32>(run_break - run_start);
base::i18n::UTF16CharIterator iter(text.c_str() + run_start,
run_length);
const UBlockCode first_block_code = ublock_getCode(iter.get());
const bool first_block_unusual = IsUnusualBlockCode(first_block_code);
while (iter.Advance() && iter.array_pos() < run_length) {
const UBlockCode current_block_code = ublock_getCode(iter.get());
if (current_block_code != first_block_code &&
(first_block_unusual || IsUnusualBlockCode(current_block_code))) {
return run_start + iter.array_pos();
}
}
return run_break;
}
// If the given scripts match, returns the one that isn't USCRIPT_COMMON or // If the given scripts match, returns the one that isn't USCRIPT_COMMON or
// USCRIPT_INHERITED, i.e. the more specific one. Otherwise returns // USCRIPT_INHERITED, i.e. the more specific one. Otherwise returns
// USCRIPT_INVALID_CODE. // USCRIPT_INVALID_CODE.
...@@ -912,22 +932,8 @@ void RenderTextHarfBuzz::ItemizeText() { ...@@ -912,22 +932,8 @@ void RenderTextHarfBuzz::ItemizeText() {
// Break runs adjacent to character substrings in certain code blocks. // Break runs adjacent to character substrings in certain code blocks.
// This avoids using their fallback fonts for more characters than needed, // This avoids using their fallback fonts for more characters than needed,
// in cases like "\x25B6 Media Title", etc. http://crbug.com/278913 // in cases like "\x25B6 Media Title", etc. http://crbug.com/278913
if (run_break > run->range.start()) { if (run_break > run->range.start())
const size_t run_start = run->range.start(); run_break = FindUnusualCharacter(text, run->range.start(), run_break);
const int32 run_length = static_cast<int32>(run_break - run_start);
base::i18n::UTF16CharIterator iter(text.c_str() + run_start,
run_length);
const UBlockCode first_block_code = ublock_getCode(iter.get());
const bool first_block_unusual = IsUnusualBlockCode(first_block_code);
while (iter.Advance() && iter.array_pos() < run_length) {
const UBlockCode current_block_code = ublock_getCode(iter.get());
if (current_block_code != first_block_code &&
(first_block_unusual || IsUnusualBlockCode(current_block_code))) {
run_break = run_start + iter.array_pos();
break;
}
}
}
DCHECK(IsValidCodePointIndex(text, run_break)); DCHECK(IsValidCodePointIndex(text, run_break));
style.UpdatePosition(LayoutIndexToTextIndex(run_break)); style.UpdatePosition(LayoutIndexToTextIndex(run_break));
......
...@@ -92,6 +92,7 @@ class GFX_EXPORT RenderTextHarfBuzz : public RenderText { ...@@ -92,6 +92,7 @@ class GFX_EXPORT RenderTextHarfBuzz : public RenderText {
private: private:
friend class RenderTextTest; friend class RenderTextTest;
FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_RunDirection); FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_RunDirection);
FRIEND_TEST_ALL_PREFIXES(RenderTextTest, HarfBuzz_BreakRunsByUnicodeBlocks);
// Return the run index that contains the argument; or the length of the // Return the run index that contains the argument; or the length of the
// |runs_| vector if argument exceeds the text length or width. // |runs_| vector if argument exceeds the text length or width.
......
...@@ -1903,7 +1903,6 @@ TEST_F(RenderTextTest, Multiline_Newline) { ...@@ -1903,7 +1903,6 @@ TEST_F(RenderTextTest, Multiline_Newline) {
} }
} }
TEST_F(RenderTextTest, Win_BreakRunsByUnicodeBlocks) { TEST_F(RenderTextTest, Win_BreakRunsByUnicodeBlocks) {
scoped_ptr<RenderTextWin> render_text( scoped_ptr<RenderTextWin> render_text(
static_cast<RenderTextWin*>(RenderText::CreateInstance())); static_cast<RenderTextWin*>(RenderText::CreateInstance()));
...@@ -1974,7 +1973,6 @@ TEST_F(RenderTextTest, HarfBuzz_CharToGlyph) { ...@@ -1974,7 +1973,6 @@ TEST_F(RenderTextTest, HarfBuzz_CharToGlyph) {
run.CharRangeToGlyphRange(Range(j, j + 1))); run.CharRangeToGlyphRange(Range(j, j + 1)));
} }
} }
} }
TEST_F(RenderTextTest, HarfBuzz_RunDirection) { TEST_F(RenderTextTest, HarfBuzz_RunDirection) {
...@@ -1989,4 +1987,23 @@ TEST_F(RenderTextTest, HarfBuzz_RunDirection) { ...@@ -1989,4 +1987,23 @@ TEST_F(RenderTextTest, HarfBuzz_RunDirection) {
EXPECT_TRUE(render_text.runs_[2]->is_rtl); EXPECT_TRUE(render_text.runs_[2]->is_rtl);
} }
TEST_F(RenderTextTest, HarfBuzz_BreakRunsByUnicodeBlocks) {
RenderTextHarfBuzz render_text;
// The '\x25B6' "play character" should break runs. http://crbug.com/278913
render_text.SetText(WideToUTF16(L"x\x25B6y"));
render_text.EnsureLayout();
ASSERT_EQ(3U, render_text.runs_.size());
EXPECT_EQ(Range(0, 1), render_text.runs_[0]->range);
EXPECT_EQ(Range(1, 2), render_text.runs_[1]->range);
EXPECT_EQ(Range(2, 3), render_text.runs_[2]->range);
render_text.SetText(WideToUTF16(L"x \x25B6 y"));
render_text.EnsureLayout();
ASSERT_EQ(3U, render_text.runs_.size());
EXPECT_EQ(Range(0, 2), render_text.runs_[0]->range);
EXPECT_EQ(Range(2, 3), render_text.runs_[1]->range);
EXPECT_EQ(Range(3, 5), render_text.runs_[2]->range);
}
} // namespace gfx } // namespace gfx
...@@ -264,6 +264,26 @@ bool IsUnusualBlockCode(const UBlockCode block_code) { ...@@ -264,6 +264,26 @@ bool IsUnusualBlockCode(const UBlockCode block_code) {
block_code == UBLOCK_MISCELLANEOUS_SYMBOLS; block_code == UBLOCK_MISCELLANEOUS_SYMBOLS;
} }
// Returns the index of the first unusual character after a usual character or
// vice versa. Unusual characters are defined by |IsUnusualBlockCode|.
size_t FindUnusualCharacter(const base::string16& text,
size_t run_start,
size_t run_break) {
const int32 run_length = static_cast<int32>(run_break - run_start);
base::i18n::UTF16CharIterator iter(text.c_str() + run_start,
run_length);
const UBlockCode first_block_code = ublock_getCode(iter.get());
const bool first_block_unusual = IsUnusualBlockCode(first_block_code);
while (iter.Advance() && iter.array_pos() < run_length) {
const UBlockCode current_block_code = ublock_getCode(iter.get());
if (current_block_code != first_block_code &&
(first_block_unusual || IsUnusualBlockCode(current_block_code))) {
return run_start + iter.array_pos();
}
}
return run_break;
}
} // namespace } // namespace
namespace internal { namespace internal {
...@@ -955,20 +975,8 @@ void RenderTextWin::ItemizeLogicalText() { ...@@ -955,20 +975,8 @@ void RenderTextWin::ItemizeLogicalText() {
// This avoids using their fallback fonts for more characters than needed, // This avoids using their fallback fonts for more characters than needed,
// in cases like "\x25B6 Media Title", etc. http://crbug.com/278913 // in cases like "\x25B6 Media Title", etc. http://crbug.com/278913
if (run_break > run->range.start()) { if (run_break > run->range.start()) {
const size_t run_start = run->range.start(); run_break =
const int32 run_length = static_cast<int32>(run_break - run_start); FindUnusualCharacter(layout_text, run->range.start(), run_break);
base::i18n::UTF16CharIterator iter(layout_text.c_str() + run_start,
run_length);
const UBlockCode first_block_code = ublock_getCode(iter.get());
const bool first_block_unusual = IsUnusualBlockCode(first_block_code);
while (iter.Advance() && iter.array_pos() < run_length) {
const UBlockCode current_block_code = ublock_getCode(iter.get());
if (current_block_code != first_block_code &&
(first_block_unusual || IsUnusualBlockCode(current_block_code))) {
run_break = run_start + iter.array_pos();
break;
}
}
} }
DCHECK(IsValidCodePointIndex(layout_text, run_break)); DCHECK(IsValidCodePointIndex(layout_text, run_break));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment