]>
git.saurik.com Git - apple/javascriptcore.git/blob - wtf/unicode/qt4/UnicodeQt4.h
1531694432f7ff8e7f6adec2ec7db856ba171bb9
2 * Copyright (C) 2006 George Staikos <staikos@kde.org>
3 * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
4 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
23 #ifndef WTF_UNICODE_QT4_H
24 #define WTF_UNICODE_QT4_H
33 #if QT_VERSION >= 0x040300
35 namespace QUnicodeTables
{
38 ushort line_break_class
: 8;
40 ushort combiningClass
:8;
42 signed short digitValue
: 6; /* 5 needed */
43 ushort unicodeVersion
: 4;
44 ushort lowerCaseSpecial
: 1;
45 ushort upperCaseSpecial
: 1;
46 ushort titleCaseSpecial
: 1;
47 ushort caseFoldSpecial
: 1; /* currently unused */
48 signed short mirrorDiff
: 16;
49 signed short lowerCaseDiff
: 16;
50 signed short upperCaseDiff
: 16;
51 signed short titleCaseDiff
: 16;
52 signed short caseFoldDiff
: 16;
54 Q_CORE_EXPORT
const Properties
* QT_FASTCALL
properties(uint ucs4
);
55 Q_CORE_EXPORT
const Properties
* QT_FASTCALL
properties(ushort ucs2
);
60 // ugly hack to make UChar compatible with JSChar in API/JSStringRef.h
62 typedef wchar_t UChar
;
64 typedef uint16_t UChar
;
66 typedef uint32_t UChar32
;
68 // some defines from ICU
70 #define U16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800)
71 #define U16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00)
72 #define U16_SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000)
73 #define U16_GET_SUPPLEMENTARY(lead, trail) \
74 (((UChar32)(lead)<<10UL)+(UChar32)(trail)-U16_SURROGATE_OFFSET)
76 #define U16_LEAD(supplementary) (UChar)(((supplementary)>>10)+0xd7c0)
77 #define U16_TRAIL(supplementary) (UChar)(((supplementary)&0x3ff)|0xdc00)
79 #define U_IS_SURROGATE(c) (((c)&0xfffff800)==0xd800)
80 #define U16_IS_SINGLE(c) !U_IS_SURROGATE(c)
81 #define U16_IS_SURROGATE(c) U_IS_SURROGATE(c)
82 #define U16_IS_SURROGATE_LEAD(c) (((c)&0x400)==0)
84 #define U16_NEXT(s, i, length, c) { \
86 if(U16_IS_LEAD(c)) { \
88 if((i)<(length) && U16_IS_TRAIL(__c2=(s)[(i)])) { \
90 (c)=U16_GET_SUPPLEMENTARY((c), __c2); \
95 #define U16_PREV(s, start, i, c) { \
97 if(U16_IS_TRAIL(c)) { \
99 if((i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \
101 (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \
106 #define U_MASK(x) ((uint32_t)1<<(x))
112 LeftToRight
= QChar::DirL
,
113 RightToLeft
= QChar::DirR
,
114 EuropeanNumber
= QChar::DirEN
,
115 EuropeanNumberSeparator
= QChar::DirES
,
116 EuropeanNumberTerminator
= QChar::DirET
,
117 ArabicNumber
= QChar::DirAN
,
118 CommonNumberSeparator
= QChar::DirCS
,
119 BlockSeparator
= QChar::DirB
,
120 SegmentSeparator
= QChar::DirS
,
121 WhiteSpaceNeutral
= QChar::DirWS
,
122 OtherNeutral
= QChar::DirON
,
123 LeftToRightEmbedding
= QChar::DirLRE
,
124 LeftToRightOverride
= QChar::DirLRO
,
125 RightToLeftArabic
= QChar::DirAL
,
126 RightToLeftEmbedding
= QChar::DirRLE
,
127 RightToLeftOverride
= QChar::DirRLO
,
128 PopDirectionalFormat
= QChar::DirPDF
,
129 NonSpacingMark
= QChar::DirNSM
,
130 BoundaryNeutral
= QChar::DirBN
133 enum DecompositionType
{
134 DecompositionNone
= QChar::NoDecomposition
,
135 DecompositionCanonical
= QChar::Canonical
,
136 DecompositionCompat
= QChar::Compat
,
137 DecompositionCircle
= QChar::Circle
,
138 DecompositionFinal
= QChar::Final
,
139 DecompositionFont
= QChar::Font
,
140 DecompositionFraction
= QChar::Fraction
,
141 DecompositionInitial
= QChar::Initial
,
142 DecompositionIsolated
= QChar::Isolated
,
143 DecompositionMedial
= QChar::Medial
,
144 DecompositionNarrow
= QChar::Narrow
,
145 DecompositionNoBreak
= QChar::NoBreak
,
146 DecompositionSmall
= QChar::Small
,
147 DecompositionSquare
= QChar::Square
,
148 DecompositionSub
= QChar::Sub
,
149 DecompositionSuper
= QChar::Super
,
150 DecompositionVertical
= QChar::Vertical
,
151 DecompositionWide
= QChar::Wide
156 Mark_NonSpacing
= U_MASK(QChar::Mark_NonSpacing
),
157 Mark_SpacingCombining
= U_MASK(QChar::Mark_SpacingCombining
),
158 Mark_Enclosing
= U_MASK(QChar::Mark_Enclosing
),
159 Number_DecimalDigit
= U_MASK(QChar::Number_DecimalDigit
),
160 Number_Letter
= U_MASK(QChar::Number_Letter
),
161 Number_Other
= U_MASK(QChar::Number_Other
),
162 Separator_Space
= U_MASK(QChar::Separator_Space
),
163 Separator_Line
= U_MASK(QChar::Separator_Line
),
164 Separator_Paragraph
= U_MASK(QChar::Separator_Paragraph
),
165 Other_Control
= U_MASK(QChar::Other_Control
),
166 Other_Format
= U_MASK(QChar::Other_Format
),
167 Other_Surrogate
= U_MASK(QChar::Other_Surrogate
),
168 Other_PrivateUse
= U_MASK(QChar::Other_PrivateUse
),
169 Other_NotAssigned
= U_MASK(QChar::Other_NotAssigned
),
170 Letter_Uppercase
= U_MASK(QChar::Letter_Uppercase
),
171 Letter_Lowercase
= U_MASK(QChar::Letter_Lowercase
),
172 Letter_Titlecase
= U_MASK(QChar::Letter_Titlecase
),
173 Letter_Modifier
= U_MASK(QChar::Letter_Modifier
),
174 Letter_Other
= U_MASK(QChar::Letter_Other
),
175 Punctuation_Connector
= U_MASK(QChar::Punctuation_Connector
),
176 Punctuation_Dash
= U_MASK(QChar::Punctuation_Dash
),
177 Punctuation_Open
= U_MASK(QChar::Punctuation_Open
),
178 Punctuation_Close
= U_MASK(QChar::Punctuation_Close
),
179 Punctuation_InitialQuote
= U_MASK(QChar::Punctuation_InitialQuote
),
180 Punctuation_FinalQuote
= U_MASK(QChar::Punctuation_FinalQuote
),
181 Punctuation_Other
= U_MASK(QChar::Punctuation_Other
),
182 Symbol_Math
= U_MASK(QChar::Symbol_Math
),
183 Symbol_Currency
= U_MASK(QChar::Symbol_Currency
),
184 Symbol_Modifier
= U_MASK(QChar::Symbol_Modifier
),
185 Symbol_Other
= U_MASK(QChar::Symbol_Other
)
189 #if QT_VERSION >= 0x040300
191 // FIXME: handle surrogates correctly in all methods
193 inline UChar32
toLower(UChar32 ch
)
195 return QChar::toLower(ch
);
198 inline int toLower(UChar
* result
, int resultLength
, const UChar
* src
, int srcLength
, bool* error
)
200 const UChar
*e
= src
+ srcLength
;
201 const UChar
*s
= src
;
205 // this avoids one out of bounds check in the loop
206 if (s
< e
&& QChar(*s
).isLowSurrogate()) {
213 while (s
< e
&& (rindex
< uint(resultLength
) || !r
)) {
215 if (QChar(c
).isLowSurrogate() && QChar(*(s
- 1)).isHighSurrogate())
216 c
= QChar::surrogateToUcs4(*(s
- 1), c
);
217 const QUnicodeTables::Properties
*prop
= QUnicodeTables::properties(c
);
218 if (prop
->lowerCaseSpecial
) {
223 qstring
+= QChar(*(s
-1));
224 qstring
+= QChar(*s
);
226 qstring
= qstring
.toLower();
227 for (int i
= 0; i
< qstring
.length(); ++i
) {
228 if (rindex
>= uint(resultLength
)) {
229 needed
+= qstring
.length() - i
;
233 r
[rindex
] = qstring
.at(i
).unicode();
238 r
[rindex
] = *s
+ prop
->lowerCaseDiff
;
245 *error
= (needed
!= 0);
246 if (rindex
< uint(resultLength
))
248 return rindex
+ needed
;
251 inline UChar32
toUpper(UChar32 ch
)
253 return QChar::toUpper(ch
);
256 inline int toUpper(UChar
* result
, int resultLength
, const UChar
* src
, int srcLength
, bool* error
)
258 const UChar
*e
= src
+ srcLength
;
259 const UChar
*s
= src
;
263 // this avoids one out of bounds check in the loop
264 if (s
< e
&& QChar(*s
).isLowSurrogate()) {
271 while (s
< e
&& (rindex
< resultLength
|| !r
)) {
273 if (QChar(c
).isLowSurrogate() && QChar(*(s
- 1)).isHighSurrogate())
274 c
= QChar::surrogateToUcs4(*(s
- 1), c
);
275 const QUnicodeTables::Properties
*prop
= QUnicodeTables::properties(c
);
276 if (prop
->upperCaseSpecial
) {
281 qstring
+= QChar(*(s
-1));
282 qstring
+= QChar(*s
);
284 qstring
= qstring
.toUpper();
285 for (int i
= 0; i
< qstring
.length(); ++i
) {
286 if (rindex
>= resultLength
) {
287 needed
+= qstring
.length() - i
;
291 r
[rindex
] = qstring
.at(i
).unicode();
296 r
[rindex
] = *s
+ prop
->upperCaseDiff
;
303 *error
= (needed
!= 0);
304 if (rindex
< resultLength
)
306 return rindex
+ needed
;
309 inline int toTitleCase(UChar32 c
)
311 return QChar::toTitleCase(c
);
314 inline UChar32
foldCase(UChar32 c
)
316 return QChar::toCaseFolded(c
);
319 inline int foldCase(UChar
* result
, int resultLength
, const UChar
* src
, int srcLength
, bool* error
)
321 // FIXME: handle special casing. Easiest with some low level API in Qt
323 if (resultLength
< srcLength
) {
327 for (int i
= 0; i
< srcLength
; ++i
)
328 result
[i
] = QChar::toCaseFolded(ushort(src
[i
]));
332 inline bool isArabicChar(UChar32 c
)
334 return c
>= 0x0600 && c
<= 0x06FF;
337 inline bool isPrintableChar(UChar32 c
)
339 const uint test
= U_MASK(QChar::Other_Control
) |
340 U_MASK(QChar::Other_NotAssigned
);
341 return !(U_MASK(QChar::category(c
)) & test
);
344 inline bool isSeparatorSpace(UChar32 c
)
346 return QChar::category(c
) == QChar::Separator_Space
;
349 inline bool isPunct(UChar32 c
)
351 const uint test
= U_MASK(QChar::Punctuation_Connector
) |
352 U_MASK(QChar::Punctuation_Dash
) |
353 U_MASK(QChar::Punctuation_Open
) |
354 U_MASK(QChar::Punctuation_Close
) |
355 U_MASK(QChar::Punctuation_InitialQuote
) |
356 U_MASK(QChar::Punctuation_FinalQuote
) |
357 U_MASK(QChar::Punctuation_Other
);
358 return U_MASK(QChar::category(c
)) & test
;
361 inline bool isLower(UChar32 c
)
363 return QChar::category(c
) == QChar::Letter_Lowercase
;
366 inline bool hasLineBreakingPropertyComplexContext(UChar32
)
368 // FIXME: Implement this to return whether the character has line breaking property SA (Complex Context).
372 inline UChar32
mirroredChar(UChar32 c
)
374 return QChar::mirroredChar(c
);
377 inline uint8_t combiningClass(UChar32 c
)
379 return QChar::combiningClass(c
);
382 inline DecompositionType
decompositionType(UChar32 c
)
384 return (DecompositionType
)QChar::decompositionTag(c
);
387 inline int umemcasecmp(const UChar
* a
, const UChar
* b
, int len
)
389 // handle surrogates correctly
390 for (int i
= 0; i
< len
; ++i
) {
391 uint c1
= QChar::toCaseFolded(ushort(a
[i
]));
392 uint c2
= QChar::toCaseFolded(ushort(b
[i
]));
399 inline Direction
direction(UChar32 c
)
401 return (Direction
)QChar::direction(c
);
404 inline CharCategory
category(UChar32 c
)
406 return (CharCategory
) U_MASK(QChar::category(c
));
411 inline UChar32
toLower(UChar32 ch
)
415 return QChar((unsigned short)ch
).toLower().unicode();
418 inline int toLower(UChar
* result
, int resultLength
, const UChar
* src
, int srcLength
, bool* error
)
421 if (resultLength
< srcLength
) {
425 for (int i
= 0; i
< srcLength
; ++i
)
426 result
[i
] = QChar(src
[i
]).toLower().unicode();
430 inline UChar32
toUpper(UChar32 ch
)
434 return QChar((unsigned short)ch
).toUpper().unicode();
437 inline int toUpper(UChar
* result
, int resultLength
, const UChar
* src
, int srcLength
, bool* error
)
440 if (resultLength
< srcLength
) {
444 for (int i
= 0; i
< srcLength
; ++i
)
445 result
[i
] = QChar(src
[i
]).toUpper().unicode();
449 inline int toTitleCase(UChar32 c
)
453 return QChar((unsigned short)c
).toUpper().unicode();
456 inline UChar32
foldCase(UChar32 c
)
460 return QChar((unsigned short)c
).toLower().unicode();
463 inline int foldCase(UChar
* result
, int resultLength
, const UChar
* src
, int srcLength
, bool* error
)
465 return toLower(result
, resultLength
, src
, srcLength
, error
);
468 inline bool isPrintableChar(UChar32 c
)
470 return (c
& 0xffff0000) == 0 && QChar((unsigned short)c
).isPrint();
473 inline bool isArabicChar(UChar32 c
)
475 return c
>= 0x0600 && c
<= 0x06FF;
478 inline bool isSeparatorSpace(UChar32 c
)
480 return (c
& 0xffff0000) == 0 && QChar((unsigned short)c
).category() == QChar::Separator_Space
;
483 inline bool isPunct(UChar32 c
)
485 return (c
& 0xffff0000) == 0 && QChar((unsigned short)c
).isPunct();
488 inline bool isLower(UChar32 c
)
490 return (c
& 0xffff0000) == 0 && QChar((unsigned short)c
).category() == QChar::Letter_Lowercase
;
493 inline UChar32
mirroredChar(UChar32 c
)
497 return QChar(c
).mirroredChar().unicode();
500 inline uint8_t combiningClass(UChar32 c
)
504 return QChar((unsigned short)c
).combiningClass();
507 inline DecompositionType
decompositionType(UChar32 c
)
510 return DecompositionNone
;
511 return (DecompositionType
)QChar(c
).decompositionTag();
514 inline int umemcasecmp(const UChar
* a
, const UChar
* b
, int len
)
516 for (int i
= 0; i
< len
; ++i
) {
517 QChar c1
= QChar(a
[i
]).toLower();
518 QChar c2
= QChar(b
[i
]).toLower();
520 return c1
.unicode() - c2
.unicode();
525 inline Direction
direction(UChar32 c
)
529 return (Direction
)QChar(c
).direction();
532 inline CharCategory
category(UChar32 c
)
536 return (CharCategory
) U_MASK(QChar(c
).category());
543 #endif // WTF_UNICODE_QT4_H