| 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
|
|
|