Modified: trunk/Source/WebCore/ChangeLog (129049 => 129050)
--- trunk/Source/WebCore/ChangeLog 2012-09-19 22:23:25 UTC (rev 129049)
+++ trunk/Source/WebCore/ChangeLog 2012-09-19 22:29:05 UTC (rev 129050)
@@ -1,3 +1,24 @@
+2012-09-19 Kenichi Ishibashi <[email protected]>
+
+ [Chromium] HarfBuzzShaper should take into account combining characters
+ https://bugs.webkit.org/show_bug.cgi?id=97069
+
+ Reviewed by Tony Chang.
+
+ When dividing a text run into HarfBuzzRuns, try to find suitable SimpleFontData for
+ combining character sequence if there are one or more mark characters are followed.
+ If there is no combined glyphs in the font, use fallback font for mark characters.
+
+ No new tests.
+ In platform/chromium-linux/fast/text/international/complex-joining-using-gpos.html,
+ U+0947 (devanagari vowel sign e) should be displayed.
+ In fast/text/wide-zero-width-space.html, é and eĭ should look identical.
+
+ * platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp:
+ (WebCore):
+ (WebCore::fontDataForCombiningCharacterSequence): Added.
+ (WebCore::HarfBuzzShaper::collectHarfBuzzRuns): See above description.
+
2012-09-19 Tony Chang <[email protected]>
Remove RenderIFrame::updateLogicalHeight and RenderIFrame::updateLogicalWidth
Modified: trunk/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp (129049 => 129050)
--- trunk/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp 2012-09-19 22:23:25 UTC (rev 129049)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp 2012-09-19 22:29:05 UTC (rev 129050)
@@ -229,8 +229,23 @@
return point + m_startOffset;
}
+static const SimpleFontData* fontDataForCombiningCharacterSequence(const Font* font, const UChar* characters, size_t length)
+{
+ UErrorCode error = U_ZERO_ERROR;
+ Vector<UChar, 4> normalizedCharacters(length);
+ int32_t normalizedLength = unorm_normalize(characters, length, UNORM_NFC, UNORM_UNICODE_3_2, &normalizedCharacters[0], length, &error);
+ // Should fallback if we have an error or no composition occurred.
+ if (U_FAILURE(error) || (static_cast<size_t>(normalizedLength) == length))
+ return 0;
+ UChar32 normalizedCharacter;
+ size_t index = 0;
+ U16_NEXT(&normalizedCharacters[0], index, static_cast<size_t>(normalizedLength), normalizedCharacter);
+ return font->glyphDataForCharacter(normalizedCharacter, false).fontData;
+}
+
bool HarfBuzzShaper::collectHarfBuzzRuns()
{
+ const UChar* normalizedBufferEnd = m_normalizedBuffer.get() + m_normalizedBufferLength;
SurrogatePairAwareTextIterator iterator(m_normalizedBuffer.get(), 0, m_normalizedBufferLength, m_normalizedBufferLength);
UChar32 character;
unsigned clusterLength = 0;
@@ -245,18 +260,40 @@
return false;
do {
+ const UChar* currentCharacterPosition = iterator.characters();
const SimpleFontData* currentFontData = nextFontData;
UScriptCode currentScript = nextScript;
for (iterator.advance(clusterLength); iterator.consume(character, clusterLength); iterator.advance(clusterLength)) {
- nextFontData = m_font->glyphDataForCharacter(character, false).fontData;
- if (nextFontData != currentFontData)
- break;
+ if (Font::treatAsZeroWidthSpace(character))
+ continue;
+ if (U_GET_GC_MASK(character) & U_GC_M_MASK) {
+ int markLength = clusterLength;
+ const UChar* markCharactersEnd = iterator.characters() + clusterLength;
+ while (markCharactersEnd < normalizedBufferEnd) {
+ UChar32 nextCharacter;
+ int nextCharacterLength = 0;
+ U16_NEXT(markCharactersEnd, nextCharacterLength, normalizedBufferEnd - markCharactersEnd, nextCharacter);
+ if (!(U_GET_GC_MASK(nextCharacter) & U_GC_M_MASK))
+ break;
+ markLength += nextCharacterLength;
+ markCharactersEnd += nextCharacterLength;
+ }
+ nextFontData = fontDataForCombiningCharacterSequence(m_font, currentCharacterPosition, markCharactersEnd - currentCharacterPosition);
+ if (nextFontData)
+ clusterLength = markLength;
+ else
+ nextFontData = m_font->glyphDataForCharacter(character, false).fontData;
+ } else
+ nextFontData = m_font->glyphDataForCharacter(character, false).fontData;
+
nextScript = uscript_getScript(character, &errorCode);
if (U_FAILURE(errorCode))
return false;
- if ((currentScript != nextScript) && (currentScript != USCRIPT_INHERITED))
+ if ((nextFontData != currentFontData) || ((currentScript != nextScript) && (nextScript != USCRIPT_INHERITED)))
break;
+ if (nextScript == USCRIPT_INHERITED)
+ nextScript = currentScript;
}
unsigned numCharactersOfCurrentRun = iterator.currentCharacter() - startIndexOfCurrentRun;
m_harfbuzzRuns.append(HarfBuzzRun::create(currentFontData, startIndexOfCurrentRun, numCharactersOfCurrentRun, m_run.direction()));