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

📄 bidi.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    BidiRun* r = 0;
    for (r = sFirstBidiRun; r; r = r->nextRun) {
        if (!r->box || r->obj->isPositioned())
            continue; // Positioned objects are only participating to figure out their
                      // correct static x position.  They have no effect on the width.
        if (r->obj->isText()) {
            int textWidth = static_cast<RenderText *>(r->obj)->width(r->start, r->stop-r->start, m_firstLine);
            if (!r->compact) {
                RenderStyle *style = r->obj->style();
                if (style->whiteSpace() == NORMAL && style->khtmlLineBreak() == AFTER_WHITE_SPACE) {
                    // shrink the box as needed to keep the line from overflowing the available width
                    textWidth = kMin(textWidth, availableWidth - totWidth + style->borderLeftWidth());
                }
            }
            r->box->setWidth(textWidth);
        }
        else if (!r->obj->isInlineFlow()) {
            r->obj->calcWidth();
            r->box->setWidth(r->obj->width());
            if (!r->compact)
                totWidth += r->obj->marginLeft() + r->obj->marginRight();
        }

        // Compacts don't contribute to the width of the line, since they are placed in the margin.
        if (!r->compact)
            totWidth += r->box->width();
    }

    // Armed with the total width of the line (without justification),
    // we now examine our text-align property in order to determine where to position the
    // objects horizontally.  The total width of the line can be increased if we end up
    // justifying text.
    int x = leftOffset(m_height);
    switch(style()->textAlign()) {
        case LEFT:
        case KHTML_LEFT:
            // The direction of the block should determine what happens with wide lines.  In
            // particular with RTL blocks, wide lines should still spill out to the left.
            if (style()->direction() == RTL && totWidth > availableWidth)
                x -= (totWidth - availableWidth);
            numSpaces = 0;
            break;
        case JUSTIFY:
            if (numSpaces != 0 && !bidi.current.atEnd() && !lineBox->endsWithBreak())
                break;
            // fall through
        case TAAUTO:
            numSpaces = 0;
            // for right to left fall through to right aligned
            if (bidi.context->basicDir == QChar::DirL)
                break;
        case RIGHT:
        case KHTML_RIGHT:
            // Wide lines spill out of the block based off direction.
            // So even if text-align is right, if direction is LTR, wide lines should overflow out of the right
            // side of the block.
            if (style()->direction() == RTL || totWidth < availableWidth)
                x += availableWidth - totWidth;
            numSpaces = 0;
            break;
        case CENTER:
        case KHTML_CENTER:
            int xd = (availableWidth - totWidth)/2;
            x += xd >0 ? xd : 0;
            numSpaces = 0;
            break;
    }

    if (numSpaces > 0) {
        for (r = sFirstBidiRun; r; r = r->nextRun) {
            if (!r->box) continue;

            int spaceAdd = 0;
            if (numSpaces > 0 && r->obj->isText() && !r->compact) {
                // get the number of spaces in the run
                int spaces = 0;
                for ( int i = r->start; i < r->stop; i++ ) {
                    const QChar c = static_cast<RenderText *>(r->obj)->text()[i];
                    if (c == ' ' || c == '\n')
                        spaces++;
                }

                KHTMLAssert(spaces <= numSpaces);

                // Only justify text with white-space: normal.
                if (r->obj->style()->whiteSpace() != PRE) {

#if NOKIA_CHANGES
                    RenderCanvas* c = canvas();
                    if(c) {
                       if(c->view()) {
                           int bidiWidth = c->view()->maxBidiWidth();
                           bidiWidth = QMAX(bidiWidth - leftOffset(m_height),0);
                           availableWidth = QMIN(availableWidth,bidiWidth);
                       }
                    }
#endif
                    spaceAdd = (availableWidth - totWidth)*spaces/numSpaces;
                    static_cast<InlineTextBox*>(r->box)->setSpaceAdd(spaceAdd);
                    totWidth += spaceAdd;
                }
                numSpaces -= spaces;
            }
        }
    }

    // The widths of all runs are now known.  We can now place every inline box (and
    // compute accurate widths for the inline flow boxes).
    int leftPosition = x;
    int rightPosition = x;
    lineBox->placeBoxesHorizontally(x, leftPosition, rightPosition);
    lineBox->setHorizontalOverflowPositions(leftPosition, rightPosition);
}

