⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bidi.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        case QChar::DirCS:            break;        case QChar::DirET:            if(bidi.status.last == QChar::DirEN) {                dirCurrent = QChar::DirEN;                bidi.eor = bidi.current; bidi.status.eor = dirCurrent;                break;            }            break;        // boundary neutrals should be ignored        case QChar::DirBN:            break;            // neutrals        case QChar::DirB:            // ### what do we do with newline and paragraph seperators that come to here?            break;        case QChar::DirS:            // ### implement rule L1            break;        case QChar::DirWS:            break;        case QChar::DirON:            break;        default:            break;        }        //cout << "     after: dir=" << //        dir << " current=" << dirCurrent << " last=" << status.last << " eor=" << status.eor << " lastStrong=" << status.lastStrong << " embedding=" << context->dir << endl;        if(bidi.current.atEnd()) break;        // set status.last as needed.        switch(dirCurrent)            {            case QChar::DirET:            case QChar::DirES:            case QChar::DirCS:            case QChar::DirS:            case QChar::DirWS:            case QChar::DirON:                switch(bidi.status.last)                    {                    case QChar::DirL:                    case QChar::DirR:                    case QChar::DirAL:                    case QChar::DirEN:                    case QChar::DirAN:                        bidi.status.last = dirCurrent;                        break;                    default:                        bidi.status.last = QChar::DirON;                    }                break;            case QChar::DirNSM:            case QChar::DirBN:                // ignore these                break;            case QChar::DirEN:                if ( bidi.status.last == QChar::DirL ) {                    bidi.status.last = QChar::DirL;                    break;                }                // fall through            default:                bidi.status.last = dirCurrent;            }#endif	if ( atEnd ) break;        bidi.last = bidi.current;	if ( emptyRun ) {	    bidi.sor = bidi.current;	    bidi.eor = bidi.current;	    emptyRun = false;	}	// this causes the operator ++ to open and close embedding levels as needed	// for the CSS unicode-bidi property	adjustEmbedding = true;        bidi.current.increment( bidi );	adjustEmbedding = false;	if ( bidi.current == end ) {	    if ( emptyRun )		break;	    atEnd = true;	}    }#if BIDI_DEBUG > 0    kdDebug(6041) << "reached end of line current=" << current.obj << "/" << current.pos		  << ", eor=" << eor.obj << "/" << eor.pos << endl;#endif    if ( !emptyRun && bidi.sor != bidi.current ) {	    bidi.eor = bidi.last;	    appendRun( bidi );    }    // reorder line according to run structure...    // first find highest and lowest levels    uchar levelLow = 128;    uchar levelHigh = 0;    BidiRun *r = sFirstBidiRun;    while ( r ) {        if ( r->level > levelHigh )            levelHigh = r->level;        if ( r->level < levelLow )            levelLow = r->level;        r = r->nextRun;    }    // implements reordering of the line (L2 according to Bidi spec):    // L2. From the highest level found in the text to the lowest odd level on each line,    // reverse any contiguous sequence of characters that are at that level or higher.    // reversing is only done up to the lowest odd level    if( !(levelLow%2) ) levelLow++;#if BIDI_DEBUG > 0    kdDebug(6041) << "lineLow = " << (uint)levelLow << ", lineHigh = " << (uint)levelHigh << endl;    kdDebug(6041) << "logical order is:" << endl;    QPtrListIterator<BidiRun> it2(runs);    BidiRun *r2;    for ( ; (r2 = it2.current()); ++it2 )        kdDebug(6041) << "    " << r2 << "  start=" << r2->start << "  stop=" << r2->stop << "  level=" << (uint)r2->level << endl;#endif    int count = sBidiRunCount - 1;    // do not reverse for visually ordered web sites    if(!style()->visuallyOrdered()) {        while(levelHigh >= levelLow) {            int i = 0;            BidiRun* currRun = sFirstBidiRun;            while ( i < count ) {                while(i < count && currRun && currRun->level < levelHigh) {                    i++;                    currRun = currRun->nextRun;                }                int start = i;                while(i <= count && currRun && currRun->level >= levelHigh) {                    i++;                    currRun = currRun->nextRun;                }                int end = i-1;                reverseRuns(start, end);                i++;                if(i >= count) break;            }            levelHigh--;        }    }#if BIDI_DEBUG > 0    kdDebug(6041) << "visual order is:" << endl;    for (BidiRun* curr = sFirstRun; curr; curr = curr->nextRun)        kdDebug(6041) << "    " << curr << endl;#endif}static void buildCompactRuns(RenderObject* compactObj, BidiState &bidi){    sBuildingCompactRuns = true;    if (!compactObj->isRenderBlock()) {        // Just append a run for our object.        isLineEmpty = false;        addRun(new (compactObj->renderArena()) BidiRun(0, compactObj->length(), compactObj, bidi.context, dir));    }    else {        // Format the compact like it is its own single line.  We build up all the runs for        // the little compact and then reorder them for bidi.        RenderBlock* compactBlock = static_cast<RenderBlock*>(compactObj);        adjustEmbedding = true;        BidiIterator start(compactBlock, first(compactBlock, bidi), 0);        adjustEmbedding = false;        BidiIterator end = start;            betweenMidpoints = false;        isLineEmpty = true;        previousLineBrokeCleanly = true;                end = compactBlock->findNextLineBreak(start, bidi);        if (!isLineEmpty)            compactBlock->bidiReorderLine(start, end, bidi);    }            sCompactFirstBidiRun = sFirstBidiRun;    sCompactLastBidiRun = sLastBidiRun;    sCompactBidiRunCount = sBidiRunCount;        sNumMidpoints = 0;    sCurrMidpoint = 0;    betweenMidpoints = false;    sBuildingCompactRuns = false;}QRect RenderBlock::layoutInlineChildren(bool relayoutChildren){    BidiState bidi;    bool useRepaintRect = false;    QRect repaintRect(0,0,0,0);    m_overflowHeight = 0;        invalidateVerticalPositions();#ifdef DEBUG_LAYOUT    QTime qt;    qt.start();    kdDebug( 6040 ) << renderName() << " layoutInlineChildren( " << this <<" )" << endl;#endif#if BIDI_DEBUG > 1 || defined( DEBUG_LINEBREAKS )    kdDebug(6041) << " ------- bidi start " << this << " -------" << endl;#endif        m_height = borderTop() + paddingTop();    int toAdd = borderBottom() + paddingBottom();    if (includeScrollbarSize())        toAdd += m_layer->horizontalScrollbarHeight();        // Figure out if we should clear out our line boxes.    // FIXME: Handle resize eventually!    // FIXME: Do something better when floats are present.    bool fullLayout = !firstLineBox() || !firstChild() || selfNeedsLayout() || relayoutChildren || containsFloats();    if (fullLayout)        deleteLineBoxes();            // Text truncation only kicks in if your overflow isn't visible and your text-overflow-mode isn't    // clip.    // FIXME: CSS3 says that descendants that are clipped must also know how to truncate.  This is insanely    // difficult to figure out (especially in the middle of doing layout), and is really an esoteric pile of nonsense    // anyway, so we won't worry about following the draft here.    bool hasTextOverflow = style()->textOverflow() && hasOverflowClip();        // Walk all the lines and delete our ellipsis line boxes if they exist.    if (hasTextOverflow)         deleteEllipsisLineBoxes();    if (firstChild()) {        // layout replaced elements        bool endOfInline = false;        RenderObject *o = first(this, bidi, false);        bool hasFloat = false;        while (o) {            if (o->isReplaced() || o->isFloating() || o->isPositioned()) {                if (relayoutChildren || o->style()->width().isPercent() || o->style()->height().isPercent())                    o->setChildNeedsLayout(true, false);                if (o->isPositioned())                    o->containingBlock()->insertPositionedObject(o);                else {                    if (o->isFloating())                        hasFloat = true;                    else if (fullLayout || o->needsLayout()) // Replaced elements                        o->dirtyLineBoxes(fullLayout);                    o->layoutIfNeeded();                }            }            else if (o->isText() || (o->isInlineFlow() && !endOfInline)) {                if (fullLayout || o->selfNeedsLayout())                    o->dirtyLineBoxes(fullLayout);                o->setNeedsLayout(false);            }            o = Bidinext( this, o, bidi, false, &endOfInline);        }        if (hasFloat)            fullLayout = true; // FIXME: Will need to find a way to optimize floats some day.                if (fullLayout && !selfNeedsLayout()) {            setNeedsLayout(true, false);  // Mark ourselves as needing a full layout. This way we'll repaint like                                          // we're supposed to.            if (!document()->view()->needsFullRepaint() && m_layer) {                // Because we waited until we were already inside layout to discover                // that the block really needed a full layout, we missed our chance to repaint the layer                // before layout started.  Luckily the layer has cached the repaint rect for its original                // position and size, and so we can use that to make a repaint happen now.                RenderCanvas* c = canvas();                if (c && !c->printingMode())                    c->repaintViewRectangle(m_layer->repaintRect());            }        }        BidiContext *startEmbed;        if( style()->direction() == LTR ) {            startEmbed = new BidiContext( 0, QChar::DirL );            bidi.status.eor = QChar::DirL;        } else {            startEmbed = new BidiContext( 1, QChar::DirR );            bidi.status.eor = QChar::DirR;        }        startEmbed->ref();	bidi.status.lastStrong = QChar::DirON;	bidi.status.last = QChar::DirON;        bidi.context = startEmbed;                if (!smidpoints)            smidpoints = new QMemArray<BidiIterator>;                sNumMidpoints = 0;        sCurrMidpoint = 0;        sCompactFirstBidiRun = sCompactLastBidiRun = 0;        sCompactBidiRunCount = 0;                // We want to skip ahead to the first dirty line        BidiIterator start;        RootInlineBox* startLine = determineStartPosition(fullLayout, start, bidi);                // We also find the first clean line and extract these lines.  We will add them back        // if we determine that we're able to synchronize after handling all our dirty lines.        BidiIterator cleanLineStart;        int endLineYPos;        RootInlineBox* endLine = (fullLayout || !startLine) ?                                  0 : determineEndPosition(startLine, cleanLineStart, endLineYPos);                if (startLine) {            useRepaintRect = true;            repaintRect.setY(m_height);            RenderArena* arena = renderArena();            RootInlineBox* box = startLine;            while (box) {                RootInlineBox* next = box->nextRootBox();                box->deleteLine(arena);                box = next;            }            startLine = 0;        }                BidiIterator end = start;        bool endLineMatched = false;        while (!end.atEnd()) {            start = end;            if (endLine && (endLineMatched = matchedEndLine(start, cleanLineStart, endLine, endLineYPos)))                break;            betweenMidpoints = false;            isLineEmpty = true;            if (m_firstLine && firstChild() && firstChild()->isCompact()) {                buildCompactRuns(firstChild(), bidi);                start.obj = firstChild()->nextSibling();                end = start;            }            end = findNextLineBreak(start, bidi);            if( start.atEnd() ) break;            if (!isLineEmpty) {                bidiReorderLine(start, end, bidi);                // Now that the runs have been ordered, we create the line boxes.                // At the same time we figure out where border/padding/margin should be applied for                // inline flow boxes.                if (sCompactFirstBidiRun) {                    // We have a compact line sharing this line.  Link the compact runs                    // to our runs to create a single line of runs.                    sCompactLastBidiRun->nextRun = sFirstBidiRun;                    sFirstBidiRun = sCompactFirstBidiRun;                    sBidiRunCount += sCompactBidiRunCount;                }                RootInlineBox* lineBox = 0;                if (sBidiRunCount) {                    lineBox = constructLine(start, end);                    if (lineBox) {                        lineBox->setEndsWithBreak(previousLineBrokeCleanly);                        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -