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

📄 render_flow.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    // the abs div.
    for (RenderObject *c = firstChild(); c; c = c->nextSibling()) {
        if (!c->isFloatingOrPositioned() && !c->isText()) {
            int lp = c->yPos() + c->lowestPosition(false);
            bottom = kMax(bottom, lp);
        }
    }
    
    return bottom;
}

int RenderFlow::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const
{
    int right = RenderContainer::rightmostPosition(includeOverflowInterior, includeSelf);
    if (!includeOverflowInterior && hasOverflowClip())
        return right;

    // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids.
    // For now, we have to descend into all the children, since we may have a huge abs div inside
    // a tiny rel div buried somewhere deep in our child tree.  In this case we have to get to
    // the abs div.
    for (RenderObject *c = firstChild(); c; c = c->nextSibling()) {
        if (!c->isFloatingOrPositioned() && !c->isText()) {
            int rp = c->xPos() + c->rightmostPosition(false);
            right = kMax(right, rp);
        }
    }
    
    return right;
}

int RenderFlow::leftmostPosition(bool includeOverflowInterior, bool includeSelf) const
{
    int left = RenderContainer::leftmostPosition(includeOverflowInterior, includeSelf);
    if (!includeOverflowInterior && hasOverflowClip())
        return left;
    
    // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids.
    // For now, we have to descend into all the children, since we may have a huge abs div inside
    // a tiny rel div buried somewhere deep in our child tree.  In this case we have to get to
    // the abs div.
    for (RenderObject *c = firstChild(); c; c = c->nextSibling()) {
        if (!c->isFloatingOrPositioned() && !c->isText()) {
            int lp = c->xPos() + c->leftmostPosition(false);
            left = kMin(left, lp);
        }
    }
    
    return left;
}

QRect RenderFlow::caretRect(int offset, EAffinity affinity, int *extraWidthToEndOfLine)
{
    if (firstChild() || style()->display() == INLINE) {
        // Do the normal calculation
        return RenderContainer::caretRect(offset, affinity, extraWidthToEndOfLine);
    }

    // This is a special case:
    // The element is not an inline element, and it's empty. So we have to
    // calculate a fake position to indicate where objects are to be inserted.
    
    int _x, _y, width, height;
    
    // EDIT FIXME: this does neither take into regard :first-line nor :first-letter
    // However, as soon as some content is entered, the line boxes will be
    // constructed properly and this kludge is not called any more. So only
    // the caret size of an empty :first-line'd block is wrong, but I think we
    // can live with that.
    RenderStyle *currentStyle = style(true);
    //height = currentStyle->fontMetrics().height();
    height = lineHeight(true);
    width = 1;

    // EDIT FIXME: This needs to account for text direction
    int w = this->width();
    switch (currentStyle->textAlign()) {
        case LEFT:
        case KHTML_LEFT:
        case TAAUTO:
        case JUSTIFY:
        default:
            _x = 0;
            break;
        case CENTER:
        case KHTML_CENTER:
            _x = w / 2;
        break;
        case RIGHT:
        case KHTML_RIGHT:
            _x = w;
        break;
    }
    
    _y = 0;
    

    if (extraWidthToEndOfLine) {
        if (isRenderBlock()) {
            *extraWidthToEndOfLine = this->width() - (_x + width);
        } else {
            int myRight = _x + width;
            int ignore;
            absolutePosition(myRight, ignore);
            
            int containerRight = containingBlock()->xPos() + containingBlockWidth();
            absolutePosition(containerRight, ignore);
            
            *extraWidthToEndOfLine = containerRight - myRight;
        }
    }

    int absx, absy;
    absolutePosition(absx, absy, false);
    _x += absx + paddingLeft() + borderLeft();
    _y += absy + paddingTop() + borderTop();

    return QRect(_x, _y, width, height);
}

#if APPLE_CHANGES
void RenderFlow::addFocusRingRects(QPainter *p, int _tx, int _ty)
{
    // Only paint focus ring around outermost contenteditable element.
    // But skip the body element if it is outermost.
    if (element() && element()->isContentEditable()) {
        if (element()->parentNode() && !element()->parentNode()->isContentEditable() && element()->id() != ID_BODY)
            p->addFocusRingRect(_tx, _ty, width(), height());
        return;
    }

    for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
        p->addFocusRingRect(_tx + curr->xPos(), 
                            _ty + curr->yPos(), 
                            curr->width(), 
                            curr->height());
    }
    
    for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
        if (!curr->isText())
            curr->addFocusRingRects(p, _tx + curr->xPos(), _ty + curr->yPos());
    }
    
    if (continuation())
        continuation()->addFocusRingRects(p, 
                                          _tx - containingBlock()->xPos() + continuation()->xPos(),
                                          _ty - containingBlock()->yPos() + continuation()->yPos());
}

