コード例 #1
0
ファイル: ubidiln.c プロジェクト: venkatarajasekhar/Qt
U_CAPI void U_EXPORT2
ubidi_setLine(const UBiDi *pParaBiDi,
              int32_t start, int32_t limit,
              UBiDi *pLineBiDi,
              UErrorCode *pErrorCode) {
    int32_t length;

    /* check the argument values */
    RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrorCode);
    RETURN_VOID_IF_NOT_VALID_PARA(pParaBiDi, *pErrorCode);
    RETURN_VOID_IF_BAD_RANGE(start, 0, limit, *pErrorCode);
    RETURN_VOID_IF_BAD_RANGE(limit, 0, pParaBiDi->length+1, *pErrorCode);
    if(pLineBiDi==NULL) {
        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    if(ubidi_getParagraph(pParaBiDi, start, NULL, NULL, NULL, pErrorCode) !=
       ubidi_getParagraph(pParaBiDi, limit-1, NULL, NULL, NULL, pErrorCode)) {
        /* the line crosses a paragraph boundary */
        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

    /* set the values in pLineBiDi from its pParaBiDi parent */
    pLineBiDi->pParaBiDi=NULL;          /* mark unfinished setLine */
    pLineBiDi->text=pParaBiDi->text+start;
    length=pLineBiDi->length=limit-start;
    pLineBiDi->resultLength=pLineBiDi->originalLength=length;
    pLineBiDi->paraLevel=GET_PARALEVEL(pParaBiDi, start);
    pLineBiDi->paraCount=pParaBiDi->paraCount;
    pLineBiDi->runs=NULL;
    pLineBiDi->flags=0;
    pLineBiDi->reorderingMode=pParaBiDi->reorderingMode;
    pLineBiDi->reorderingOptions=pParaBiDi->reorderingOptions;
    pLineBiDi->controlCount=0;
    if(pParaBiDi->controlCount>0) {
        int32_t j;
        for(j=start; j<limit; j++) {
            if(IS_BIDI_CONTROL_CHAR(pParaBiDi->text[j])) {
                pLineBiDi->controlCount++;
            }
        }
        pLineBiDi->resultLength-=pLineBiDi->controlCount;
    }

    pLineBiDi->dirProps=pParaBiDi->dirProps+start;
    pLineBiDi->levels=pParaBiDi->levels+start;
    pLineBiDi->runCount=-1;

    if(pParaBiDi->direction!=UBIDI_MIXED) {
        /* the parent is already trivial */
        pLineBiDi->direction=pParaBiDi->direction;

        /*
         * The parent's levels are all either
         * implicitly or explicitly ==paraLevel;
         * do the same here.
         */
        if(pParaBiDi->trailingWSStart<=start) {
            pLineBiDi->trailingWSStart=0;
        } else if(pParaBiDi->trailingWSStart<limit) {
            pLineBiDi->trailingWSStart=pParaBiDi->trailingWSStart-start;
        } else {
            pLineBiDi->trailingWSStart=length;
        }
    } else {
        const UBiDiLevel *levels=pLineBiDi->levels;
        int32_t i, trailingWSStart;
        UBiDiLevel level;

        setTrailingWSStart(pLineBiDi);
        trailingWSStart=pLineBiDi->trailingWSStart;

        /* recalculate pLineBiDi->direction */
        if(trailingWSStart==0) {
            /* all levels are at paraLevel */
            pLineBiDi->direction=(UBiDiDirection)(pLineBiDi->paraLevel&1);
        } else {
            /* get the level of the first character */
            level=(UBiDiLevel)(levels[0]&1);

            /* if there is anything of a different level, then the line is mixed */
            if(trailingWSStart<length && (pLineBiDi->paraLevel&1)!=level) {
                /* the trailing WS is at paraLevel, which differs from levels[0] */
                pLineBiDi->direction=UBIDI_MIXED;
            } else {
                /* see if levels[1..trailingWSStart-1] have the same direction as levels[0] and paraLevel */
                i=1;
                for(;;) {
                    if(i==trailingWSStart) {
                        /* the direction values match those in level */
                        pLineBiDi->direction=(UBiDiDirection)level;
                        break;
                    } else if((levels[i]&1)!=level) {
                        pLineBiDi->direction=UBIDI_MIXED;
                        break;
                    }
                    ++i;
                }
            }
        }

        switch(pLineBiDi->direction) {
        case UBIDI_LTR:
            /* make sure paraLevel is even */
            pLineBiDi->paraLevel=(UBiDiLevel)((pLineBiDi->paraLevel+1)&~1);

            /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */
            pLineBiDi->trailingWSStart=0;
            break;
        case UBIDI_RTL:
            /* make sure paraLevel is odd */
            pLineBiDi->paraLevel|=1;

            /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */
            pLineBiDi->trailingWSStart=0;
            break;
        default:
            break;
        }
    }
    pLineBiDi->pParaBiDi=pParaBiDi;     /* mark successful setLine */
    return;
}
コード例 #2
0
U_CAPI void U_EXPORT2
ubidi_setLine(const UBiDi *pParaBiDi,
              int32_t start, int32_t limit,
              UBiDi *pLineBiDi,
              UErrorCode *pErrorCode) {
    int32_t length;

    /* check the argument values */
    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
        return;
    } else if(pParaBiDi==NULL || pLineBiDi==NULL) {
        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
        return;
    } else if(start<0 || start>limit || limit>pParaBiDi->length) {
        *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
        return;
    }

    /* set the values in pLineBiDi from its pParaBiDi parent */
    pLineBiDi->text=pParaBiDi->text+start;
    length=pLineBiDi->length=limit-start;
    pLineBiDi->paraLevel=pParaBiDi->paraLevel;

    pLineBiDi->runs=NULL;
    pLineBiDi->flags=0;

    if(length>0) {
        pLineBiDi->dirProps=pParaBiDi->dirProps+start;
        pLineBiDi->levels=pParaBiDi->levels+start;
        pLineBiDi->runCount=-1;

        if(pParaBiDi->direction!=UBIDI_MIXED) {
            /* the parent is already trivial */
            pLineBiDi->direction=pParaBiDi->direction;

            /*
             * The parent's levels are all either
             * implicitly or explicitly ==paraLevel;
             * do the same here.
             */
            if(pParaBiDi->trailingWSStart<=start) {
                pLineBiDi->trailingWSStart=0;
            } else if(pParaBiDi->trailingWSStart<limit) {
                pLineBiDi->trailingWSStart=pParaBiDi->trailingWSStart-start;
            } else {
                pLineBiDi->trailingWSStart=length;
            }
        } else {
            const UBiDiLevel *levels=pLineBiDi->levels;
            int32_t i, trailingWSStart;
            UBiDiLevel level;

            setTrailingWSStart(pLineBiDi);
            trailingWSStart=pLineBiDi->trailingWSStart;

            /* recalculate pLineBiDi->direction */
            if(trailingWSStart==0) {
                /* all levels are at paraLevel */
                pLineBiDi->direction=(UBiDiDirection)(pLineBiDi->paraLevel&1);
            } else {
                /* get the level of the first character */
                level=(UBiDiLevel)(levels[0]&1);

                /* if there is anything of a different level, then the line is mixed */
                if(trailingWSStart<length && (pLineBiDi->paraLevel&1)!=level) {
                    /* the trailing WS is at paraLevel, which differs from levels[0] */
                    pLineBiDi->direction=UBIDI_MIXED;
                } else {
                    /* see if levels[1..trailingWSStart-1] have the same direction as levels[0] and paraLevel */
                    i=1;
                    for(;;) {
                        if(i==trailingWSStart) {
                            /* the direction values match those in level */
                            pLineBiDi->direction=(UBiDiDirection)level;
                            break;
                        } else if((levels[i]&1)!=level) {
                            pLineBiDi->direction=UBIDI_MIXED;
                            break;
                        }
                        ++i;
                    }
                }
            }

            switch(pLineBiDi->direction) {
            case UBIDI_LTR:
                /* make sure paraLevel is even */
                pLineBiDi->paraLevel=(UBiDiLevel)((pLineBiDi->paraLevel+1)&~1);

                /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */
                pLineBiDi->trailingWSStart=0;
                break;
            case UBIDI_RTL:
                /* make sure paraLevel is odd */
                pLineBiDi->paraLevel|=1;

                /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */
                pLineBiDi->trailingWSStart=0;
                break;
            default:
                break;
            }
        }
    } else {
        /* create an object for a zero-length line */
        pLineBiDi->direction=pLineBiDi->paraLevel&1 ? UBIDI_RTL : UBIDI_LTR;
        pLineBiDi->trailingWSStart=pLineBiDi->runCount=0;

        pLineBiDi->dirProps=NULL;
        pLineBiDi->levels=NULL;
    }
    return;
}