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

📄 bidi.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}static void reverseRuns(int start, int end){    if (start >= end)        return;    assert(start >= 0 && end < sBidiRunCount);    // Get the item before the start of the runs to reverse and put it in    // |beforeStart|.  |curr| should point to the first run to reverse.    BidiRun* curr = sFirstBidiRun;    BidiRun* beforeStart = 0;    int i = 0;    while (i < start) {        i++;        beforeStart = curr;        curr = curr->nextRun;    }    BidiRun* startRun = curr;    while (i < end) {        i++;        curr = curr->nextRun;    }    BidiRun* endRun = curr;    BidiRun* afterEnd = curr->nextRun;    i = start;    curr = startRun;    BidiRun* newNext = afterEnd;    while (i <= end) {        // Do the reversal.        BidiRun* next = curr->nextRun;        curr->nextRun = newNext;        newNext = curr;        curr = next;        i++;    }    // Now hook up beforeStart and afterEnd to the newStart and newEnd.    if (beforeStart)        beforeStart->nextRun = endRun;    else        sFirstBidiRun = endRun;    startRun->nextRun = afterEnd;    if (!afterEnd)        sLastBidiRun = startRun;}static void chopMidpointsAt(RenderObject* obj, uint pos){    if (!sNumMidpoints) return;    BidiIterator* midpoints = smidpoints->data();    for (uint i = 0; i < sNumMidpoints; i++) {        const BidiIterator& point = midpoints[i];        if (point.obj == obj && point.pos == pos) {            sNumMidpoints = i;            break;        }    }}static void checkMidpoints(BidiIterator& lBreak, BidiState &bidi){    // Check to see if our last midpoint is a start point beyond the line break.  If so,    // shave it off the list, and shave off a trailing space if the previous end point isn't    // white-space: pre.    if (lBreak.obj && sNumMidpoints && sNumMidpoints%2 == 0) {        BidiIterator* midpoints = smidpoints->data();        BidiIterator& endpoint = midpoints[sNumMidpoints-2];        const BidiIterator& startpoint = midpoints[sNumMidpoints-1];        BidiIterator currpoint = endpoint;        while (!currpoint.atEnd() && currpoint != startpoint && currpoint != lBreak)            currpoint.increment( bidi );        if (currpoint == lBreak) {            // We hit the line break before the start point.  Shave off the start point.            sNumMidpoints--;            if (!endpoint.obj->style()->preserveWS()) {                if (endpoint.obj->isText()) {                    // Don't shave a character off the endpoint if it was from a soft hyphen.                    RenderText* textObj = static_cast<RenderText*>(endpoint.obj);                    if (endpoint.pos+1 < textObj->length() &&                        textObj->text()[endpoint.pos+1].unicode() == SOFT_HYPHEN)                        return;                }                endpoint.pos--;            }        }    }}static void addMidpoint(const BidiIterator& midpoint){    if (!smidpoints)        return;    if (smidpoints->size() <= sNumMidpoints)        smidpoints->resize(sNumMidpoints+10);    BidiIterator* midpoints = smidpoints->data();    midpoints[sNumMidpoints++] = midpoint;}static void appendRunsForObject(int start, int end, RenderObject* obj, BidiState &bidi){    if (start > end || obj->isFloating() ||        (obj->isPositioned() && !obj->hasStaticX() && !obj->hasStaticY()))        return;    bool haveNextMidpoint = (smidpoints && sCurrMidpoint < sNumMidpoints);    BidiIterator nextMidpoint;    if (haveNextMidpoint)        nextMidpoint = smidpoints->at(sCurrMidpoint);    if (betweenMidpoints) {        if (!(haveNextMidpoint && nextMidpoint.obj == obj))            return;        // This is a new start point. Stop ignoring objects and        // adjust our start.        betweenMidpoints = false;        start = nextMidpoint.pos;        sCurrMidpoint++;        if (start < end)            return appendRunsForObject(start, end, obj, bidi);    }    else {        if (!smidpoints || !haveNextMidpoint || (obj != nextMidpoint.obj)) {            addRun(new (obj->renderArena()) BidiRun(start, end, obj, bidi.context, dir));            return;        }        // An end midpoint has been encountered within our object.  We        // need to go ahead and append a run with our endpoint.        if (int(nextMidpoint.pos+1) <= end) {            betweenMidpoints = true;            sCurrMidpoint++;            if (nextMidpoint.pos != UINT_MAX) { // UINT_MAX means stop at the object and don't include any of it.                addRun(new (obj->renderArena())                    BidiRun(start, nextMidpoint.pos+1, obj, bidi.context, dir));                return appendRunsForObject(nextMidpoint.pos+1, end, obj, bidi);            }        }        else           addRun(new (obj->renderArena()) BidiRun(start, end, obj, bidi.context, dir));    }}static void appendRun( BidiState &bidi ){    if ( emptyRun ) return;#if BIDI_DEBUG > 1    kdDebug(6041) << "appendRun: dir="<<(int)dir<<endl;#endif    bool b = adjustEmbedding;    adjustEmbedding = false;    int start = bidi.sor.pos;    RenderObject *obj = bidi.sor.obj;    while( obj && obj != bidi.eor.obj ) {        appendRunsForObject(start, obj->length(), obj, bidi);        start = 0;        obj = Bidinext( bidi.sor.par, obj, bidi );    }    if (obj)        appendRunsForObject(start, bidi.eor.pos+1, obj, bidi);    bidi.eor.increment( bidi );    bidi.sor = bidi.eor;    dir = QChar::DirON;    bidi.status.eor = QChar::DirON;    adjustEmbedding = b;}static void embed( QChar::Direction d, BidiState &bidi ){#if BIDI_DEBUG > 1    qDebug("*** embed dir=%d emptyrun=%d", d, emptyRun );#endif    bool b = adjustEmbedding ;    adjustEmbedding = false;    if ( d == QChar::DirPDF ) {	BidiContext *c = bidi.context->parent;	if (c) {	    if ( bidi.eor != bidi.last ) {		appendRun( bidi );		bidi.eor = bidi.last;	    }	    appendRun( bidi );	    emptyRun = true;	    bidi.status.last = bidi.context->dir;	    bidi.context->deref();	    bidi.context = c;	    if(bidi.context->override)		dir = bidi.context->dir;	    else		dir = QChar::DirON;	    bidi.status.lastStrong = bidi.context->dir;	}    } else {	QChar::Direction runDir;	if( d == QChar::DirRLE || d == QChar::DirRLO )	    runDir = QChar::DirR;	else	    runDir = QChar::DirL;	bool override;	if( d == QChar::DirLRO || d == QChar::DirRLO )	    override = true;	else	    override = false;	unsigned char level = bidi.context->level;	if ( runDir == QChar::DirR ) {	    if(level%2) // we have an odd level		level += 2;	    else		level++;	} else {	    if(level%2) // we have an odd level		level++;	    else		level += 2;	}	if(level < 61) {	    if ( bidi.eor != bidi.last ) {                appendRun( bidi );                bidi.eor = bidi.last;            }            appendRun( bidi );            emptyRun = true;	    bidi.context = new BidiContext(level, runDir, bidi.context, override);	    bidi.context->ref();	    dir = runDir;	    bidi.status.last = runDir;	    bidi.status.lastStrong = runDir;	    bidi.status.eor = runDir;	}    }    adjustEmbedding = b;}InlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj){    // See if we have an unconstructed line box for this object that is also    // the last item on the line.    KHTMLAssert(obj->isInlineFlow() || obj == this);    RenderFlow* flow = static_cast<RenderFlow*>(obj);    // Get the last box we made for this render object.    InlineFlowBox* box = flow->lastLineBox();    // If this box is constructed then it is from a previous line, and we need    // to make a new box for our line.  If this box is unconstructed but it has    // something following it on the line, then we know we have to make a new box    // as well.  In this situation our inline has actually been split in two on    // the same line (this can happen with very fancy language mixtures).    if (!box || box->isConstructed() || box->nextOnLine()) {        // We need to make a new box for this render object.  Once        // made, we need to place it at the end of the current line.        InlineBox* newBox = obj->createInlineBox(false, obj == this);        KHTMLAssert(newBox->isInlineFlowBox());        box = static_cast<InlineFlowBox*>(newBox);        box->setFirstLineStyleBit(m_firstLine);        // We have a new box. Append it to the inline box we get by constructing our        // parent.  If we have hit the block itself, then |box| represents the root        // inline box for the line, and it doesn't have to be appended to any parent        // inline.        if (obj != this) {            InlineFlowBox* parentBox = createLineBoxes(obj->parent());            parentBox->addToLine(box);        }    }    return box;}InlineFlowBox* RenderBlock::constructLine(const BidiIterator &start, const BidiIterator &end){    if (!sFirstBidiRun)        return 0; // We had no runs. Don't make a root inline box at all. The line is empty.    InlineFlowBox* parentBox = 0;    for (BidiRun* r = sFirstBidiRun; r; r = r->nextRun) {        // Create a box for our object.        r->box = r->obj->createInlineBox(r->obj->isPositioned(), false);        // If we have no parent box yet, or if the run is not simply a sibling,        // then we need to construct inline boxes as necessary to properly enclose the        // run's inline box.        if (!parentBox || (parentBox->object() != r->obj->parent()))            // Create new inline boxes all the way back to the appropriate insertion point.            parentBox = createLineBoxes(r->obj->parent());        // Append the inline box to this line.        parentBox->addToLine(r->box);    }    // We should have a root inline box.  It should be unconstructed and    // be the last continuation of our line list.    KHTMLAssert(lastLineBox() && !lastLineBox()->isConstructed());    // Set bits on our inline flow boxes that indicate which sides should    // paint borders/margins/padding.  This knowledge will ultimately be used when    // we determine the horizontal positions and widths of all the inline boxes on    // the line.    RenderObject* endObject = 0;    bool lastLine = !end.obj;    if (end.obj && end.pos == 0)        endObject = end.obj;    lastLineBox()->determineSpacingForFlowBoxes(lastLine, endObject);    // Now mark the line boxes as being constructed.    lastLineBox()->setConstructed();    // Return the last line.    return lastLineBox();}void RenderBlock::computeHorizontalPositionsForLine(InlineFlowBox* lineBox, BidiState &bidi){    // First determine our total width.    int totWidth = lineBox->getFlowSpacingWidth();    BidiRun* r = 0;    for (r = sFirstBidiRun; r; r = r->nextRun) {        if (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())            r->box->setWidth(static_cast<RenderText *>(r->obj)->width(r->start, r->stop-r->start, m_firstLine));        else if (!r->obj->isInlineFlow()) {            r->obj->calcWidth();            r->box->setWidth(r->obj->width());            totWidth += r->obj->marginLeft() + r->obj->marginRight();        }        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);    int availableWidth = lineWidth(m_height);    switch(style()->textAlign()) {        case LEFT:        case KHTML_LEFT:            numSpaces = 0;            break;        case JUSTIFY:            if (numSpaces != 0 && !bidi.current.atEnd() && !bidi.current.obj->isBR() )                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:            x += availableWidth - totWidth;            numSpaces = 0;            break;        case CENTER:        case KHTML_CENTER:            int xd = (availableWidth - totWidth)/2;            x += xd >0 ? xd : 0;            numSpaces = 0;

⌨️ 快捷键说明

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