OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ******************************************************************************* |
| 3 * |
| 4 * Copyright (C) 2004-2010, International Business Machines |
| 5 * Corporation and others. All Rights Reserved. |
| 6 * |
| 7 ******************************************************************************* |
| 8 * file name: ubidi_props.c |
| 9 * encoding: US-ASCII |
| 10 * tab size: 8 (not used) |
| 11 * indentation:4 |
| 12 * |
| 13 * created on: 2004dec30 |
| 14 * created by: Markus W. Scherer |
| 15 * |
| 16 * Low-level Unicode bidi/shaping properties access. |
| 17 */ |
| 18 |
| 19 #include "unicode/utypes.h" |
| 20 #include "unicode/uset.h" |
| 21 #include "unicode/udata.h" /* UDataInfo */ |
| 22 #include "ucmndata.h" /* DataHeader */ |
| 23 #include "udatamem.h" |
| 24 #include "umutex.h" |
| 25 #include "uassert.h" |
| 26 #include "cmemory.h" |
| 27 #include "utrie2.h" |
| 28 #include "ubidi_props.h" |
| 29 #include "ucln_cmn.h" |
| 30 |
| 31 struct UBiDiProps { |
| 32 UDataMemory *mem; |
| 33 const int32_t *indexes; |
| 34 const uint32_t *mirrors; |
| 35 const uint8_t *jgArray; |
| 36 |
| 37 UTrie2 trie; |
| 38 uint8_t formatVersion[4]; |
| 39 }; |
| 40 |
| 41 /* ubidi_props_data.c is machine-generated by genbidi --csource */ |
| 42 #include "ubidi_props_data.c" |
| 43 |
| 44 /* UBiDiProps singleton ----------------------------------------------------- */ |
| 45 |
| 46 U_CFUNC const UBiDiProps * |
| 47 ubidi_getSingleton() { |
| 48 return &ubidi_props_singleton; |
| 49 } |
| 50 |
| 51 /* set of property starts for UnicodeSet ------------------------------------ */ |
| 52 |
| 53 static UBool U_CALLCONV |
| 54 _enumPropertyStartsRange(const void *context, UChar32 start, UChar32 end, uint32
_t value) { |
| 55 /* add the start code point to the USet */ |
| 56 const USetAdder *sa=(const USetAdder *)context; |
| 57 sa->add(sa->set, start); |
| 58 return TRUE; |
| 59 } |
| 60 |
| 61 U_CFUNC void |
| 62 ubidi_addPropertyStarts(const UBiDiProps *bdp, const USetAdder *sa, UErrorCode *
pErrorCode) { |
| 63 int32_t i, length; |
| 64 UChar32 c, start, limit; |
| 65 |
| 66 const uint8_t *jgArray; |
| 67 uint8_t prev, jg; |
| 68 |
| 69 if(U_FAILURE(*pErrorCode)) { |
| 70 return; |
| 71 } |
| 72 |
| 73 /* add the start code point of each same-value range of the trie */ |
| 74 utrie2_enum(&bdp->trie, NULL, _enumPropertyStartsRange, sa); |
| 75 |
| 76 /* add the code points from the bidi mirroring table */ |
| 77 length=bdp->indexes[UBIDI_IX_MIRROR_LENGTH]; |
| 78 for(i=0; i<length; ++i) { |
| 79 c=UBIDI_GET_MIRROR_CODE_POINT(bdp->mirrors[i]); |
| 80 sa->addRange(sa->set, c, c+1); |
| 81 } |
| 82 |
| 83 /* add the code points from the Joining_Group array where the value changes
*/ |
| 84 start=bdp->indexes[UBIDI_IX_JG_START]; |
| 85 limit=bdp->indexes[UBIDI_IX_JG_LIMIT]; |
| 86 jgArray=bdp->jgArray; |
| 87 prev=0; |
| 88 while(start<limit) { |
| 89 jg=*jgArray++; |
| 90 if(jg!=prev) { |
| 91 sa->add(sa->set, start); |
| 92 prev=jg; |
| 93 } |
| 94 ++start; |
| 95 } |
| 96 if(prev!=0) { |
| 97 /* add the limit code point if the last value was not 0 (it is now start
==limit) */ |
| 98 sa->add(sa->set, limit); |
| 99 } |
| 100 |
| 101 /* add code points with hardcoded properties, plus the ones following them *
/ |
| 102 |
| 103 /* (none right now) */ |
| 104 } |
| 105 |
| 106 /* property access functions ------------------------------------------------ */ |
| 107 |
| 108 U_CFUNC int32_t |
| 109 ubidi_getMaxValue(const UBiDiProps *bdp, UProperty which) { |
| 110 int32_t max; |
| 111 |
| 112 if(bdp==NULL) { |
| 113 return -1; |
| 114 } |
| 115 |
| 116 max=bdp->indexes[UBIDI_MAX_VALUES_INDEX]; |
| 117 switch(which) { |
| 118 case UCHAR_BIDI_CLASS: |
| 119 return (max&UBIDI_CLASS_MASK); |
| 120 case UCHAR_JOINING_GROUP: |
| 121 return (max&UBIDI_MAX_JG_MASK)>>UBIDI_MAX_JG_SHIFT; |
| 122 case UCHAR_JOINING_TYPE: |
| 123 return (max&UBIDI_JT_MASK)>>UBIDI_JT_SHIFT; |
| 124 default: |
| 125 return -1; /* undefined */ |
| 126 } |
| 127 } |
| 128 |
| 129 U_CAPI UCharDirection |
| 130 ubidi_getClass(const UBiDiProps *bdp, UChar32 c) { |
| 131 uint16_t props=UTRIE2_GET16(&bdp->trie, c); |
| 132 return (UCharDirection)UBIDI_GET_CLASS(props); |
| 133 } |
| 134 |
| 135 U_CFUNC UBool |
| 136 ubidi_isMirrored(const UBiDiProps *bdp, UChar32 c) { |
| 137 uint16_t props=UTRIE2_GET16(&bdp->trie, c); |
| 138 return (UBool)UBIDI_GET_FLAG(props, UBIDI_IS_MIRRORED_SHIFT); |
| 139 } |
| 140 |
| 141 U_CFUNC UChar32 |
| 142 ubidi_getMirror(const UBiDiProps *bdp, UChar32 c) { |
| 143 uint16_t props=UTRIE2_GET16(&bdp->trie, c); |
| 144 int32_t delta=((int16_t)props)>>UBIDI_MIRROR_DELTA_SHIFT; |
| 145 if(delta!=UBIDI_ESC_MIRROR_DELTA) { |
| 146 return c+delta; |
| 147 } else { |
| 148 /* look for mirror code point in the mirrors[] table */ |
| 149 const uint32_t *mirrors; |
| 150 uint32_t m; |
| 151 int32_t i, length; |
| 152 UChar32 c2; |
| 153 |
| 154 mirrors=bdp->mirrors; |
| 155 length=bdp->indexes[UBIDI_IX_MIRROR_LENGTH]; |
| 156 |
| 157 /* linear search */ |
| 158 for(i=0; i<length; ++i) { |
| 159 m=mirrors[i]; |
| 160 c2=UBIDI_GET_MIRROR_CODE_POINT(m); |
| 161 if(c==c2) { |
| 162 /* found c, return its mirror code point using the index in m */ |
| 163 return UBIDI_GET_MIRROR_CODE_POINT(mirrors[UBIDI_GET_MIRROR_INDE
X(m)]); |
| 164 } else if(c<c2) { |
| 165 break; |
| 166 } |
| 167 } |
| 168 |
| 169 /* c not found, return it itself */ |
| 170 return c; |
| 171 } |
| 172 } |
| 173 |
| 174 U_CFUNC UBool |
| 175 ubidi_isBidiControl(const UBiDiProps *bdp, UChar32 c) { |
| 176 uint16_t props=UTRIE2_GET16(&bdp->trie, c); |
| 177 return (UBool)UBIDI_GET_FLAG(props, UBIDI_BIDI_CONTROL_SHIFT); |
| 178 } |
| 179 |
| 180 U_CFUNC UBool |
| 181 ubidi_isJoinControl(const UBiDiProps *bdp, UChar32 c) { |
| 182 uint16_t props=UTRIE2_GET16(&bdp->trie, c); |
| 183 return (UBool)UBIDI_GET_FLAG(props, UBIDI_JOIN_CONTROL_SHIFT); |
| 184 } |
| 185 |
| 186 U_CFUNC UJoiningType |
| 187 ubidi_getJoiningType(const UBiDiProps *bdp, UChar32 c) { |
| 188 uint16_t props=UTRIE2_GET16(&bdp->trie, c); |
| 189 return (UJoiningType)((props&UBIDI_JT_MASK)>>UBIDI_JT_SHIFT); |
| 190 } |
| 191 |
| 192 U_CFUNC UJoiningGroup |
| 193 ubidi_getJoiningGroup(const UBiDiProps *bdp, UChar32 c) { |
| 194 UChar32 start, limit; |
| 195 |
| 196 start=bdp->indexes[UBIDI_IX_JG_START]; |
| 197 limit=bdp->indexes[UBIDI_IX_JG_LIMIT]; |
| 198 if(start<=c && c<limit) { |
| 199 return (UJoiningGroup)bdp->jgArray[c-start]; |
| 200 } else { |
| 201 return U_JG_NO_JOINING_GROUP; |
| 202 } |
| 203 } |
| 204 |
| 205 /* public API (see uchar.h) ------------------------------------------------- */ |
| 206 |
| 207 U_CFUNC UCharDirection |
| 208 u_charDirection(UChar32 c) { |
| 209 return ubidi_getClass(&ubidi_props_singleton, c); |
| 210 } |
| 211 |
| 212 U_CFUNC UBool |
| 213 u_isMirrored(UChar32 c) { |
| 214 return ubidi_isMirrored(&ubidi_props_singleton, c); |
| 215 } |
| 216 |
| 217 U_CFUNC UChar32 |
| 218 u_charMirror(UChar32 c) { |
| 219 return ubidi_getMirror(&ubidi_props_singleton, c); |
| 220 } |
OLD | NEW |