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

📄 render_flow.cpp

📁 monqueror一个很具有参考价值的源玛
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    if (!f) f = new SpecialObject;    f->type = SpecialObject::Positioned;    f->node = o;    f->count = specialObjects->count();    specialObjects->append(f);    setContainsPositioned(true);}voidRenderFlow::insertFloat(RenderObject *o){//    kdDebug( 6040 ) << renderName() << " " << this << "::insertFloat()" << endl;    // a floating element    if(!specialObjects) {        specialObjects = new QSortedList<SpecialObject>;        specialObjects->setAutoDelete(true);    }    // don't insert it twice!    QListIterator<SpecialObject> it(*specialObjects);    SpecialObject* f;    while ( (f = it.current()) ) {        if (f->node == o)        {            f->width = o->width() + o->marginLeft() + o->marginRight();            f->startY = -1;            f->endY = -1;            return;        }        ++it;    }    o->layout();    if(!f) f = new SpecialObject;    f->count = specialObjects->count();    f->startY = -1;    f->endY = -1;    f->width = o->width() + o->marginLeft() + o->marginRight();    if(o->style()->floating() == FLEFT)        f->type = SpecialObject::FloatLeft;    else        f->type = SpecialObject::FloatRight;    f->node = o;    specialObjects->append(f);//    kdDebug( 6040 ) << "inserting node " << o << " number of specialobject = " << //     specialObjects->count() << endl;}void RenderFlow::positionNewFloats(){    if(!specialObjects) return;    SpecialObject *f = specialObjects->getLast();    if(!f || f->startY != -1) return;    SpecialObject *lastFloat;    while(1)    {        lastFloat = specialObjects->prev();        if(!lastFloat || (lastFloat->startY != -1 && lastFloat->type!=SpecialObject::Positioned)) {            specialObjects->next();            break;        }        f = lastFloat;    }    int y = m_height;    // the float can not start above the y position of the last positioned float.    if(lastFloat && lastFloat->startY > y)        y = lastFloat->startY;    while(f)    {        //skip elements copied from elsewhere and positioned elements        if (f->node->containingBlock()!=this || f->type==SpecialObject::Positioned)        {            f = specialObjects->next();            continue;        }                        RenderObject *o = f->node;		//kdDebug() << "In function: RenderFlow::positionNewFloats" << endl;		//kdDebug() << "child name is " << o->renderName() << endl;        int _height = o->height() + o->marginTop() + o->marginBottom();        if (o->style()->floating() == FLEFT)        {            int fx = leftOffset(y);            if (contentWidth() >= f->width)            {                while (rightOffset(y)-fx < f->width)                {                    y++;                    fx = leftOffset(y);                }            }            f->left = fx;          	//kdDebug() << "positioning left aligned float at (" << fx + o->marginLeft()  << "/" << y + o->marginTop() << ")" << endl;        	o->setXPos(fx + o->marginLeft());        	o->setYPos(y + o->marginTop());        }        else        {            int fx = rightOffset(y);            if (contentWidth() >= f->width)            {                while (fx - leftOffset(y) < f->width)                {                    y++;                    fx = rightOffset(y);                }            }            f->left = fx - f->width;	        //kdDebug() << "positioning right aligned float at (" << fx - o->marginRight() - o->width() << "/" << y + o->marginTop() << ")" << endl;            o->setXPos(fx - o->marginRight() - o->width());            o->setYPos(y + o->marginTop());        }        f->startY = y;        f->endY = f->startY + _height;        // Copy float to the containing block        // In case of anonymous box, copy to containing block _and_ it's containing block,        // so the creation of anonymous box does not prevent elements dom parent        // of getting the float.        //        // The whole thing is a hack to support html behaviour, where certain block        // elements (tables, lists) flow around floats as if they were inlines.        // Khtml float layouting is modeled after css2, and implementing this has        // been somewhat messy        //        if(style()->htmlHacks() && childrenInline() && !style()->flowAroundFloats())        {            RenderObject* obj = this;            for (int n = 0 ; n < (isAnonymousBox()?2:1); n++ )            {                obj = obj->containingBlock();                if (obj && obj->isFlow() )                {                    RenderFlow* par = static_cast<RenderFlow*>(obj);                    if (par->isFloating())                        break;                    else                    {                        if(!par->specialObjects) {                            par->specialObjects = new QSortedList<SpecialObject>;                            par->specialObjects->setAutoDelete(true);                        }                        QListIterator<SpecialObject> it(*par->specialObjects);                        SpecialObject* tt;                        while ( (tt = it.current()) ) {                            if (tt->node == o) break;                            ++it;                        }                        if (!tt || tt->node==o)                        {                            SpecialObject* so = new SpecialObject(*f);                            so->count = specialObjects->count();                            so->startY += m_y;                            so->endY += m_y;                            par->specialObjects->append(so);                        }                    }                }            }        }//      kdDebug( 6040 ) << "specialObject y= (" << f->startY << "-" << f->endY << ")" << endl;        f = specialObjects->next();    }}void RenderFlow::newLine(){    positionNewFloats();    // set y position    int newY = 0;    switch(m_clearStatus)    {    case CLEFT:        newY = leftBottom();        break;    case CRIGHT:        newY = rightBottom();        break;    case CBOTH:        newY = floatBottom();    default:        break;    }    if(m_height < newY)    {//      kdDebug( 6040 ) << "adjusting y position" << endl;        m_height = newY;    }    m_clearStatus = CNONE;}shortRenderFlow::leftOffset(int y) const{    int left = 0;    if ( firstLine && m_style->direction() == LTR ) {        int cw=0;        if (style()->width().isPercent())            cw = containingBlock()->contentWidth();        left += m_style->textIndent().minWidth(cw);    }    if(m_style->hasBorder())        left = borderLeft();    if(m_style->hasPadding())        left += paddingLeft();    if(!specialObjects) return left;    SpecialObject* r;    QListIterator<SpecialObject> it(*specialObjects);    for ( ; (r = it.current()); ++it )    {//      kdDebug( 6040 ) << "left: sy, ey, x, w " << r->startY << "," << r->endY << "," << r->left << "," << r->width << " " << endl;        if (r->startY <= y && r->endY > y &&            r->type == SpecialObject::FloatLeft &&            r->left + r->width > left)            left = r->left + r->width;    }//    kdDebug( 6040 ) << "leftOffset(" << y << ") = " << left << endl;    return left;}intRenderFlow::rightOffset(int y) const{    int right = m_width;    if ( firstLine && m_style->direction() == RTL ) {        int cw=0;        if (style()->width().isPercent())            cw = containingBlock()->contentWidth();        right += m_style->textIndent().minWidth(cw);    }    if(m_style->hasBorder())        right -= borderRight();    if(m_style->hasPadding())        right -= paddingRight();    if (!specialObjects) return right;    SpecialObject* r;    QListIterator<SpecialObject> it(*specialObjects);    for ( ; (r = it.current()); ++it )    {//      kdDebug( 6040 ) << "right: sy, ey, x, w " << //     r->startY << "," << r->endY << "," << r->left << "," << r->width << " " << endl;        if (r->startY <= y && r->endY > y &&            r->type == SpecialObject::FloatRight &&            r->left < right)            right = r->left;    }//    kdDebug( 6040 ) << "rightOffset(" << y << ") = " << right << endl;    return right;}unsigned shortRenderFlow::lineWidth(int y) const{//    kdDebug( 6040 ) << "lineWidth(" << y << ")=" << rightOffset(y) - leftOffset(y) << endl;    return rightOffset(y) - leftOffset(y);}intRenderFlow::floatBottom() const{    if (!specialObjects) return 0;    int bottom=0;    SpecialObject* r;    QListIterator<SpecialObject> it(*specialObjects);    for ( ; (r = it.current()); ++it )        if (r->endY>bottom && r->type <= SpecialObject::FloatRight)            bottom=r->endY;    return bottom;}intRenderFlow::lowestPosition() const{    int bottom = m_height + marginBottom();    int lp = 0;    if ( !m_childrenInline ) {        RenderObject *last = lastChild();        while( last && (last->isPositioned() || last->isFloating()) )            last = last->previousSibling();        if( last )            lp = yPos() + last->lowestPosition();    }    if(  lp > bottom )        bottom = lp;    //kdDebug(0) << renderName() << " bottom = " << bottom << endl;    if (specialObjects) {        SpecialObject* r;        QListIterator<SpecialObject> it(*specialObjects);        for ( ; (r = it.current()); ++it ) {            lp = 0;            if ( r->type < SpecialObject::Positioned ) {                lp = r->startY + r->node->lowestPosition();                //kdDebug(0) << r->node->renderName() << " lp = " << lp << "startY=" << r->startY << endl;            } else if ( r->type <= SpecialObject::Positioned ) {                lp = r->node->yPos() + r->node->lowestPosition();            }            if( lp > bottom)                bottom = lp;        }    }    //kdDebug(0) << renderName() << " bottom = " << bottom << endl;    return bottom;}intRenderFlow::leftBottom(){    if (!specialObjects) return 0;    int bottom=0;    SpecialObject* r;    QListIterator<SpecialObject> it(*specialObjects);    for ( ; (r = it.current()); ++it )        if (r->endY>bottom && r->type == SpecialObject::FloatLeft)            bottom=r->endY;    return bottom;}intRenderFlow::rightBottom(){    if (!specialObjects) return 0;    int bottom=0;    SpecialObject* r;    QListIterator<SpecialObject> it(*specialObjects);    for ( ; (r = it.current()); ++it )        if (r->endY>bottom && r->type == SpecialObject::FloatRight)            bottom=r->endY;    return bottom;}voidRenderFlow::clearFloats(){//    kdDebug( 6040 ) << "clearFloats" << endl;         if (specialObjects) {	if( containsPositioned() ) {            specialObjects->first();                        while ( specialObjects->current()) {		if ( specialObjects->current()->type != SpecialObject::Positioned ) 		    specialObjects->remove();                else		    specialObjects->next();	    }		} else	    specialObjects->clear();    }    if (isFloating()) return;    RenderObject *prev = m_previous;    // find the element to copy the floats from    // pass non-flows    // pass fAF's unless they contain overhanging stuff    while (prev && (!prev->isFlow() ||        (prev->style()->flowAroundFloats() &&            (static_cast<RenderFlow *>(prev)->floatBottom()+prev->yPos() < m_y ))))            prev = prev->previousSibling();    int offset = m_y;    if(prev ) {        if(prev->isTableCell()) return;        offset -= prev->yPos();    } else {        prev = m_parent;        if(!prev) return;    }    // add overhanging special objects from the previous RenderFlow    if(!prev->isFlow()) return;    RenderFlow * flow = static_cast<RenderFlow *>(prev);    if(!flow->specialObjects) return;    if(style()->htmlHacks() && style()->flowAroundFloats())        return; //html tables and lists flow as blocks    if(flow->floatBottom() > offset)    {#ifdef DEBUG_LAYOUT//        kdDebug( 6040 ) << this << ": adding overhanging floats" << endl;#endif        // we have overhanging floats        if(!specialObjects)        {            specialObjects = new QSortedList<SpecialObject>;            specialObjects->setAutoDelete(true);        }        QListIterator<SpecialObject> it(*flow->specialObjects);        SpecialObject *r;        for ( ; (r = it.current()); ++it )        {            if (r->endY > offset && r->type <= SpecialObject::FloatRight)            {                // we need to add the float here too                SpecialObject *special = new SpecialObject;                special->count = specialObjects->count();                special->startY = r->startY - offset;                special->endY = r->endY - offset;                special->left = r->left - marginLeft();                if (prev!=m_parent)                    special->left += prev->marginLeft();                special->width = r->width;                special->node = r->node;                special->type = r->type;                specialObjects->append(special);#ifdef DEBUG_LAYOUT//                kdDebug( 6040 ) << "    y: " << special->startY << "-" << special->endY << " left: " << special->left << " width: " << special->width << endl;#endif            }        }    }}short RenderFlow::baselineOffset() const{    switch(m_style->verticalAlign())    {    case BASELINE:        {        int r = 0;        if (firstChild())            r = firstChild()->yPos() + firstChild()->baselineOffset();//kdDebug( 6040 ) << "aligned to baseline " << r << endl;        return r;        }    case SUB:        // ###    case SUPER:        // ###    case TOP:        return 0;    case TEXT_TOP:        return MGFontMetrics(m_style->font(), m_part).ascent();    case MIDDLE:        return contentHeight()/2;    case BOTTOM:        return contentHeight();    case TEXT_BOTTOM:        return contentHeight() - MGFontMetrics(m_style->font(), m_part).descent();

⌨️ 快捷键说明

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