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

📄 renderinline.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();    if (madeNewBeforeBlock)        block->children()->insertChildNode(block, pre, boxFirst);    block->children()->insertChildNode(block, newBlockBox, boxFirst);    block->children()->insertChildNode(block, post, boxFirst);    block->setChildrenInline(false);        if (madeNewBeforeBlock) {        RenderObject* o = boxFirst;        while (o) {            RenderObject* no = o;            o = no->nextSibling();            pre->children()->appendChildNode(pre, block->children()->removeChildNode(block, no));            no->setNeedsLayoutAndPrefWidthsRecalc();        }    }    splitInlines(pre, post, newBlockBox, beforeChild, oldCont);    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting    // time in makeChildrenNonInline by just setting this explicitly up front.    newBlockBox->setChildrenInline(false);    // We delayed adding the newChild until now so that the |newBlockBox| would be fully    // connected, thus allowing newChild access to a renderArena should it need    // to wrap itself in additional boxes (e.g., table construction).    newBlockBox->addChild(newChild);    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)    // get deleted properly.  Because objects moves from the pre block into the post block, we want to    // make new line boxes instead of leaving the old line boxes around.    pre->setNeedsLayoutAndPrefWidthsRecalc();    block->setNeedsLayoutAndPrefWidthsRecalc();    post->setNeedsLayoutAndPrefWidthsRecalc();}void RenderInline::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild){    RenderBoxModelObject* flow = continuationBefore(beforeChild);    ASSERT(!beforeChild || beforeChild->parent()->isRenderBlock() || beforeChild->parent()->isRenderInline());    RenderBoxModelObject* beforeChildParent = 0;    if (beforeChild)        beforeChildParent = static_cast<RenderBoxModelObject*>(beforeChild->parent());    else {        RenderBoxModelObject* cont = nextContinuation(flow);        if (cont)            beforeChildParent = cont;        else            beforeChildParent = flow;    }    if (newChild->isFloatingOrPositioned())        return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);    // A continuation always consists of two potential candidates: an inline or an anonymous    // block box holding block children.    bool childInline = newChild->isInline();    bool bcpInline = beforeChildParent->isInline();    bool flowInline = flow->isInline();    if (flow == beforeChildParent)        return flow->addChildIgnoringContinuation(newChild, beforeChild);    else {        // The goal here is to match up if we can, so that we can coalesce and create the        // minimal # of continuations needed for the inline.        if (childInline == bcpInline)            return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);        else if (flowInline == childInline)            return flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.        else            return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);    }}void RenderInline::paint(PaintInfo& paintInfo, int tx, int ty){    m_lineBoxes.paint(this, paintInfo, tx, ty);}void RenderInline::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool topLevel){    for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())        rects.append(IntRect(tx + curr->x(), ty + curr->y(), curr->width(), curr->height()));    if (continuation() && topLevel) {        if (continuation()->isBox()) {            RenderBox* box = toRenderBox(continuation());            continuation()->absoluteRects(rects,                                           tx - containingBlock()->x() + box->x(),                                          ty - containingBlock()->y() + box->y(),                                          topLevel);        } else            continuation()->absoluteRects(rects, tx - containingBlock()->x(), ty - containingBlock()->y(), topLevel);    }}void RenderInline::absoluteQuads(Vector<FloatQuad>& quads, bool topLevel){    for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {        FloatRect localRect(curr->x(), curr->y(), curr->width(), curr->height());        quads.append(localToAbsoluteQuad(localRect));    }        if (continuation() && topLevel)        continuation()->absoluteQuads(quads, topLevel);}int RenderInline::offsetLeft() const{    int x = RenderBoxModelObject::offsetLeft();    if (firstLineBox())        x += firstLineBox()->x();    return x;}int RenderInline::offsetTop() const{    int y = RenderBoxModelObject::offsetTop();    if (firstLineBox())        y += firstLineBox()->y();    return y;}int RenderInline::marginLeft() const{    Length margin = style()->marginLeft();    if (margin.isAuto())        return 0;    if (margin.isFixed())        return margin.value();    if (margin.isPercent())        return margin.calcMinValue(max(0, containingBlock()->availableWidth()));    return 0;}int RenderInline::marginRight() const{    Length margin = style()->marginRight();    if (margin.isAuto())        return 0;    if (margin.isFixed())        return margin.value();    if (margin.isPercent())        return margin.calcMinValue(max(0, containingBlock()->availableWidth()));    return 0;}const char* RenderInline::renderName() const{    if (isRelPositioned())        return "RenderInline (relative positioned)";    if (isAnonymous())        return "RenderInline (generated)";    if (isRunIn())        return "RenderInline (run-in)";    return "RenderInline";}bool RenderInline::nodeAtPoint(const HitTestRequest& request, HitTestResult& result,                                int x, int y, int tx, int ty, HitTestAction hitTestAction){    return m_lineBoxes.hitTest(this, request, result, x, y, tx, ty, hitTestAction);}VisiblePosition RenderInline::positionForPoint(const IntPoint& point){    // FIXME: Does not deal with relative positioned inlines (should it?)    RenderBlock* cb = containingBlock();    if (firstLineBox()) {        // This inline actually has a line box.  We must have clicked in the border/padding of one of these boxes.  We        // should try to find a result by asking our containing block.        return cb->positionForPoint(point);    }    // Translate the coords from the pre-anonymous block to the post-anonymous block.    int parentBlockX = cb->x() + point.x();    int parentBlockY = cb->y() + point.y();    RenderBoxModelObject* c = continuation();    while (c) {        RenderBox* contBlock = c->isInline() ? c->containingBlock() : toRenderBlock(c);        if (c->isInline() || c->firstChild())            return c->positionForCoordinates(parentBlockX - contBlock->x(), parentBlockY - contBlock->y());        c = toRenderBlock(c)->inlineContinuation();    }        return RenderBoxModelObject::positionForPoint(point);}IntRect RenderInline::linesBoundingBox() const{    IntRect result;        // See <rdar://problem/5289721>, for an unknown reason the linked list here is sometimes inconsistent, first is non-zero and last is zero.  We have been    // unable to reproduce this at all (and consequently unable to figure ot why this is happening).  The assert will hopefully catch the problem in debug    // builds and help us someday figure out why.  We also put in a redundant check of lastLineBox() to avoid the crash for now.    ASSERT(!firstLineBox() == !lastLineBox());  // Either both are null or both exist.    if (firstLineBox() && lastLineBox()) {        // Return the width of the minimal left side and the maximal right side.        int leftSide = 0;        int rightSide = 0;        for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {            if (curr == firstLineBox() || curr->x() < leftSide)                leftSide = curr->x();            if (curr == firstLineBox() || curr->x() + curr->width() > rightSide)                rightSide = curr->x() + curr->width();        }        result.setWidth(rightSide - leftSide);        result.setX(leftSide);        result.setHeight(lastLineBox()->y() + lastLineBox()->height() - firstLineBox()->y());        result.setY(firstLineBox()->y());    }    return result;}IntRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer){    // Only run-ins are allowed in here during layout.    ASSERT(!view() || !view()->layoutStateEnabled() || isRunIn());    if (!firstLineBox() && !continuation())        return IntRect();    // Find our leftmost position.    IntRect boundingBox(linesBoundingBox());    int left = boundingBox.x();    int top = boundingBox.y();    // Now invalidate a rectangle.    int ow = style() ? style()->outlineSize() : 0;        // We need to add in the relative position offsets of any inlines (including us) up to our    // containing block.    RenderBlock* cb = containingBlock();    for (RenderObject* inlineFlow = this; inlineFlow && inlineFlow->isRenderInline() && inlineFlow != cb;          inlineFlow = inlineFlow->parent()) {         if (inlineFlow->style()->position() == RelativePosition && inlineFlow->hasLayer())            toRenderInline(inlineFlow)->layer()->relativePositionOffset(left, top);    }    IntRect r(-ow + left, -ow + top, boundingBox.width() + ow * 2, boundingBox.height() + ow * 2);    if (cb->hasColumns())        cb->adjustRectForColumns(r);    if (cb->hasOverflowClip()) {        // cb->height() is inaccurate if we're in the middle of a layout of |cb|, so use the        // layer's size instead.  Even if the layer's size is wrong, the layer itself will repaint        // anyway if its size does change.        int x = r.x();        int y = r.y();        IntRect boxRect(0, 0, cb->layer()->width(), cb->layer()->height());        cb->layer()->subtractScrolledContentOffset(x, y); // For overflow:auto/scroll/hidden.        IntRect repaintRect(x, y, r.width(), r.height());        r = intersection(repaintRect, boxRect);    }        // FIXME: need to ensure that we compute the correct repaint rect when the repaint container    // is an inline.    if (repaintContainer != this)        cb->computeRectForRepaint(repaintContainer, r);    if (ow) {        for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {            if (!curr->isText()) {                IntRect childRect = curr->rectWithOutlineForRepaint(repaintContainer, ow);                r.unite(childRect);            }        }        if (continuation() && !continuation()->isInline()) {            IntRect contRect = continuation()->rectWithOutlineForRepaint(repaintContainer, ow);            r.unite(contRect);        }    }    return r;}IntRect RenderInline::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth){    IntRect r(RenderBoxModelObject::rectWithOutlineForRepaint(repaintContainer, outlineWidth));    for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {        if (!curr->isText())            r.unite(curr->rectWithOutlineForRepaint(repaintContainer, outlineWidth));    }    return r;}void RenderInline::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed){    if (RenderView* v = view()) {        // LayoutState is only valid for root-relative repainting        if (v->layoutStateEnabled() && !repaintContainer) {            LayoutState* layoutState = v->layoutState();            if (style()->position() == RelativePosition && layer())                rect.move(layer()->relativePositionOffset());            rect.move(layoutState->m_offset);            if (layoutState->m_clipped)                rect.intersect(layoutState->m_clipRect);            return;        }    }    if (repaintContainer == this)        return;    RenderObject* o = container();    if (!o)        return;    IntPoint topLeft = rect.location();    if (o->isBlockFlow() && style()->position() != AbsolutePosition && style()->position() != FixedPosition) {        RenderBlock* cb = toRenderBlock(o);        if (cb->hasColumns()) {            IntRect repaintRect(topLeft, rect.size());            cb->adjustRectForColumns(repaintRect);            topLeft = repaintRect.location();            rect = repaintRect;        }    }    if (style()->position() == RelativePosition && layer()) {        // Apply the relative position offset when invalidating a rectangle.  The layer        // is translated, but the render box isn't, so we need to do this to get the        // right dirty rect.  Since this is called from RenderObject::setStyle, the relative position        // flag on the RenderObject has been cleared, so use the one on the style().        topLeft += layer()->relativePositionOffset();    }        // FIXME: We ignore the lightweight clipping rect that controls use, since if |o| is in mid-layout,    // its controlClipRect will be wrong. For overflow clip we use the values cached by the layer.    if (o->hasOverflowClip()) {        RenderBox* containerBox = toRenderBox(o);        // o->height() is inaccurate if we're in the middle of a layout of |o|, so use the        // layer's size instead.  Even if the layer's size is wrong, the layer itself will repaint        // anyway if its size does change.        topLeft -= containerBox->layer()->scrolledContentOffset(); // For overflow:auto/scroll/hidden.        IntRect repaintRect(topLeft, rect.size());        IntRect boxRect(0, 0, containerBox->layer()->width(), containerBox->layer()->height());        rect = intersection(repaintRect, boxRect);

⌨️ 快捷键说明

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