示例#1
0
文件: bidi.c 项目: klickverbot/wine
/*------------------------------------------------------------------------
    Function: resolveWhiteSpace

    Resolves levels for WS and S
    Implements rule L1 of the Unicode bidi Algorithm.

    Input:  Base embedding level
            Character count
            Array of direction classes (for one line of text)

    In/Out: Array of embedding levels (for one line of text)

    Note: this should be applied a line at a time. The default driver
          code supplied in this file assumes a single line of text; for
          a real implementation, cch and the initial pointer values
          would have to be adjusted.
------------------------------------------------------------------------*/
static void resolveWhitespace(int baselevel, const WORD *pcls, BYTE *plevel, int cch)
{
    int cchrun = 0;
    BYTE oldlevel = baselevel;

    int ich = 0;
    for (; ich < cch; ich++)
    {
        switch(pcls[ich])
        {
        default:
            cchrun = 0; /* any other character breaks the run */
            break;
        case WS:
            cchrun++;
            break;

        case RLE:
        case LRE:
        case LRO:
        case RLO:
        case PDF:
        case BN:
            plevel[ich] = oldlevel;
            cchrun++;
            break;

        case S:
        case B:
            /* reset levels for WS before eot */
            SetDeferredRun(plevel, cchrun, ich, baselevel);
            cchrun = 0;
            plevel[ich] = baselevel;
            break;
        }
        oldlevel = plevel[ich];
    }
    /* reset level before eot */
    SetDeferredRun(plevel, cchrun, ich, baselevel);
}
/*------------------------------------------------------------------------
    Function: resolveWeak

    Resolves the directionality of numeric and other weak character types

    Implements rules X10 and W1-W6 of the Unicode Bidirectional Algorithm.

    Input: Array of embedding levels
           Character count

    In/Out: Array of directional classes

    Note: On input only these directional classes are expected
          AL, HL, R, L,  ON, BN, NSM, AN, EN, ES, ET, CS,
------------------------------------------------------------------------*/
void resolveWeak(int baselevel, int *pcls, int *plevel, int cch) {
    int state = odd(baselevel) ? xl : xr;
    int action;
    
    int cls;
    int clsRun;
    int clsNew;
    
    int level = baselevel;
    
    int cchRun = 0;
    
    int ich = 0;
    for (; ich < cch; ich++) {
        // ignore boundary neutrals
        if (pcls[ich] == BN) {
            // must flatten levels unless at a level change;
            plevel[ich] = level;
            
            // lookahead for level changes
            if (ich + 1 == cch && level != baselevel) {
                // have to fixup last BN before end of the loop, since
                // its fix-upped value will be needed below the assert
                pcls[ich] = EmbeddingDirection(level);
            } else if (ich + 1 < cch && level != plevel[ich+1] && pcls[ich+1] != BN) {
                // fixup LAST BN in front / after a level run to make
                // it act like the SOR/EOR in rule X10
                int newlevel = plevel[ich+1];
                if (level > newlevel) {
                    newlevel = level;
                }
                plevel[ich] = newlevel;
                
                // must match assigned level
                pcls[ich] = EmbeddingDirection(newlevel);
                level = plevel[ich+1];
            } else {
                // don't interrupt runs
                if (cchRun) {
                    cchRun++;
                }
                
                continue;
            }
        }
        
        cls = pcls[ich];
        
        action = actionWeak[state][cls];
        
        // resolve the directionality for deferred runs
        clsRun = GetDeferredType(action);
        if (clsRun != XX) {
            SetDeferredRun(pcls, cchRun, ich, clsRun);
            cchRun = 0;
        }
        
        // resolve the directionality class at the current location
        clsNew = GetResolvedType(action);
        if (clsNew != XX) {
            pcls[ich] = clsNew;
        }
        
        // increment a deferred run
        if (IX & action) {
            cchRun++;
        }
        
        state = stateWeak[state][cls];
    }
    
    // resolve any deferred runs
    // use the direction of the current level to emulate PDF
    cls = EmbeddingDirection(level);
    
    // resolve the directionality for deferred runs
    clsRun = GetDeferredType(actionWeak[state][cls]);
    if (clsRun != XX) {
        SetDeferredRun(pcls, cchRun, ich, clsRun);
    }
}
示例#3
0
/*------------------------------------------------------------------------
    Function: resolveWeak

    Resolves the directionality of numeric and other weak character types

    Implements rules X10 and W1-W6 of the Unicode Bidirectional Algorithm.

    Input: Array of embedding levels
           Character count

    In/Out: Array of directional classes

    Note: On input only these directional classes are expected
          AL, HL, R, L,  ON, BN, NSM, AN, EN, ES, ET, CS,
------------------------------------------------------------------------*/
static void resolveWeak(int baselevel, WORD *pcls, WORD *plevel, int cch)
{
    int state = odd(baselevel) ? xr : xl;
    int cls;

    int level = baselevel;
    int action, clsRun, clsNew;
    int cchRun = 0;
    int ich = 0;

    for (; ich < cch; ich++)
    {
        /* ignore boundary neutrals */
        if (pcls[ich] == BN)
        {
            /* must flatten levels unless at a level change; */
            plevel[ich] = level;

            /* lookahead for level changes */
            if (ich + 1 == cch && level != baselevel)
            {
                /* have to fixup last BN before end of the loop, since
                 * its fix-upped value will be needed below the assert */
                pcls[ich] = EmbeddingDirection(level);
            }
            else if (ich + 1 < cch && level != plevel[ich+1] && pcls[ich+1] != BN)
            {
                /* fixup LAST BN in front / after a level run to make
                 * it act like the SOR/EOR in rule X10 */
                int newlevel = plevel[ich+1];
                if (level > newlevel) {
                    newlevel = level;
                }
                plevel[ich] = newlevel;

                /* must match assigned level */
                pcls[ich] = EmbeddingDirection(newlevel);
                level = plevel[ich+1];
            }
            else
            {
                /* don't interrupt runs */
                if (cchRun)
                {
                    cchRun++;
                }
                continue;
            }
        }

        ASSERT(pcls[ich] <= BN);
        cls = pcls[ich];

        action = actionWeak[state][cls];

        /* resolve the directionality for deferred runs */
        clsRun = GetDeferredType(action);
        if (clsRun != XX)
        {
            SetDeferredRun(pcls, cchRun, ich, clsRun);
            cchRun = 0;
        }

        /* resolve the directionality class at the current location */
        clsNew = GetResolvedType(action);
        if (clsNew != XX)
            pcls[ich] = clsNew;

        /* increment a deferred run */
        if (IX & action)
            cchRun++;

        state = stateWeak[state][cls];
    }

    /* resolve any deferred runs
     * use the direction of the current level to emulate PDF */
    cls = EmbeddingDirection(level);

    /* resolve the directionality for deferred runs */
    clsRun = GetDeferredType(actionWeak[state][cls]);
    if (clsRun != XX)
        SetDeferredRun(pcls, cchRun, ich, clsRun);
}