summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclaireho <chinglanho@gmail.com>2010-11-03 12:52:05 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-11-03 12:52:05 -0700
commitd5a8aa497723e8ab3b77f0ecb8c9c6cc7ab5d7b0 (patch)
tree6466cbdd6b33c539c6ee42cf4e2f784adfaf0d14
parent43fe0893edfe68457bfdeb4533d02f55210ad6eb (diff)
parent5e45e11e0649161823ace17ca9e020111624a486 (diff)
downloadexternal_webkit-d5a8aa497723e8ab3b77f0ecb8c9c6cc7ab5d7b0.zip
external_webkit-d5a8aa497723e8ab3b77f0ecb8c9c6cc7ab5d7b0.tar.gz
external_webkit-d5a8aa497723e8ab3b77f0ecb8c9c6cc7ab5d7b0.tar.bz2
Merge "Bug 3158404 : Performance improvement for browser complex script handle."
-rw-r--r--WebCore/platform/graphics/android/FontAndroid.cpp89
1 files changed, 42 insertions, 47 deletions
diff --git a/WebCore/platform/graphics/android/FontAndroid.cpp b/WebCore/platform/graphics/android/FontAndroid.cpp
index 006bf7b..ec98af9 100644
--- a/WebCore/platform/graphics/android/FontAndroid.cpp
+++ b/WebCore/platform/graphics/android/FontAndroid.cpp
@@ -307,7 +307,7 @@ public:
TextRunWalker(const TextRun& run, unsigned startingX, const Font* font)
: m_font(font)
, m_startingX(startingX)
- , m_run(getTextRun(run))
+ , m_run(getNormalizedTextRun(run, m_normalizedRun, m_normalizedBuffer))
, m_iterateBackwards(m_run.rtl())
, m_wordSpacingAdjustment(0)
, m_padding(0)
@@ -331,18 +331,8 @@ public:
m_item.item.bidiLevel = m_run.rtl();
- int length = m_run.length();
- m_item.stringLength = length;
-
- if (!m_item.item.bidiLevel)
- m_item.string = m_run.characters();
- else {
- // Assume mirrored character is in the same Unicode multilingual plane as the original one.
- UChar* string = new UChar[length];
- mirrorCharacters(string, m_run.characters(), length);
- m_item.string = string;
- }
-
+ m_item.string = m_run.characters();
+ m_item.stringLength = m_run.length();
reset();
}
@@ -351,8 +341,6 @@ public:
fastFree(m_item.font);
deleteGlyphArrays();
delete[] m_item.log_clusters;
- if (m_item.item.bidiLevel)
- delete[] m_item.string;
}
// setWordSpacingAdjustment sets a delta (in pixels) which is applied at
@@ -552,9 +540,10 @@ public:
}
private:
- const TextRun& getTextRun(const TextRun& originalRun)
+ const TextRun& getNormalizedTextRun(const TextRun& originalRun,
+ OwnPtr<TextRun>& normalizedRun, OwnArrayPtr<UChar>& normalizedBuffer)
{
- // Normalize the text run in two ways:
+ // Normalize the text run in three ways:
// 1) Convert the |originalRun| to NFC normalized form if combining diacritical marks
// (U+0300..) are used in the run. This conversion is necessary since most OpenType
// fonts (e.g., Arial) don't have substitution rules for the diacritical marks in
@@ -566,41 +555,43 @@ private:
// Harfbuzz will do the same thing for us using the GSUB table.
// 2) Convert spacing characters into plain spaces, as some fonts will provide glyphs
// for characters like '\n' otherwise.
+ // 3) Convert mirrored characters such as parenthesis for rtl text.
+
+ // Convert to NFC form if the text has diacritical marks.
+ icu::UnicodeString normalizedString;
+ UErrorCode error = U_ZERO_ERROR;
+
for (int16_t i = 0; i < originalRun.length(); ++i) {
UChar ch = originalRun[i];
- UBlockCode block = ::ublock_getCode(ch);
- if (block == UBLOCK_COMBINING_DIACRITICAL_MARKS ||
- (Font::treatAsSpace(ch) && ch != ' ')) {
- return getNormalizedTextRun(originalRun);
+ if (::ublock_getCode(ch) == UBLOCK_COMBINING_DIACRITICAL_MARKS) {
+ icu::Normalizer::normalize(icu::UnicodeString(originalRun.characters(),
+ originalRun.length()), UNORM_NFC, 0 /* no options */,
+ normalizedString, error);
+ if (U_FAILURE(error))
+ return originalRun;
+ break;
}
}
- return originalRun;
- }
- const TextRun& getNormalizedTextRun(const TextRun& originalRun)
- {
- icu::UnicodeString normalizedString;
- UErrorCode error = U_ZERO_ERROR;
- icu::Normalizer::normalize(icu::UnicodeString(originalRun.characters(),
- originalRun.length()), UNORM_NFC, 0 /* no options */,
- normalizedString, error);
- if (U_FAILURE(error))
- return originalRun;
-
- m_normalizedBuffer.set(new UChar[normalizedString.length() + 1]);
- normalizedString.extract(m_normalizedBuffer.get(),
- normalizedString.length() + 1, error);
- ASSERT(U_SUCCESS(error));
-
- for (int32_t i = 0; i < normalizedString.length(); ++i) {
- if (Font::treatAsSpace(m_normalizedBuffer[i]))
- m_normalizedBuffer[i] = ' ';
+ // Normalize space and mirror parenthesis for rtl text.
+ int normalizedBufferLength;
+ const UChar* sourceText;
+ if (normalizedString.isEmpty()) {
+ normalizedBufferLength = originalRun.length();
+ sourceText = originalRun.characters();
+ } else {
+ normalizedBufferLength = normalizedString.length();
+ sourceText = normalizedString.getBuffer();
}
- m_normalizedRun.set(new TextRun(originalRun));
- m_normalizedRun->setText(m_normalizedBuffer.get(),
- normalizedString.length());
- return *m_normalizedRun;
+ normalizedBuffer.set(new UChar[normalizedBufferLength + 1]);
+
+ normalizeSpacesAndMirrorChars(sourceText, originalRun.rtl(), normalizedBuffer.get(),
+ normalizedBufferLength);
+
+ normalizedRun.set(new TextRun(originalRun));
+ normalizedRun->setText(normalizedBuffer.get(), normalizedBufferLength);
+ return *normalizedRun;
}
void setupFontForScriptRun()
@@ -743,7 +734,8 @@ private:
m_offsetX += m_pixelWidth;
}
- void mirrorCharacters(UChar* destination, const UChar* source, int length) const
+ static void normalizeSpacesAndMirrorChars(const UChar* source, bool rtl,
+ UChar* destination, int length)
{
int position = 0;
bool error = false;
@@ -752,7 +744,10 @@ private:
UChar32 character;
int nextPosition = position;
U16_NEXT(source, nextPosition, length, character);
- character = u_charMirror(character);
+ if (Font::treatAsSpace(character))
+ character = ' ';
+ else if (rtl)
+ character = u_charMirror(character);
U16_APPEND(destination, position, length, character, error);
ASSERT(!error);
position = nextPosition;