/*------------------------------------------------------------------------ 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); } }
/*------------------------------------------------------------------------ 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); }