tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ubidi_props.cpp (7431B)


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