void RenderBlock::computeVerticalPositionsForLine(RootInlineBox* lineBox)
{
    lineBox->verticallyAlignBoxes(m_height);
    lineBox->setBlockHeight(m_height);

    // See if the line spilled out.  If so set overflow height accordingly.
    int bottomOfLine = lineBox->bottomOverflow();
    if (bottomOfLine > m_height && bottomOfLine > m_overflowHeight)
        m_overflowHeight = bottomOfLine;

    // Now make sure we place replaced render objects correctly.
    for (BidiRun* r = sFirstBidiRun; r; r = r->nextRun) {
        if (!r->box) continue; // Skip runs with no line boxes.

        // Align positioned boxes with the top of the line box.  This is
        // a reasonable approximation of an appropriate y position.
        if (r->obj->isPositioned())
            r->box->setYPos(m_height);

        // Position is used to properly position both replaced elements and
        // to update the static normal flow x/y of positioned elements.
        r->obj->position(r->box, r->start, r->stop - r->start, r->level%2);
    }
}

// collects one line of the paragraph and transforms it to visual order
void RenderBlock::bidiReorderLine(const BidiIterator &start, const BidiIterator &end, BidiState &bidi)
{
    if ( start == end ) {
        if ( start.current() == '\n' ) {
            m_height += lineHeight( m_firstLine, true );
        }
        return;
    }

#if BIDI_DEBUG > 1
    kdDebug(6041) << "reordering Line from " << start.obj << "/" << start.pos << " to " << end.obj << "/" << end.pos << endl;
#endif

    sFirstBidiRun = 0;
    sLastBidiRun = 0;
    sBidiRunCount = 0;

    //    context->ref();

    dir = QChar::DirON;

    // Adopt the directionality of the text's element if specified as RTL
    // and the first position is neutral.
    if (start.direction() == QChar::DirON) {
        if (start.obj) {
            if (start.obj->style()->direction() == RTL)
                dir = QChar::DirR;
        }
        else if (style()->direction() == RTL) {
            dir = QChar::DirR;
        }
    }

    emptyRun = true;

    numSpaces = 0;

    bidi.current = start;
    bidi.last = bidi.current;
    bool atEnd = false;

    while( 1 ) {

        QChar::Direction dirCurrent;
        if (atEnd) {
            //kdDebug(6041) << "atEnd" << endl;
            BidiContext *c = bidi.context;
            if ( bidi.current.atEnd())
                while ( c->parent )
                    c = c->parent;
            dirCurrent = c->dir;
        } else {
            dirCurrent = bidi.current.direction();
        }

#ifndef QT_NO_UNICODETABLES

#if BIDI_DEBUG > 1
        kdDebug(6041) << "directions: dir=" << (int)dir << " current=" << (int)dirCurrent << " last=" << status.last << " eor=" << status.eor << " lastStrong=" << status.lastStrong << " embedding=" << (int)context->dir << " level =" << (int)context->level << endl;
#endif

        switch(dirCurrent) {

            // embedding and overrides (X1-X9 in the Bidi specs)
        case QChar::DirRLE:
        case QChar::DirLRE:
        case QChar::DirRLO:
        case QChar::DirLRO:
        case QChar::DirPDF:
            bidi.eor = bidi.last;
            embed( dirCurrent, bidi );
            break;

            // strong types
        case QChar::DirL:
            if(dir == QChar::DirON)
                dir = QChar::DirL;
            switch(bidi.status.last)
                {
                case QChar::DirL:
                    bidi.eor = bidi.current; bidi.status.eor = QChar::DirL; break;
                case QChar::DirR:
                case QChar::DirAL:
                case QChar::DirEN:
                case QChar::DirAN:
                    appendRun( bidi );
                    break;
                case QChar::DirES:
                case QChar::DirET:
                case QChar::DirCS:
                case QChar::DirBN:
                case QChar::DirB:
                case QChar::DirS:
                case QChar::DirWS:
                case QChar::DirON:
                    if(dir != QChar::DirL) {
                        //last stuff takes embedding dir
                        if( bidi.context->dir == QChar::DirR ) {
                            if(!(bidi.status.eor == QChar::DirR)) {
                                // AN or EN
                                appendRun( bidi );
                                dir = QChar::DirR;
                            }
                            else
                                bidi.eor = bidi.last;
                            appendRun( bidi );
                            dir = QChar::DirL;
                            bidi.status.eor = QChar::DirL;
                        } else {
                            if(bidi.status.eor == QChar::DirR) {
                                appendRun( bidi );
                                dir = QChar::DirL;
                            } else {
                                bidi.eor = bidi.current; bidi.status.eor = QChar::DirL; break;
                            }
                        }
                    } else {
                        bidi.eor = bidi.current; bidi.status.eor = QChar::DirL;
                    }
                default:
                    break;
                }
            bidi.status.lastStrong = QChar::DirL;
            break;
        case QChar::DirAL:
        case QChar::DirR:
            if(dir == QChar::DirON) dir = QChar::DirR;
            switch(bidi.status.last)
                {
                case QChar::DirR:
                case QChar::DirAL:
                    bidi.eor = bidi.current; bidi.status.eor = QChar::DirR; break;
                case QChar::DirL:
                case QChar::DirEN:
                case QChar::DirAN:
                    appendRun( bidi );
		    dir = QChar::DirR;
		    bidi.eor = bidi.current;
		    bidi.status.eor = QChar::DirR;
                    break;
                case QChar::DirES:
                case QChar::DirET:
                case QChar::DirCS:
                case QChar::DirBN:
                case QChar::DirB:
                case QChar::DirS:
                case QChar::DirWS:
                case QChar::DirON:
                    if( !(bidi.status.eor == QChar::DirR) && !(bidi.status.eor == QChar::DirAL) ) {
                        //last stuff takes embedding dir
                        if(bidi.context->dir == QChar::DirR || bidi.status.lastStrong == QChar::DirR) {
                            appendRun( bidi );
                            dir = QChar::DirR;
                            bidi.eor = bidi.current;
			    bidi.status.eor = QChar::DirR;
                        } else {
                            bidi.eor = bidi.last;
                            appendRun( bidi );
                            dir = QChar::DirR;
			    bidi.status.eor = QChar::DirR;
                        }
                    } else {
                        bidi.eor = bidi.current; bidi.status.eor = QChar::DirR;
                    }
                default:
                    break;
                }
            bidi.status.lastStrong = dirCurrent;
            break;

            // weak types:

        case QChar::DirNSM:
            // ### if @sor, set dir to dirSor
            break;
        case QChar::DirEN:
            if(!(bidi.status.lastStrong == QChar::DirAL)) {
                // if last strong was AL change EN to AN
                if(dir == QChar::DirON) {
                    if(bidi.status.lastStrong == QChar::DirAL)
                        dir = QChar::DirAN;
                    else
                        dir = QChar::DirL;
                }
                switch(bidi.status.last)
                    {
                    case QChar::DirET:
			if ( bidi.status.lastStrong == QChar::DirR || bidi.status.lastStrong == QChar::DirAL ) {
			    appendRun( bidi );
                            dir = QChar::DirEN;
                            bidi.status.eor = QChar::DirEN;
			}
			// fall through
                    case QChar::DirEN:
                    case QChar::DirL:
                        bidi.eor = bidi.current;
                        bidi.status.eor = dirCurrent;
                        break;
                    case QChar::DirR:
                    case QChar::DirAL:
                    case QChar::DirAN:
                        appendRun( bidi );
			bidi.status.eor = QChar::DirEN;
                        dir = QChar::DirEN; break;
                    case QChar::DirES:
                    case QChar::DirCS:
                        if(bidi.status.eor == QChar::DirEN) {
                            bidi.eor = bidi.current; break;
                        }
                    case QChar::DirBN:
                    case QChar::DirB:
                    case QChar::DirS:
                    case QChar::DirWS:
                    case QChar::DirON:
                        if(bidi.status.eor == QChar::DirR) {
                            // neutrals go to R
                            bidi.eor = bidi.last;
                            appendRun( bidi );
                            dir = QChar::DirEN;
                            bidi.status.eor = QChar::DirEN;
                        }

⌨️ 快捷键说明

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