-#else
-/*!
- @function CFStringGetRangeOfComposedCharactersAtIndex
- Returns the range of the composed character sequence at the specified index.
- @param theString The CFString which is to be searched. If this
- parameter is not a valid CFString, the behavior is
- undefined.
- @param theIndex The index of the character contained in the
- composed character sequence. If the index is
- outside the index space of the string (0 to N-1 inclusive,
- where N is the length of the string), the behavior is
- undefined.
- @result The range of the composed character sequence.
-*/
-#define ExtHighHalfZoneLow 0xD800
-#define ExtHighHalfZoneHigh 0xDBFF
-#define ExtLowHalfZoneLow 0xDC00
-#define ExtLowHalfZoneHigh 0xDFFF
-#define JunseongStart 0x1160
-#define JonseongEnd 0x11F9
-CF_INLINE Boolean IsHighCode(UniChar X) { return (X >= ExtHighHalfZoneLow && X <= ExtHighHalfZoneHigh); }
-CF_INLINE Boolean IsLowCode(UniChar X) { return (X >= ExtLowHalfZoneLow && X <= ExtLowHalfZoneHigh); }
-#define IsHangulConjoiningJamo(X) (X >= JunseongStart && X <= JonseongEnd)
-#define IsHalfwidthKanaVoicedMark(X) ((X == 0xFF9E) || (X == 0xFF9F))
-CF_INLINE Boolean IsNonBaseChar(UniChar X, CFCharacterSetRef nonBaseSet) { return (CFCharacterSetIsCharacterMember(nonBaseSet, X) || IsHangulConjoiningJamo(X) || IsHalfwidthKanaVoicedMark(X) || (X & 0x1FFFF0) == 0xF870); } // combining char, hangul jamo, or Apple corporate variant tag
-#define ZWJ 0x200D
-#define ZWNJ 0x200C
-#define COMBINING_GRAPHEME_JOINER (0x034F)
-
-static CFCharacterSetRef nonBaseChars = NULL;
-static CFCharacterSetRef letterChars = NULL;
-static const void *__CFCombiningClassBMP = NULL;
-
-CF_INLINE bool IsVirama(UTF32Char character) {
- return ((character == COMBINING_GRAPHEME_JOINER) ? true : ((character < 0x10000) && (CFUniCharGetCombiningPropertyForCharacter(character, __CFCombiningClassBMP) == 9) ? true : false));
-}
-
-CFRange CFStringGetRangeOfComposedCharactersAtIndex(CFStringRef theString, CFIndex theIndex) {
- CFIndex left, current, save;
- CFIndex len = CFStringGetLength(theString);
- CFStringInlineBuffer stringBuffer;
- static volatile Boolean _isInited = false;
-
- if (theIndex >= len) return CFRangeMake(kCFNotFound, 0);
-
- if (!_isInited) {
- nonBaseChars = CFCharacterSetGetPredefined(kCFCharacterSetNonBase);
- letterChars = CFCharacterSetGetPredefined(kCFCharacterSetLetter);
- __CFCombiningClassBMP = CFUniCharGetUnicodePropertyDataForPlane(kCFUniCharCombiningProperty, 0);
- _isInited = true;
- }
-
- save = current = theIndex;
-
- CFStringInitInlineBuffer(theString, &stringBuffer, CFRangeMake(0, len));
-
- /*
- * First check for transcoding hints
- */
- {
- CFRange theRange = (current > MAX_TRANSCODING_LENGTH ? CFRangeMake(current - MAX_TRANSCODING_LENGTH, MAX_TRANSCODING_LENGTH + 1) : CFRangeMake(0, current + 1));
-
- // Should check the next loc ?
- if (current + 1 < len) ++theRange.length;
-
- if (theRange.length > 1) {
- UniChar characterBuffer[MAX_TRANSCODING_LENGTH + 2]; // Transcoding hint length + current loc + next loc
-
- if (stringBuffer.directBuffer) {
- memmove(characterBuffer, stringBuffer.directBuffer + theRange.location, theRange.length * sizeof(UniChar));
- } else {
- CFStringGetCharacters(theString, theRange, characterBuffer);
- }
-
- while (current >= theRange.location) {
- if ((characterBuffer[current - theRange.location] & 0x1FFFF0) == 0xF860) {
- theRange = CFRangeMake(current, __CFTranscodingHintLength[characterBuffer[current - theRange.location] - 0xF860] + 1);
- if ((theRange.location + theRange.length) <= theIndex) break;
- if ((theRange.location + theRange.length) >= len) theRange.length = len - theRange.location;
- return theRange;
- }
- if (current == 0) break;
- --current;
- }
- current = theIndex; // Reset current
- }
- }
-
-//#warning Aki 5/29/01 This does not support non-base chars in non-BMP planes (i.e. musical symbol combining stem in Unicode 3.1)
- /*
- * if we start NOT on a base, first move back to a base as appropriate.
- */
-
- roundAgain:
-
- while ((current > 0) && IsNonBaseChar(CFStringGetCharacterFromInlineBuffer(&stringBuffer, current), nonBaseChars)) --current;
-
- if (current >= 1 && current < len && CFCharacterSetIsCharacterMember(letterChars, CFStringGetCharacterFromInlineBuffer(&stringBuffer, current)) && IsVirama(CFStringGetCharacterFromInlineBuffer(&stringBuffer, current - 1))) {
- --current;
- goto roundAgain;
- } else if ((current >= 2) && (CFStringGetCharacterFromInlineBuffer(&stringBuffer, current - 1) == ZWJ) && IsVirama(CFStringGetCharacterFromInlineBuffer(&stringBuffer, current - 2))) {
- current -= 2;
- goto roundAgain;
- }
-
- /*
- * Set the left position, then jump back to the saved original position.
- */
-
- if (current >= 1 && IsLowCode(CFStringGetCharacterFromInlineBuffer(&stringBuffer, current)) && IsHighCode(CFStringGetCharacterFromInlineBuffer(&stringBuffer, current - 1))) --current;
- left = current;
- current = save;
-
- /*
- * Now, presume we are on a base; move forward & look for the next base.
- * Handle jumping over H/L codes.
- */
- if (IsHighCode(CFStringGetCharacterFromInlineBuffer(&stringBuffer, current)) && (current + 1) < len && IsLowCode(CFStringGetCharacterFromInlineBuffer(&stringBuffer, current + 1))) ++current;
- ++current;
-
- round2Again:
-
- if (current < len) {
- while (IsNonBaseChar(CFStringGetCharacterFromInlineBuffer(&stringBuffer, current), nonBaseChars)) {
- ++current;
- if (current >= len) break;
- }
- if ((current < len) && CFCharacterSetIsCharacterMember(letterChars, CFStringGetCharacterFromInlineBuffer(&stringBuffer, current))) {
- if (IsVirama(CFStringGetCharacterFromInlineBuffer(&stringBuffer, current - 1))) {
- ++current; goto round2Again;
- } else if ((current >= 2) && (CFStringGetCharacterFromInlineBuffer(&stringBuffer, current - 1) == ZWJ) && IsVirama(CFStringGetCharacterFromInlineBuffer(&stringBuffer, current - 2))) {
- ++current; goto round2Again;
- }
- }
- }
- /*
- * Now, "current" is a base, and "left" is a base.
- * The junk between had better contain "save"!
- */
- if ((! (left <= save)) || (! (save <= current))) {
- CFLog(kCFLogLevelWarning, CFSTR("CFString: CFStringGetRangeOfComposedCharactersAtIndex:%d returned invalid\n"), save);
- }
- return CFRangeMake(left, current - left);
-}
-#endif