Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Side by Side Diff: third_party/WebKit/Source/platform/fonts/shaping/CaseMappingHarfBuzzBufferFiller.cpp

Issue 2102113002: Fix case mapping buffer length divergence for synthetic caps (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Turkish test is a progression, rebaselining, Moving comment up in test case Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "CaseMappingHarfBuzzBufferFiller.h" 5 #include "CaseMappingHarfBuzzBufferFiller.h"
6 6
7 #include "wtf/text/WTFString.h" 7 #include "wtf/text/WTFString.h"
8 8
9 namespace blink { 9 namespace blink {
10 10
11 static const uint16_t* toUint16(const UChar* src) 11 static const uint16_t* toUint16(const UChar* src)
12 { 12 {
13 // FIXME: This relies on undefined behavior however it works on the 13 // FIXME: This relies on undefined behavior however it works on the
14 // current versions of all compilers we care about and avoids making 14 // current versions of all compilers we care about and avoids making
15 // a copy of the string. 15 // a copy of the string.
16 static_assert(sizeof(UChar) == sizeof(uint16_t), "UChar should be the same s ize as uint16_t"); 16 static_assert(sizeof(UChar) == sizeof(uint16_t), "UChar should be the same s ize as uint16_t");
17 return reinterpret_cast<const uint16_t*>(src); 17 return reinterpret_cast<const uint16_t*>(src);
18 } 18 }
19 19
20 20
21 CaseMappingHarfBuzzBufferFiller::CaseMappingHarfBuzzBufferFiller( 21 CaseMappingHarfBuzzBufferFiller::CaseMappingHarfBuzzBufferFiller(
22 CaseMapIntend caseMapIntend, 22 CaseMapIntend caseMapIntend,
23 AtomicString locale,
23 hb_buffer_t* harfBuzzBuffer, 24 hb_buffer_t* harfBuzzBuffer,
24 const UChar* buffer, 25 const UChar* buffer,
25 unsigned bufferLength, 26 unsigned bufferLength,
26 unsigned startIndex, 27 unsigned startIndex,
27 unsigned numCharacters) 28 unsigned numCharacters)
28 : m_harfBuzzBuffer(harfBuzzBuffer) 29 : m_harfBuzzBuffer(harfBuzzBuffer)
29 { 30 {
30 31
31 if (caseMapIntend == CaseMapIntend::KeepSameCase) { 32 if (caseMapIntend == CaseMapIntend::KeepSameCase) {
32 hb_buffer_add_utf16(m_harfBuzzBuffer, 33 hb_buffer_add_utf16(m_harfBuzzBuffer,
33 toUint16(buffer), 34 toUint16(buffer),
34 bufferLength, 35 bufferLength,
35 startIndex, 36 startIndex,
36 numCharacters); 37 numCharacters);
37 } else { 38 } else {
38 String caseMappedText; 39 String caseMappedText;
39 if (caseMapIntend == CaseMapIntend::UpperCase) { 40 if (caseMapIntend == CaseMapIntend::UpperCase) {
40 caseMappedText = String(buffer, bufferLength).upper(); 41 caseMappedText = String(buffer, bufferLength).upper(locale);
41 } else { 42 } else {
42 caseMappedText = String(buffer, bufferLength).lower(); 43 caseMappedText = String(buffer, bufferLength).lower(locale);
43 } 44 }
44 // TODO(drott): crbug.com/589335 Implement those for the case where the 45
45 // case-mapped string differs in length through one of the rule 46 if (caseMappedText.length() != bufferLength) {
46 // references in Unicode's SpecialCasing.txt 47 fillSlowCase(caseMapIntend, locale, buffer, bufferLength, startIndex , numCharacters);
48 return;
49 }
47 50
48 ASSERT(caseMappedText.length() == bufferLength); 51 ASSERT(caseMappedText.length() == bufferLength);
49 ASSERT(!caseMappedText.is8Bit()); 52 ASSERT(!caseMappedText.is8Bit());
50 hb_buffer_add_utf16(m_harfBuzzBuffer, toUint16(caseMappedText.characters 16()), 53 hb_buffer_add_utf16(m_harfBuzzBuffer, toUint16(caseMappedText.characters 16()),
51 bufferLength, startIndex, numCharacters); 54 bufferLength, startIndex, numCharacters);
52 } 55 }
53 } 56 }
54 57
58 // TODO(drott): crbug.com/623940 Fix lack of context sensitive case mapping here .
59 void CaseMappingHarfBuzzBufferFiller::fillSlowCase(
60 CaseMapIntend caseMapIntend,
61 AtomicString locale,
62 const UChar* buffer,
63 unsigned bufferLength,
64 unsigned startIndex,
65 unsigned numCharacters)
66 {
67 // Record pre-context.
68 hb_buffer_add_utf16(m_harfBuzzBuffer, toUint16(buffer), bufferLength, startI ndex, 0);
69
70 for (unsigned charIndex = startIndex; charIndex < startIndex + numCharacters ;) {
71 unsigned newCharIndex = charIndex;
72 U16_FWD_1(buffer, newCharIndex, numCharacters);
73 String charByChar(&buffer[charIndex], newCharIndex - charIndex);
74 String caseMappedChar;
75 if (caseMapIntend == CaseMapIntend::UpperCase)
76 caseMappedChar = charByChar.upper(locale);
77 else
78 caseMappedChar = charByChar.lower(locale);
79
80 for (unsigned j = 0; j < caseMappedChar.length();) {
81 UChar32 codepoint = 0;
82 U16_NEXT(caseMappedChar.characters16(), j, caseMappedChar.length(), codepoint);
83 // Add all characters of the case mapping result at the same cluster position.
84 hb_buffer_add(m_harfBuzzBuffer, codepoint, charIndex);
85 }
86 charIndex = newCharIndex;
87 }
88
89 // Record post-context
90 hb_buffer_add_utf16(m_harfBuzzBuffer, toUint16(buffer), bufferLength, startI ndex + numCharacters, 0);
91 }
92
55 } // namespace blink 93 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698