void RenderFlow::paintFocusRing(QPainter *p, int tx, int ty)
{
    int ow = style()->outlineWidth();
    QColor oc = style()->outlineColor();
    if (!oc.isValid())
        oc = style()->color();
    
    p->initFocusRing(ow,  style()->outlineOffset(), oc);
    addFocusRingRects(p, tx, ty);
    p->drawFocusRing();
    p->clearFocusRing();
}
#endif

void RenderFlow::paintOutlines(QPainter *p, int _tx, int _ty)
{
    if (style()->outlineStyle() <= BHIDDEN)
        return;
    
    QPtrList <QRect> rects;
    rects.setAutoDelete(true);
    
    rects.append(new QRect(0,0,0,0));
    for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
        rects.append(new QRect(curr->xPos(), curr->yPos(), curr->width(), curr->height()));
    }
    rects.append(new QRect(0,0,0,0));
    
    for (unsigned int i = 1; i < rects.count() - 1; i++)
        paintOutlineForLine(p, _tx, _ty, *rects.at(i-1), *rects.at(i), *rects.at(i+1));
}

void RenderFlow::paintOutlineForLine(QPainter *p, int tx, int ty, const QRect &lastline, const QRect &thisline, const QRect &nextline)
{
    int ow = style()->outlineWidth();
    EBorderStyle os = style()->outlineStyle();
    QColor oc = style()->outlineColor();
    if (!oc.isValid())
        oc = style()->color();
    
    int offset = style()->outlineOffset();
    
    int t = ty + thisline.top() - offset;
    int l = tx + thisline.left() - offset;
    int b = ty + thisline.bottom() + offset + 1;
    int r = tx + thisline.right() + offset + 1;
    
    // left edge
    drawBorder(p,
               l - ow,
               t - (lastline.isEmpty() || thisline.left() < lastline.left() || lastline.right() <= thisline.left() ? ow : 0),
               l,
               b + (nextline.isEmpty() || thisline.left() <= nextline.left() || nextline.right() <= thisline.left() ? ow : 0),
               BSLeft,
               oc, style()->color(), os,
               (lastline.isEmpty() || thisline.left() < lastline.left() || lastline.right() <= thisline.left() ? ow : -ow),
               (nextline.isEmpty() || thisline.left() <= nextline.left() || nextline.right() <= thisline.left() ? ow : -ow),
               true);
    
    // right edge
    drawBorder(p,
               r,
               t - (lastline.isEmpty() || lastline.right() < thisline.right() || thisline.right() <= lastline.left() ? ow : 0),
               r + ow,
               b + (nextline.isEmpty() || nextline.right() <= thisline.right() || thisline.right() <= nextline.left() ? ow : 0),
               BSRight,
               oc, style()->color(), os,
               (lastline.isEmpty() || lastline.right() < thisline.right() || thisline.right() <= lastline.left() ? ow : -ow),
               (nextline.isEmpty() || nextline.right() <= thisline.right() || thisline.right() <= nextline.left() ? ow : -ow),
               true);
    // upper edge
    if ( thisline.left() < lastline.left())
        drawBorder(p,
                   l - ow,
                   t - ow,
                   QMIN(r+ow, (lastline.isValid()? tx+lastline.left() : 1000000)),
                   t ,
                   BSTop, oc, style()->color(), os,
                   ow,
                   (lastline.isValid() && tx+lastline.left()+1<r+ow ? -ow : ow),
                   true);
    
    if (lastline.right() < thisline.right())
        drawBorder(p,
                   QMAX(lastline.isValid()?tx + lastline.right() + 1:-1000000, l - ow),
                   t - ow,
                   r + ow,
                   t ,
                   BSTop, oc, style()->color(), os,
                   (lastline.isValid() && l-ow < tx+lastline.right()+1 ? -ow : ow),
                   ow,
                   true);
    
    // lower edge
    if ( thisline.left() < nextline.left())
        drawBorder(p,
                   l - ow,
                   b,
                   QMIN(r+ow, nextline.isValid()? tx+nextline.left()+1 : 1000000),
                   b + ow,
                   BSBottom, oc, style()->color(), os,
                   ow,
                   (nextline.isValid() && tx+nextline.left()+1<r+ow? -ow : ow),
                   true);
    
    if (nextline.right() < thisline.right())
        drawBorder(p,
                   QMAX(nextline.isValid()?tx+nextline.right()+1:-1000000 , l-ow),
                   b,
                   r + ow,
                   b + ow,
                   BSBottom, oc, style()->color(), os,
                   (nextline.isValid() && l-ow < tx+nextline.right()+1? -ow : ow),
                   ow,
                   true);
}

⌨️ 快捷键说明

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