1/* 2 * Copyright (C) 2008 Jürg Billeter <j@bitron.ch> 3 * Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com> 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 * 20 */ 21 22#include "config.h" 23#include "UnicodeGLib.h" 24 25namespace WTF { 26namespace Unicode { 27 28UChar32 foldCase(UChar32 ch) 29{ 30 GOwnPtr<GError> gerror; 31 32 GOwnPtr<char> utf8char; 33 utf8char.set(g_ucs4_to_utf8(reinterpret_cast<gunichar*>(&ch), 1, 0, 0, &gerror.outPtr())); 34 if (gerror) 35 return ch; 36 37 GOwnPtr<char> utf8caseFolded; 38 utf8caseFolded.set(g_utf8_casefold(utf8char.get(), -1)); 39 40 GOwnPtr<gunichar> ucs4Result; 41 ucs4Result.set(g_utf8_to_ucs4_fast(utf8caseFolded.get(), -1, 0)); 42 43 return *ucs4Result; 44} 45 46int foldCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) 47{ 48 *error = false; 49 GOwnPtr<GError> gerror; 50 51 GOwnPtr<char> utf8src; 52 utf8src.set(g_utf16_to_utf8(src, srcLength, 0, 0, &gerror.outPtr())); 53 if (gerror) { 54 *error = true; 55 return -1; 56 } 57 58 GOwnPtr<char> utf8result; 59 utf8result.set(g_utf8_casefold(utf8src.get(), -1)); 60 61 long utf16resultLength = -1; 62 GOwnPtr<UChar> utf16result; 63 utf16result.set(g_utf8_to_utf16(utf8result.get(), -1, 0, &utf16resultLength, &gerror.outPtr())); 64 if (gerror) { 65 *error = true; 66 return -1; 67 } 68 69 if (utf16resultLength > resultLength) { 70 *error = true; 71 return utf16resultLength; 72 } 73 memcpy(result, utf16result.get(), utf16resultLength * sizeof(UChar)); 74 75 return utf16resultLength; 76} 77 78int toLower(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) 79{ 80 *error = false; 81 GOwnPtr<GError> gerror; 82 83 GOwnPtr<char> utf8src; 84 utf8src.set(g_utf16_to_utf8(src, srcLength, 0, 0, &gerror.outPtr())); 85 if (gerror) { 86 *error = true; 87 return -1; 88 } 89 90 GOwnPtr<char> utf8result; 91 utf8result.set(g_utf8_strdown(utf8src.get(), -1)); 92 93 long utf16resultLength = -1; 94 GOwnPtr<UChar> utf16result; 95 utf16result.set(g_utf8_to_utf16(utf8result.get(), -1, 0, &utf16resultLength, &gerror.outPtr())); 96 if (gerror) { 97 *error = true; 98 return -1; 99 } 100 101 if (utf16resultLength > resultLength) { 102 *error = true; 103 return utf16resultLength; 104 } 105 memcpy(result, utf16result.get(), utf16resultLength * sizeof(UChar)); 106 107 return utf16resultLength; 108} 109 110int toUpper(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) 111{ 112 *error = false; 113 GOwnPtr<GError> gerror; 114 115 GOwnPtr<char> utf8src; 116 utf8src.set(g_utf16_to_utf8(src, srcLength, 0, 0, &gerror.outPtr())); 117 if (gerror) { 118 *error = true; 119 return -1; 120 } 121 122 GOwnPtr<char> utf8result; 123 utf8result.set(g_utf8_strup(utf8src.get(), -1)); 124 125 long utf16resultLength = -1; 126 GOwnPtr<UChar> utf16result; 127 utf16result.set(g_utf8_to_utf16(utf8result.get(), -1, 0, &utf16resultLength, &gerror.outPtr())); 128 if (gerror) { 129 *error = true; 130 return -1; 131 } 132 133 if (utf16resultLength > resultLength) { 134 *error = true; 135 return utf16resultLength; 136 } 137 memcpy(result, utf16result.get(), utf16resultLength * sizeof(UChar)); 138 139 return utf16resultLength; 140} 141 142Direction direction(UChar32 c) 143{ 144 PangoBidiType type = pango_bidi_type_for_unichar(c); 145 switch (type) { 146 case PANGO_BIDI_TYPE_L: 147 return LeftToRight; 148 case PANGO_BIDI_TYPE_R: 149 return RightToLeft; 150 case PANGO_BIDI_TYPE_AL: 151 return RightToLeftArabic; 152 case PANGO_BIDI_TYPE_LRE: 153 return LeftToRightEmbedding; 154 case PANGO_BIDI_TYPE_RLE: 155 return RightToLeftEmbedding; 156 case PANGO_BIDI_TYPE_LRO: 157 return LeftToRightOverride; 158 case PANGO_BIDI_TYPE_RLO: 159 return RightToLeftOverride; 160 case PANGO_BIDI_TYPE_PDF: 161 return PopDirectionalFormat; 162 case PANGO_BIDI_TYPE_EN: 163 return EuropeanNumber; 164 case PANGO_BIDI_TYPE_AN: 165 return ArabicNumber; 166 case PANGO_BIDI_TYPE_ES: 167 return EuropeanNumberSeparator; 168 case PANGO_BIDI_TYPE_ET: 169 return EuropeanNumberTerminator; 170 case PANGO_BIDI_TYPE_CS: 171 return CommonNumberSeparator; 172 case PANGO_BIDI_TYPE_NSM: 173 return NonSpacingMark; 174 case PANGO_BIDI_TYPE_BN: 175 return BoundaryNeutral; 176 case PANGO_BIDI_TYPE_B: 177 return BlockSeparator; 178 case PANGO_BIDI_TYPE_S: 179 return SegmentSeparator; 180 case PANGO_BIDI_TYPE_WS: 181 return WhiteSpaceNeutral; 182 default: 183 return OtherNeutral; 184 } 185} 186 187int umemcasecmp(const UChar* a, const UChar* b, int len) 188{ 189 GOwnPtr<char> utf8a; 190 GOwnPtr<char> utf8b; 191 192 utf8a.set(g_utf16_to_utf8(a, len, 0, 0, 0)); 193 utf8b.set(g_utf16_to_utf8(b, len, 0, 0, 0)); 194 195 GOwnPtr<char> foldedA; 196 GOwnPtr<char> foldedB; 197 198 foldedA.set(g_utf8_casefold(utf8a.get(), -1)); 199 foldedB.set(g_utf8_casefold(utf8b.get(), -1)); 200 201 // FIXME: umemcasecmp needs to mimic u_memcasecmp of icu 202 // from the ICU docs: 203 // "Compare two strings case-insensitively using full case folding. 204 // his is equivalent to u_strcmp(u_strFoldCase(s1, n, options), u_strFoldCase(s2, n, options))." 205 // 206 // So it looks like we don't need the full g_utf8_collate here, 207 // but really a bitwise comparison of casefolded unicode chars (not utf-8 bytes). 208 // As there is no direct equivalent to this icu function in GLib, for now 209 // we'll use g_utf8_collate(): 210 211 return g_utf8_collate(foldedA.get(), foldedB.get()); 212} 213 214} 215} 216