Index: third_party/WebKit/Source/platform/fonts/shaping/CaseMappingHarfBuzzBufferFiller.cpp |
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/CaseMappingHarfBuzzBufferFiller.cpp b/third_party/WebKit/Source/platform/fonts/shaping/CaseMappingHarfBuzzBufferFiller.cpp |
index e74e8209b17c5a4cd293e015d81a32df51000a60..a33caf38e0748e8287e26a18a3bc5a689f9a1126 100644 |
--- a/third_party/WebKit/Source/platform/fonts/shaping/CaseMappingHarfBuzzBufferFiller.cpp |
+++ b/third_party/WebKit/Source/platform/fonts/shaping/CaseMappingHarfBuzzBufferFiller.cpp |
@@ -20,6 +20,7 @@ static const uint16_t* toUint16(const UChar* src) |
CaseMappingHarfBuzzBufferFiller::CaseMappingHarfBuzzBufferFiller( |
CaseMapIntend caseMapIntend, |
+ AtomicString locale, |
hb_buffer_t* harfBuzzBuffer, |
const UChar* buffer, |
unsigned bufferLength, |
@@ -37,13 +38,15 @@ CaseMappingHarfBuzzBufferFiller::CaseMappingHarfBuzzBufferFiller( |
} else { |
String caseMappedText; |
if (caseMapIntend == CaseMapIntend::UpperCase) { |
- caseMappedText = String(buffer, bufferLength).upper(); |
+ caseMappedText = String(buffer, bufferLength).upper(locale); |
} else { |
- caseMappedText = String(buffer, bufferLength).lower(); |
+ caseMappedText = String(buffer, bufferLength).lower(locale); |
+ } |
+ |
+ if (caseMappedText.length() != bufferLength) { |
+ fillSlowCase(caseMapIntend, locale, buffer, bufferLength, startIndex, numCharacters); |
+ return; |
} |
- // TODO(drott): crbug.com/589335 Implement those for the case where the |
- // case-mapped string differs in length through one of the rule |
- // references in Unicode's SpecialCasing.txt |
ASSERT(caseMappedText.length() == bufferLength); |
ASSERT(!caseMappedText.is8Bit()); |
@@ -52,4 +55,39 @@ CaseMappingHarfBuzzBufferFiller::CaseMappingHarfBuzzBufferFiller( |
} |
} |
+// TODO(drott): crbug.com/623940 Fix lack of context sensitive case mapping here. |
+void CaseMappingHarfBuzzBufferFiller::fillSlowCase( |
+ CaseMapIntend caseMapIntend, |
+ AtomicString locale, |
+ const UChar* buffer, |
+ unsigned bufferLength, |
+ unsigned startIndex, |
+ unsigned numCharacters) |
+{ |
+ // Record pre-context. |
+ hb_buffer_add_utf16(m_harfBuzzBuffer, toUint16(buffer), bufferLength, startIndex, 0); |
+ |
+ for (unsigned charIndex = startIndex; charIndex < startIndex + numCharacters;) { |
+ unsigned newCharIndex = charIndex; |
+ U16_FWD_1(buffer, newCharIndex, numCharacters); |
+ String charByChar(&buffer[charIndex], newCharIndex - charIndex); |
+ String caseMappedChar; |
+ if (caseMapIntend == CaseMapIntend::UpperCase) |
+ caseMappedChar = charByChar.upper(locale); |
+ else |
+ caseMappedChar = charByChar.lower(locale); |
+ |
+ for (unsigned j = 0; j < caseMappedChar.length();) { |
+ UChar32 codepoint = 0; |
+ U16_NEXT(caseMappedChar.characters16(), j, caseMappedChar.length(), codepoint); |
+ // Add all characters of the case mapping result at the same cluster position. |
+ hb_buffer_add(m_harfBuzzBuffer, codepoint, charIndex); |
+ } |
+ charIndex = newCharIndex; |
+ } |
+ |
+ // Record post-context |
+ hb_buffer_add_utf16(m_harfBuzzBuffer, toUint16(buffer), bufferLength, startIndex + numCharacters, 0); |
+} |
+ |
} // namespace blink |