Changeset 243049 in webkit
- Timestamp:
- Mar 16, 2019, 7:20:52 PM (7 years ago)
- Location:
- trunk/Source
- Files:
-
- 13 edited
-
JavaScriptCore/ChangeLog (modified) (1 diff)
-
JavaScriptCore/runtime/JSString.h (modified) (1 diff)
-
JavaScriptCore/runtime/StringPrototype.cpp (modified) (3 diffs)
-
WTF/ChangeLog (modified) (1 diff)
-
WTF/wtf/URLHelpers.cpp (modified) (6 diffs)
-
WTF/wtf/text/StringView.cpp (modified) (3 diffs)
-
WTF/wtf/text/StringView.h (modified) (5 diffs)
-
WebCore/ChangeLog (modified) (1 diff)
-
WebCore/editing/TextIterator.cpp (modified) (4 diffs)
-
WebCore/platform/graphics/SurrogatePairAwareTextIterator.cpp (modified) (5 diffs)
-
WebCore/platform/graphics/cairo/FontCairoHarfbuzzNG.cpp (modified) (3 diffs)
-
WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp (modified) (1 diff)
-
WebCore/platform/text/TextEncoding.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r243032 r243049 1 2019-03-16 Darin Adler <darin@apple.com> 2 3 Improve normalization code, including moving from unorm.h to unorm2.h 4 https://bugs.webkit.org/show_bug.cgi?id=195330 5 6 Reviewed by Michael Catanzaro. 7 8 * runtime/JSString.h: Move StringViewWithUnderlyingString to StringView.h. 9 10 * runtime/StringPrototype.cpp: Include unorm2.h instead of unorm.h. 11 (JSC::normalizer): Added. Function to create normalizer object given 12 enumeration value indicating which is selected. Simplified because we 13 know the function will not fail and so we don't need error handling code. 14 (JSC::normalize): Changed this function to take a JSString* so we can 15 optimize the case where no normalization is needed. Added an early exit 16 if the string is stored as 8-bit and another if the string is already 17 normalized, using unorm2_isNormalized. Changed error handling to only 18 check cases that can actually fail in practice. Also did other small 19 optimizations like passing VM rather than ExecState. 20 (JSC::stringProtoFuncNormalize): Used smaller enumeration names that are 21 identical to the names used in the API and normalization parlance rather 22 than longer ones that expand the acronyms. Updated to pass JSString* to 23 the normalize function, so we can optimize 8-bit and already-normalized 24 cases, rather than callling the expensive String::upconvertedCharacters 25 function. Use throwVMRangeError. 26 1 27 2019-03-15 Mark Lam <mark.lam@apple.com> 2 28 -
trunk/Source/JavaScriptCore/runtime/JSString.h
r242519 r243049 67 67 bool isJSString(JSValue); 68 68 JSString* asString(JSValue); 69 70 struct StringViewWithUnderlyingString {71 StringView view;72 String underlyingString;73 };74 75 69 76 70 // In 64bit architecture, JSString and JSRopeString have the following memory layout to make sizeof(JSString) == 16 and sizeof(JSRopeString) == 32. -
trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp
r242252 r243049 50 50 #include <algorithm> 51 51 #include <unicode/uconfig.h> 52 #include <unicode/unorm .h>52 #include <unicode/unorm2.h> 53 53 #include <unicode/ustring.h> 54 54 #include <wtf/ASCIICType.h> … … 1806 1806 } 1807 1807 1808 enum class NormalizationForm { 1809 CanonicalComposition, 1810 CanonicalDecomposition, 1811 CompatibilityComposition, 1812 CompatibilityDecomposition 1813 }; 1814 1815 static JSValue normalize(ExecState* exec, const UChar* source, size_t sourceLength, NormalizationForm form) 1816 { 1817 VM& vm = exec->vm(); 1818 auto scope = DECLARE_THROW_SCOPE(vm); 1819 1808 enum class NormalizationForm { NFC, NFD, NFKC, NFKD }; 1809 1810 static constexpr bool normalizationAffects8Bit(NormalizationForm form) 1811 { 1812 switch (form) { 1813 case NormalizationForm::NFC: 1814 return false; 1815 case NormalizationForm::NFD: 1816 return true; 1817 case NormalizationForm::NFKC: 1818 return false; 1819 case NormalizationForm::NFKD: 1820 return true; 1821 } 1822 ASSERT_NOT_REACHED(); 1823 return true; 1824 } 1825 1826 static const UNormalizer2* normalizer(NormalizationForm form) 1827 { 1820 1828 UErrorCode status = U_ZERO_ERROR; 1821 // unorm2_get*Instance() documentation says: "Returns an unmodifiable singleton instance. Do not delete it."1822 1829 const UNormalizer2* normalizer = nullptr; 1823 1830 switch (form) { 1824 case NormalizationForm:: CanonicalComposition:1831 case NormalizationForm::NFC: 1825 1832 normalizer = unorm2_getNFCInstance(&status); 1826 1833 break; 1827 case NormalizationForm:: CanonicalDecomposition:1834 case NormalizationForm::NFD: 1828 1835 normalizer = unorm2_getNFDInstance(&status); 1829 1836 break; 1830 case NormalizationForm:: CompatibilityComposition:1837 case NormalizationForm::NFKC: 1831 1838 normalizer = unorm2_getNFKCInstance(&status); 1832 1839 break; 1833 case NormalizationForm:: CompatibilityDecomposition:1840 case NormalizationForm::NFKD: 1834 1841 normalizer = unorm2_getNFKDInstance(&status); 1835 1842 break; 1836 1843 } 1837 1838 if (!normalizer || U_FAILURE(status)) 1839 return throwTypeError(exec, scope); 1840 1841 int32_t normalizedStringLength = unorm2_normalize(normalizer, source, sourceLength, nullptr, 0, &status); 1842 1843 if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) { 1844 // The behavior is not specified when normalize fails. 1845 // Now we throw a type error since it seems that the contents of the string are invalid. 1846 return throwTypeError(exec, scope); 1847 } 1848 1849 UChar* buffer = nullptr; 1850 auto impl = StringImpl::tryCreateUninitialized(normalizedStringLength, buffer); 1851 if (!impl) 1844 ASSERT(normalizer); 1845 ASSERT(U_SUCCESS(status)); 1846 return normalizer; 1847 } 1848 1849 static JSValue normalize(ExecState* exec, JSString* string, NormalizationForm form) 1850 { 1851 VM& vm = exec->vm(); 1852 auto scope = DECLARE_THROW_SCOPE(vm); 1853 1854 auto viewWithString = string->viewWithUnderlyingString(exec); 1855 RETURN_IF_EXCEPTION(scope, { }); 1856 1857 StringView view = viewWithString.view; 1858 if (view.is8Bit() && (!normalizationAffects8Bit(form) || charactersAreAllASCII(view.characters8(), view.length()))) 1859 RELEASE_AND_RETURN(scope, string); 1860 1861 const UNormalizer2* normalizer = JSC::normalizer(form); 1862 1863 // Since ICU does not offer functions that can perform normalization or check for 1864 // normalization with input that is Latin-1, we need to upconvert to UTF-16 at this point. 1865 auto characters = view.upconvertedCharacters(); 1866 1867 UErrorCode status = U_ZERO_ERROR; 1868 UBool isNormalized = unorm2_isNormalized(normalizer, characters, view.length(), &status); 1869 ASSERT(U_SUCCESS(status)); 1870 if (isNormalized) 1871 RELEASE_AND_RETURN(scope, string); 1872 1873 int32_t normalizedStringLength = unorm2_normalize(normalizer, characters, view.length(), nullptr, 0, &status); 1874 ASSERT(status == U_BUFFER_OVERFLOW_ERROR); 1875 1876 UChar* buffer; 1877 auto result = StringImpl::tryCreateUninitialized(normalizedStringLength, buffer); 1878 if (!result) 1852 1879 return throwOutOfMemoryError(exec, scope); 1853 1880 1854 1881 status = U_ZERO_ERROR; 1855 unorm2_normalize(normalizer, source, sourceLength, buffer, normalizedStringLength, &status); 1856 if (U_FAILURE(status)) 1857 return throwTypeError(exec, scope); 1858 1859 RELEASE_AND_RETURN(scope, jsString(exec, WTFMove(impl))); 1882 unorm2_normalize(normalizer, characters, view.length(), buffer, normalizedStringLength, &status); 1883 ASSERT(U_SUCCESS(status)); 1884 1885 RELEASE_AND_RETURN(scope, jsString(&vm, WTFMove(result))); 1860 1886 } 1861 1887 … … 1868 1894 if (!checkObjectCoercible(thisValue)) 1869 1895 return throwVMTypeError(exec, scope); 1870 auto viewWithString = thisValue.toString(exec)->viewWithUnderlyingString(exec); 1871 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 1872 StringView view = viewWithString.view; 1873 1874 NormalizationForm form = NormalizationForm::CanonicalComposition; 1875 // Verify that the argument is provided and is not undefined. 1876 if (!exec->argument(0).isUndefined()) { 1877 String formString = exec->uncheckedArgument(0).toWTFString(exec); 1878 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 1896 JSString* string = thisValue.toString(exec); 1897 RETURN_IF_EXCEPTION(scope, { }); 1898 1899 auto form = NormalizationForm::NFC; 1900 JSValue formValue = exec->argument(0); 1901 if (!formValue.isUndefined()) { 1902 String formString = formValue.toWTFString(exec); 1903 RETURN_IF_EXCEPTION(scope, { }); 1879 1904 1880 1905 if (formString == "NFC") 1881 form = NormalizationForm:: CanonicalComposition;1906 form = NormalizationForm::NFC; 1882 1907 else if (formString == "NFD") 1883 form = NormalizationForm:: CanonicalDecomposition;1908 form = NormalizationForm::NFD; 1884 1909 else if (formString == "NFKC") 1885 form = NormalizationForm:: CompatibilityComposition;1910 form = NormalizationForm::NFKC; 1886 1911 else if (formString == "NFKD") 1887 form = NormalizationForm:: CompatibilityDecomposition;1912 form = NormalizationForm::NFKD; 1888 1913 else 1889 return throwVM Error(exec, scope, createRangeError(exec, "argument does not match any normalization form"_s));1890 } 1891 1892 RELEASE_AND_RETURN(scope, JSValue::encode(normalize(exec, view.upconvertedCharacters(), view.length(), form)));1914 return throwVMRangeError(exec, scope, "argument does not match any normalization form"_s); 1915 } 1916 1917 RELEASE_AND_RETURN(scope, JSValue::encode(normalize(exec, string, form))); 1893 1918 } 1894 1919 -
trunk/Source/WTF/ChangeLog
r243040 r243049 1 2019-03-16 Darin Adler <darin@apple.com> 2 3 Improve normalization code, including moving from unorm.h to unorm2.h 4 https://bugs.webkit.org/show_bug.cgi?id=195330 5 6 Reviewed by Michael Catanzaro. 7 8 * wtf/URLHelpers.cpp: Removed unneeded include of unorm.h since the 9 normalization code is now in StringView.cpp. 10 (WTF::URLHelpers::escapeUnsafeCharacters): Renamed from 11 createStringWithEscapedUnsafeCharacters since it now only creates 12 a new string if one is needed. Use unsigned for string lengths, since 13 that's what WTF::String uses, not size_t. Added a first loop so that 14 we can return the string unmodified if no lookalike characters are 15 found. Removed unnecessary round trip from UTF-16 and then back in 16 the case where the character is not a lookalike. 17 (WTF::URLHelpers::toNormalizationFormC): Deleted. Moved this logic 18 into the WTF::normalizedNFC function in StringView.cpp. 19 (WTF::URLHelpers::userVisibleURL): Call escapeUnsafeCharacters and 20 normalizedNFC. The normalizedNFC function is better in multiple ways, 21 but primarily it handles 8-bit strings and other already-normalized 22 strings much more efficiently. 23 24 * wtf/text/StringView.cpp: 25 (WTF::normalizedNFC): Added. This has two overloads. One is for when 26 we already have a String, and want to re-use it if no normalization 27 is needed, and another is when we only have a StringView, and may need 28 to allocate a String to hold the result. Includes a fast special case 29 for 8-bit and already-normalized strings, and uses the same strategy 30 that JSC::normalize was already using: calls unorm2_normalize twice, 31 first just to determine the length. 32 33 * wtf/text/StringView.h: Added normalizedNFC, which can be called with 34 either a StringView or a String. Also moved StringViewWithUnderlyingString 35 here from JSString.h, here for use as the return value of normalizedNFC; 36 it is used for a similar purpose in the JavaScriptCore rope implementation. 37 Also removed an inaccurate comment. 38 1 39 2019-03-16 Diego Pino Garcia <dpino@igalia.com> 2 40 -
trunk/Source/WTF/wtf/URLHelpers.cpp
r242776 r243049 1 1 /* 2 * Copyright (C) 2005 , 2007, 2014Apple Inc. All rights reserved.2 * Copyright (C) 2005-2019 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2018 Igalia S.L. 4 4 * … … 34 34 #include <mutex> 35 35 #include <unicode/uidna.h> 36 #include <unicode/unorm.h>37 36 #include <unicode/uscript.h> 38 37 #include <wtf/Optional.h> … … 738 737 } 739 738 740 static String createStringWithEscapedUnsafeCharacters(const String& sourceBuffer) 741 { 739 static String escapeUnsafeCharacters(const String& sourceBuffer) 740 { 741 unsigned length = sourceBuffer.length(); 742 743 Optional<UChar32> previousCodePoint; 744 745 unsigned i; 746 for (i = 0; i < length; ) { 747 UChar32 c = sourceBuffer.characterStartingAt(i); 748 if (isLookalikeCharacter(previousCodePoint, sourceBuffer.characterStartingAt(i))) 749 break; 750 previousCodePoint = c; 751 i += U16_LENGTH(c); 752 } 753 754 if (i == length) 755 return sourceBuffer; 756 742 757 Vector<UChar, urlBytesBufferLength> outBuffer; 743 758 744 const size_t length = sourceBuffer.length(); 745 746 Optional<UChar32> previousCodePoint; 747 size_t i = 0; 748 while (i < length) { 759 outBuffer.grow(i); 760 if (sourceBuffer.is8Bit()) 761 StringImpl::copyCharacters(outBuffer.data(), sourceBuffer.characters8(), i); 762 else 763 StringImpl::copyCharacters(outBuffer.data(), sourceBuffer.characters16(), i); 764 765 for (; i < length; ) { 749 766 UChar32 c = sourceBuffer.characterStartingAt(i); 750 767 unsigned characterLength = U16_LENGTH(c); 751 768 if (isLookalikeCharacter(previousCodePoint, c)) { 752 769 uint8_t utf8Buffer[4]; … … 755 772 U8_APPEND(utf8Buffer, offset, 4, c, failure) 756 773 ASSERT(!failure); 757 774 758 775 for (size_t j = 0; j < offset; ++j) { 759 776 outBuffer.append('%'); … … 762 779 } 763 780 } else { 764 UChar utf16Buffer[2]; 765 size_t offset = 0; 766 UBool failure = false; 767 U16_APPEND(utf16Buffer, offset, 2, c, failure) 768 ASSERT(!failure); 769 for (size_t j = 0; j < offset; ++j) 770 outBuffer.append(utf16Buffer[j]); 781 for (unsigned j = 0; j < characterLength; ++j) 782 outBuffer.append(sourceBuffer[i + j]); 771 783 } 772 784 previousCodePoint = c; 773 i += U16_LENGTH(c); 774 } 785 i += characterLength; 786 } 787 775 788 return String::adopt(WTFMove(outBuffer)); 776 }777 778 static String toNormalizationFormC(const String& string)779 {780 Vector<UChar> sourceBuffer = string.charactersWithNullTermination();781 ASSERT(sourceBuffer.last() == '\0');782 sourceBuffer.removeLast();783 784 UErrorCode uerror = U_ZERO_ERROR;785 const UNormalizer2* normalizer = unorm2_getNFCInstance(&uerror);786 if (U_FAILURE(uerror))787 return { };788 789 UNormalizationCheckResult checkResult = unorm2_quickCheck(normalizer, sourceBuffer.data(), sourceBuffer.size(), &uerror);790 if (U_FAILURE(uerror))791 return { };792 793 // No need to normalize if already normalized.794 if (checkResult == UNORM_YES)795 return string;796 797 Vector<UChar, urlBytesBufferLength> normalizedCharacters(sourceBuffer.size());798 auto normalizedLength = unorm2_normalize(normalizer, sourceBuffer.data(), sourceBuffer.size(), normalizedCharacters.data(), normalizedCharacters.size(), &uerror);799 if (uerror == U_BUFFER_OVERFLOW_ERROR) {800 uerror = U_ZERO_ERROR;801 normalizedCharacters.resize(normalizedLength);802 normalizedLength = unorm2_normalize(normalizer, sourceBuffer.data(), sourceBuffer.size(), normalizedCharacters.data(), normalizedLength, &uerror);803 }804 if (U_FAILURE(uerror))805 return { };806 807 return String(normalizedCharacters.data(), normalizedLength);808 789 } 809 790 … … 892 873 } 893 874 894 auto normalized = toNormalizationFormC(result); 895 return createStringWithEscapedUnsafeCharacters(normalized); 875 return escapeUnsafeCharacters(normalizedNFC(result)); 896 876 } 897 877 -
trunk/Source/WTF/wtf/text/StringView.cpp
r241183 r243049 1 1 /* 2 2 3 Copyright (C) 2014-201 7Apple Inc. All rights reserved.3 Copyright (C) 2014-2019 Apple Inc. All rights reserved. 4 4 5 5 Redistribution and use in source and binary forms, with or without … … 30 30 #include <mutex> 31 31 #include <unicode/ubrk.h> 32 #include <unicode/unorm2.h> 32 33 #include <wtf/HashMap.h> 33 34 #include <wtf/Lock.h> … … 239 240 return convertASCIICase<ASCIICase::Upper>(static_cast<const LChar*>(m_characters), m_length); 240 241 return convertASCIICase<ASCIICase::Upper>(static_cast<const UChar*>(m_characters), m_length); 242 } 243 244 StringViewWithUnderlyingString normalizedNFC(StringView string) 245 { 246 // Latin-1 characters are unaffected by normalization. 247 if (string.is8Bit()) 248 return { string, { } }; 249 250 UErrorCode status = U_ZERO_ERROR; 251 const UNormalizer2* normalizer = unorm2_getNFCInstance(&status); 252 ASSERT(U_SUCCESS(status)); 253 254 // No need to normalize if already normalized. 255 UBool checkResult = unorm2_isNormalized(normalizer, string.characters16(), string.length(), &status); 256 if (checkResult) 257 return { string, { } }; 258 259 unsigned normalizedLength = unorm2_normalize(normalizer, string.characters16(), string.length(), nullptr, 0, &status); 260 ASSERT(status == U_BUFFER_OVERFLOW_ERROR); 261 262 UChar* characters; 263 String result = String::createUninitialized(normalizedLength, characters); 264 265 status = U_ZERO_ERROR; 266 unorm2_normalize(normalizer, string.characters16(), string.length(), characters, normalizedLength, &status); 267 ASSERT(U_SUCCESS(status)); 268 269 StringView view { result }; 270 return { view, WTFMove(result) }; 271 } 272 273 String normalizedNFC(const String& string) 274 { 275 auto result = normalizedNFC(StringView { string }); 276 if (result.underlyingString.isNull()) 277 return string; 278 return result.underlyingString; 241 279 } 242 280 -
trunk/Source/WTF/wtf/text/StringView.h
r242308 r243049 1 1 /* 2 * Copyright (C) 2014-201 7Apple Inc. All rights reserved.2 * Copyright (C) 2014-2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 212 212 inline bool operator!=(const char*a, StringView b) { return !equal(b, a); } 213 213 214 struct StringViewWithUnderlyingString; 215 216 // This returns a StringView of the normalized result, and a String that is either 217 // null, if the input was already normalized, or contains the normalized result 218 // and needs to be kept around so the StringView remains valid. Typically the 219 // easiest way to use it correctly is to put it into a local and use the StringView. 220 WTF_EXPORT_PRIVATE StringViewWithUnderlyingString normalizedNFC(StringView); 221 222 WTF_EXPORT_PRIVATE String normalizedNFC(const String&); 223 214 224 } 215 225 … … 219 229 namespace WTF { 220 230 231 struct StringViewWithUnderlyingString { 232 StringView view; 233 String underlyingString; 234 }; 235 221 236 inline StringView::StringView() 222 237 { 223 // FIXME: It's peculiar that null strings are 16-bit and empty strings return 8-bit (according to the is8Bit function).224 238 } 225 239 226 240 #if CHECK_STRINGVIEW_LIFETIME 241 227 242 inline StringView::~StringView() 228 243 { … … 281 296 return *this; 282 297 } 298 283 299 #endif // CHECK_STRINGVIEW_LIFETIME 284 300 … … 997 1013 using WTF::equal; 998 1014 using WTF::StringView; 1015 using WTF::StringViewWithUnderlyingString; -
trunk/Source/WebCore/ChangeLog
r243048 r243049 1 2019-03-16 Darin Adler <darin@apple.com> 2 3 Improve normalization code, including moving from unorm.h to unorm2.h 4 https://bugs.webkit.org/show_bug.cgi?id=195330 5 6 Reviewed by Michael Catanzaro. 7 8 * editing/TextIterator.cpp: Include unorm2.h. 9 (WebCore::normalizeCharacters): Rewrote to use unorm2_normalize rather than 10 unorm_normalize, but left the logic otherwise the same. 11 12 * platform/graphics/SurrogatePairAwareTextIterator.cpp: Include unorm2.h. 13 (WebCore::SurrogatePairAwareTextIterator::normalizeVoicingMarks): 14 Use unorm2_composePair instead of unorm_normalize. 15 16 * platform/graphics/cairo/FontCairoHarfbuzzNG.cpp: 17 (characterSequenceIsEmoji): Changed to use existing SurrogatePairAwareTextIterator. 18 (FontCascade::fontForCombiningCharacterSequence): Use normalizedNFC instead of 19 calling unorm2_normalize directly. 20 21 * WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp: 22 Removed unneeded include of <unicode/normlzr.h>. 23 24 * platform/text/TextEncoding.cpp: 25 (WebCore::TextEncoding::encode const): Use normalizedNFC instead of the 26 code that was here. The normalizedNFC function is better in multiple ways, 27 but primarily it handles 8-bit strings and other already-normalized 28 strings much more efficiently. 29 1 30 2019-03-16 Jer Noble <jer.noble@apple.com> 2 31 -
trunk/Source/WebCore/editing/TextIterator.cpp
r238693 r243049 1 1 /* 2 * Copyright (C) 2004-201 7Apple Inc. All rights reserved.2 * Copyright (C) 2004-2019 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2005 Alexey Proskuryakov. 4 4 * … … 61 61 #include "VisiblePosition.h" 62 62 #include "VisibleUnits.h" 63 #include <unicode/unorm2.h> 63 64 #include <wtf/Function.h> 64 65 #include <wtf/text/CString.h> … … 72 73 #endif 73 74 74 75 75 namespace WebCore { 76 76 77 using namespace WTF::Unicode; 77 78 78 using namespace HTMLNames; 79 79 … … 2015 2015 } 2016 2016 2017 ALLOW_DEPRECATED_DECLARATIONS_BEGIN2018 // NOTE: ICU's unorm_normalize function is deprecated.2019 2020 2017 static void normalizeCharacters(const UChar* characters, unsigned length, Vector<UChar>& buffer) 2021 2018 { 2022 ASSERT(length); 2019 UErrorCode status = U_ZERO_ERROR; 2020 const UNormalizer2* normalizer = unorm2_getNFCInstance(&status); 2021 ASSERT(U_SUCCESS(status)); 2023 2022 2024 2023 buffer.resize(length); 2025 2024 2026 UErrorCode status = U_ZERO_ERROR; 2027 size_t bufferSize = unorm_normalize(characters, length, UNORM_NFC, 0, buffer.data(), length, &status); 2028 ASSERT(status == U_ZERO_ERROR || status == U_STRING_NOT_TERMINATED_WARNING || status == U_BUFFER_OVERFLOW_ERROR); 2029 ASSERT(bufferSize); 2030 2031 buffer.resize(bufferSize); 2032 2033 if (status == U_ZERO_ERROR || status == U_STRING_NOT_TERMINATED_WARNING) 2025 auto normalizedLength = unorm2_normalize(normalizer, characters, length, buffer.data(), length, &status); 2026 ASSERT(U_SUCCESS(status) || status == U_BUFFER_OVERFLOW_ERROR); 2027 2028 buffer.resize(normalizedLength); 2029 2030 if (U_SUCCESS(status)) 2034 2031 return; 2035 2032 2036 2033 status = U_ZERO_ERROR; 2037 unorm_normalize(characters, length, UNORM_NFC, 0, buffer.data(), bufferSize, &status); 2038 ASSERT(status == U_STRING_NOT_TERMINATED_WARNING); 2039 } 2040 2041 ALLOW_DEPRECATED_DECLARATIONS_END 2034 unorm2_normalize(normalizer, characters, length, buffer.data(), length, &status); 2035 ASSERT(U_SUCCESS(status)); 2036 } 2042 2037 2043 2038 static bool isNonLatin1Separator(UChar32 character) -
trunk/Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.cpp
r235935 r243049 1 1 /* 2 * Copyright (C) 2003 , 2006, 2008, 2009, 2010, 2011Apple Inc. All rights reserved.2 * Copyright (C) 2003-2019 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2008 Holger Hans Peter Freyther 4 4 * Copyright (C) Research In Motion Limited 2011. All rights reserved. … … 24 24 #include "SurrogatePairAwareTextIterator.h" 25 25 26 #include <unicode/unorm .h>26 #include <unicode/unorm2.h> 27 27 28 28 namespace WebCore { … … 70 70 } 71 71 72 ALLOW_DEPRECATED_DECLARATIONS_BEGIN73 // NOTE: ICU's unorm_normalize function is deprecated.74 75 72 UChar32 SurrogatePairAwareTextIterator::normalizeVoicingMarks() 76 73 { 77 74 // According to http://www.unicode.org/Public/UNIDATA/UCD.html#Canonical_Combining_Class_Values 78 static const uint8_t hiraganaKatakanaVoicingMarksCombiningClass = 8;75 static constexpr uint8_t hiraganaKatakanaVoicingMarksCombiningClass = 8; 79 76 80 77 if (m_currentIndex + 1 >= m_endIndex) … … 82 79 83 80 if (u_getCombiningClass(m_characters[1]) == hiraganaKatakanaVoicingMarksCombiningClass) { 84 // Normalize into composed form using 3.2 rules.85 UChar normalizedCharacters[2] = { 0, 0 };86 UErrorCode uStatus = U_ZERO_ERROR;87 int32_t resultLength = unorm_normalize(m_characters, 2, UNORM_NFC, UNORM_UNICODE_3_2, &normalizedCharacters[0], 2, &uStatus);88 if ( resultLength == 1 && !uStatus)89 return normalizedCharacters[0];81 UErrorCode status = U_ZERO_ERROR; 82 const UNormalizer2* normalizer = unorm2_getNFCInstance(&status); 83 ASSERT(U_SUCCESS(status)); 84 auto composedCharacter = unorm2_composePair(normalizer, m_characters[0], m_characters[1]); 85 if (composedCharacter > 0) 86 return composedCharacter; 90 87 } 91 88 … … 93 90 } 94 91 95 ALLOW_DEPRECATED_DECLARATIONS_END96 97 92 } -
trunk/Source/WebCore/platform/graphics/cairo/FontCairoHarfbuzzNG.cpp
r241402 r243049 33 33 #include "FontCache.h" 34 34 #include "SurrogatePairAwareTextIterator.h" 35 #include <unicode/normlzr.h>36 35 37 36 namespace WebCore { … … 47 46 } 48 47 49 static bool characterSequenceIsEmoji( const Vector<UChar, 4>& normalizedCharacters, int32_t normalizedLength)48 static bool characterSequenceIsEmoji(SurrogatePairAwareTextIterator& iterator, UChar32 firstCharacter, unsigned firstClusterLength) 50 49 { 51 UChar32 character; 52 unsigned clusterLength = 0; 53 SurrogatePairAwareTextIterator iterator(normalizedCharacters.data(), 0, normalizedLength, normalizedLength); 50 UChar32 character = firstCharacter; 51 unsigned clusterLength = firstClusterLength; 54 52 if (!iterator.consume(character, clusterLength)) 55 53 return false; … … 101 99 } 102 100 103 const Font* FontCascade::fontForCombiningCharacterSequence(const UChar* characters, size_t length) const101 const Font* FontCascade::fontForCombiningCharacterSequence(const UChar* originalCharacters, size_t originalLength) const 104 102 { 105 UErrorCode error = U_ZERO_ERROR; 106 Vector<UChar, 4> normalizedCharacters(length); 107 const auto* normalizer = unorm2_getNFCInstance(&error); 108 if (U_FAILURE(error)) 109 return nullptr; 110 int32_t normalizedLength = unorm2_normalize(normalizer, characters, length, normalizedCharacters.data(), length, &error); 111 if (U_FAILURE(error)) { 112 if (error != U_BUFFER_OVERFLOW_ERROR) 113 return nullptr; 103 auto normalizedString = normalizedNFC(StringView { originalCharacters, static_cast<unsigned>(originalLength) }); 114 104 115 error = U_ZERO_ERROR; 116 normalizedCharacters.resize(normalizedLength); 117 normalizedLength = unorm2_normalize(normalizer, characters, length, normalizedCharacters.data(), normalizedLength, &error); 118 if (U_FAILURE(error)) 119 return nullptr; 120 } 105 // Code below relies on normalizedNFC never narrowing a 16-bit input string into an 8-bit output string. 106 // At the time of this writing, the function never does this, but in theory a future version could, and 107 // we would then need to add code paths here for the simpler 8-bit case. 108 auto characters = normalizedString.view.characters16(); 109 auto length = normalizedString.view.length(); 121 110 122 111 UChar32 character; 123 112 unsigned clusterLength = 0; 124 SurrogatePairAwareTextIterator iterator( normalizedCharacters.data(), 0, normalizedLength, normalizedLength);113 SurrogatePairAwareTextIterator iterator(characters, 0, length, length); 125 114 if (!iterator.consume(character, clusterLength)) 126 115 return nullptr; 127 116 128 bool isEmoji = characterSequenceIsEmoji( normalizedCharacters, normalizedLength);117 bool isEmoji = characterSequenceIsEmoji(iterator, character, clusterLength); 129 118 130 119 const Font* baseFont = glyphDataForCharacter(character, false, NormalVariant).font; 131 120 if (baseFont 132 && ( static_cast<int32_t>(clusterLength) == normalizedLength || baseFont->canRenderCombiningCharacterSequence(characters, length))121 && (clusterLength == length || baseFont->canRenderCombiningCharacterSequence(characters, length)) 133 122 && (!isEmoji || baseFont->platformData().isColorBitmapFont())) 134 123 return baseFont; -
trunk/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
r239822 r243049 51 51 #include FT_TRUETYPE_TABLES_H 52 52 #include FT_TRUETYPE_TAGS_H 53 #include <unicode/normlzr.h>54 53 #include <wtf/MathExtras.h> 55 54 -
trunk/Source/WebCore/platform/text/TextEncoding.cpp
r236674 r243049 1 1 /* 2 * Copyright (C) 2004-201 7Apple Inc. All rights reserved.2 * Copyright (C) 2004-2019 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> 4 4 * Copyright (C) 2007-2009 Torch Mobile, Inc. … … 32 32 #include "TextCodec.h" 33 33 #include "TextEncodingRegistry.h" 34 #include <unicode/unorm.h>35 34 #include <wtf/NeverDestroyed.h> 36 35 #include <wtf/StdLibExtras.h> 37 #include <wtf/text/CString.h>38 36 #include <wtf/text/StringView.h> 39 37 … … 72 70 } 73 71 74 ALLOW_DEPRECATED_DECLARATIONS_BEGIN 75 // NOTE: ICU's unorm_quickCheck and unorm_normalize functions are deprecated. 76 77 Vector<uint8_t> TextEncoding::encode(StringView text, UnencodableHandling handling) const 72 Vector<uint8_t> TextEncoding::encode(StringView string, UnencodableHandling handling) const 78 73 { 79 if (!m_name || text.isEmpty())74 if (!m_name || string.isEmpty()) 80 75 return { }; 81 82 // FIXME: Consider adding a fast case for ASCII.83 76 84 77 // FIXME: What's the right place to do normalization? 85 78 // It's a little strange to do it inside the encode function. 86 79 // Perhaps normalization should be an explicit step done before calling encode. 87 88 auto upconvertedCharacters = text.upconvertedCharacters(); 89 90 const UChar* source = upconvertedCharacters; 91 unsigned sourceLength = text.length(); 92 93 Vector<UChar> normalizedCharacters; 94 95 UErrorCode err = U_ZERO_ERROR; 96 if (unorm_quickCheck(source, sourceLength, UNORM_NFC, &err) != UNORM_YES) { 97 // First try using the length of the original string, since normalization to NFC rarely increases length. 98 normalizedCharacters.grow(sourceLength); 99 int32_t normalizedLength = unorm_normalize(source, sourceLength, UNORM_NFC, 0, normalizedCharacters.data(), sourceLength, &err); 100 if (err == U_BUFFER_OVERFLOW_ERROR) { 101 err = U_ZERO_ERROR; 102 normalizedCharacters.resize(normalizedLength); 103 normalizedLength = unorm_normalize(source, sourceLength, UNORM_NFC, 0, normalizedCharacters.data(), normalizedLength, &err); 104 } 105 ASSERT(U_SUCCESS(err)); 106 107 source = normalizedCharacters.data(); 108 sourceLength = normalizedLength; 109 } 110 111 return newTextCodec(*this)->encode(StringView { source, sourceLength }, handling); 80 auto normalizedString = normalizedNFC(string); 81 return newTextCodec(*this)->encode(normalizedString.view, handling); 112 82 } 113 114 ALLOW_DEPRECATED_DECLARATIONS_END115 83 116 84 const char* TextEncoding::domName() const
Note:
See TracChangeset
for help on using the changeset viewer.