Index: Source/platform/fonts/shaping/HarfBuzzShaper.cpp |
diff --git a/Source/platform/fonts/shaping/HarfBuzzShaper.cpp b/Source/platform/fonts/shaping/HarfBuzzShaper.cpp |
index e44d55753560c693ca44de87c11439bebc244319..0f602c32b96b633015922f9a5669f16a0a4c4109 100644 |
--- a/Source/platform/fonts/shaping/HarfBuzzShaper.cpp |
+++ b/Source/platform/fonts/shaping/HarfBuzzShaper.cpp |
@@ -359,17 +359,37 @@ static void normalizeCharacters(const TextRun& run, unsigned length, UChar* dest |
source = run.characters16(); |
} |
+ // Convert to NFC form if the text has diacritical marks. In most of the font, OTF rules |
+ // for diacritical marks are missing. Using ICU calls to convert to final form and then pass |
+ // updated Unicode string to Harfbuzz. |
+ icu::UnicodeString normalizedString; |
+ UErrorCode errorICU = U_ZERO_ERROR; |
+ bool isDiacriticalMarkPresent = false; |
+ |
*destinationLength = 0; |
while (position < length) { |
UChar32 character; |
U16_NEXT(source, position, length, character); |
// Don't normalize tabs as they are not treated as spaces for word-end. |
- if (run.normalizeSpace() && Character::isNormalizedCanvasSpaceCharacter(character)) |
+ if (run.normalizeSpace() && Character::isNormalizedCanvasSpaceCharacter(character)) { |
character = spaceCharacter; |
- else if (Character::treatAsSpace(character) && character != tabulationCharacter) |
+ } else if (Character::treatAsSpace(character) && character != tabulationCharacter) { |
character = spaceCharacter; |
- else if (Character::treatAsZeroWidthSpaceInComplexScript(character)) |
+ } else if (Character::treatAsZeroWidthSpaceInComplexScript(character)) { |
character = zeroWidthSpaceCharacter; |
+ } else if (!isDiacriticalMarkPresent && ::ublock_getCode(character) == UBLOCK_COMBINING_DIACRITICAL_MARKS) { |
+ isDiacriticalMarkPresent = true; |
+ icu::Normalizer::normalize(icu::UnicodeString(source, length), UNORM_NFC, 0 , normalizedString, errorICU); |
+ if (U_FAILURE(errorICU)) { |
+ normalizedString.remove(); |
+ } else if (!normalizedString.isEmpty()) { |
+ *destinationLength = 0; |
+ position = 0; |
+ length = static_cast<int>(normalizedString.length()); |
+ source = normalizedString.getBuffer(); |
+ continue; |
+ } |
+ } |
U16_APPEND(destination, *destinationLength, length, character, error); |
ASSERT_UNUSED(error, !error); |