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

📄 renderboxmodelobject.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            includeLeftEdge ? style()->borderBottomLeftRadius() : IntSize(),            includeRightEdge ? style()->borderBottomRightRadius() : IntSize());        clippedToBorderRadius = true;    }    if (bgLayer->clip() == PaddingFillBox || bgLayer->clip() == ContentFillBox) {        // Clip to the padding or content boxes as necessary.        bool includePadding = bgLayer->clip() == ContentFillBox;        int x = tx + bLeft + (includePadding ? pLeft : 0);        int y = ty + borderTop() + (includePadding ? paddingTop() : 0);        int width = w - bLeft - bRight - (includePadding ? pLeft + pRight : 0);        int height = h - borderTop() - borderBottom() - (includePadding ? paddingTop() + paddingBottom() : 0);        context->save();        context->clip(IntRect(x, y, width, height));    } else if (bgLayer->clip() == TextFillBox) {        // We have to draw our text into a mask that can then be used to clip background drawing.        // First figure out how big the mask has to be.  It should be no bigger than what we need        // to actually render, so we should intersect the dirty rect with the border box of the background.        IntRect maskRect(tx, ty, w, h);        maskRect.intersect(paintInfo.rect);                // Now create the mask.        auto_ptr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size(), false);        if (!maskImage.get())            return;                GraphicsContext* maskImageContext = maskImage->context();        maskImageContext->translate(-maskRect.x(), -maskRect.y());                // Now add the text to the clip.  We do this by painting using a special paint phase that signals to        // InlineTextBoxes that they should just add their contents to the clip.        PaintInfo info(maskImageContext, maskRect, PaintPhaseTextClip, true, 0, 0);        if (box)            box->paint(info, tx - box->x(), ty - box->y());        else            paint(info, tx, ty);                    // The mask has been created.  Now we just need to clip to it.        context->save();        context->clipToImageBuffer(maskRect, maskImage.get());    }        StyleImage* bg = bgLayer->image();    bool shouldPaintBackgroundImage = bg && bg->canRender(style()->effectiveZoom());    Color bgColor = c;    // When this style flag is set, change existing background colors and images to a solid white background.    // If there's no bg color or image, leave it untouched to avoid affecting transparency.    // We don't try to avoid loading the background images, because this style flag is only set    // when printing, and at that point we've already loaded the background images anyway. (To avoid    // loading the background images we'd have to do this check when applying styles rather than    // while rendering.)    if (style()->forceBackgroundsToWhite()) {        // Note that we can't reuse this variable below because the bgColor might be changed        bool shouldPaintBackgroundColor = !bgLayer->next() && bgColor.isValid() && bgColor.alpha() > 0;        if (shouldPaintBackgroundImage || shouldPaintBackgroundColor) {            bgColor = Color::white;            shouldPaintBackgroundImage = false;        }    }    // Only fill with a base color (e.g., white) if we're the root document, since iframes/frames with    // no background in the child document should show the parent's background.    bool isTransparent = false;    if (!bgLayer->next() && isRoot() && !(bgColor.isValid() && bgColor.alpha() > 0) && view()->frameView()) {        Node* elt = document()->ownerElement();        if (elt) {            if (!elt->hasTagName(frameTag)) {                // Locate the <body> element using the DOM.  This is easier than trying                // to crawl around a render tree with potential :before/:after content and                // anonymous blocks created by inline <body> tags etc.  We can locate the <body>                // render object very easily via the DOM.                HTMLElement* body = document()->body();                isTransparent = !body || !body->hasLocalName(framesetTag); // Can't scroll a frameset document anyway.            }        } else            isTransparent = view()->frameView()->isTransparent();        // FIXME: This needs to be dynamic.  We should be able to go back to blitting if we ever stop being transparent.        if (isTransparent)            view()->frameView()->setUseSlowRepaints(); // The parent must show behind the child.    }    // Paint the color first underneath all images.    if (!bgLayer->next()) {        IntRect rect(tx, clipY, w, clipH);        // If we have an alpha and we are painting the root element, go ahead and blend with the base background color.        if (isRoot() && (!bgColor.isValid() || bgColor.alpha() < 0xFF) && !isTransparent) {            Color baseColor = view()->frameView()->baseBackgroundColor();            if (baseColor.alpha() > 0) {                context->save();                context->setCompositeOperation(CompositeCopy);                context->fillRect(rect, baseColor);                context->restore();            } else                context->clearRect(rect);        }        if (bgColor.isValid() && bgColor.alpha() > 0)            context->fillRect(rect, bgColor);    }    // no progressive loading of the background image    if (shouldPaintBackgroundImage) {        IntRect destRect;        IntPoint phase;        IntSize tileSize;        calculateBackgroundImageGeometry(bgLayer, tx, ty, w, h, destRect, phase, tileSize);        IntPoint destOrigin = destRect.location();        destRect.intersect(paintInfo.rect);        if (!destRect.isEmpty()) {            phase += destRect.location() - destOrigin;            CompositeOperator compositeOp = op == CompositeSourceOver ? bgLayer->composite() : op;            context->drawTiledImage(bg->image(this, tileSize), destRect, phase, tileSize, compositeOp);        }    }    if (bgLayer->clip() != BorderFillBox)        // Undo the background clip        context->restore();    if (clippedToBorderRadius)        // Undo the border radius clip        context->restore();}IntSize RenderBoxModelObject::calculateBackgroundSize(const FillLayer* bgLayer, int scaledWidth, int scaledHeight) const{    StyleImage* bg = bgLayer->image();    bg->setImageContainerSize(IntSize(scaledWidth, scaledHeight)); // Use the box established by background-origin.    if (bgLayer->isSizeSet()) {        int w = scaledWidth;        int h = scaledHeight;        Length bgWidth = bgLayer->size().width();        Length bgHeight = bgLayer->size().height();        if (bgWidth.isFixed())            w = bgWidth.value();        else if (bgWidth.isPercent())            w = bgWidth.calcValue(scaledWidth);                if (bgHeight.isFixed())            h = bgHeight.value();        else if (bgHeight.isPercent())            h = bgHeight.calcValue(scaledHeight);                // If one of the values is auto we have to use the appropriate        // scale to maintain our aspect ratio.        if (bgWidth.isAuto() && !bgHeight.isAuto())            w = bg->imageSize(this, style()->effectiveZoom()).width() * h / bg->imageSize(this, style()->effectiveZoom()).height();                else if (!bgWidth.isAuto() && bgHeight.isAuto())            h = bg->imageSize(this, style()->effectiveZoom()).height() * w / bg->imageSize(this, style()->effectiveZoom()).width();        else if (bgWidth.isAuto() && bgHeight.isAuto()) {            // If both width and height are auto, we just want to use the image's            // intrinsic size.            w = bg->imageSize(this, style()->effectiveZoom()).width();            h = bg->imageSize(this, style()->effectiveZoom()).height();        }                return IntSize(max(1, w), max(1, h));    } else        return bg->imageSize(this, style()->effectiveZoom());}void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* bgLayer, int tx, int ty, int w, int h,                                                             IntRect& destRect, IntPoint& phase, IntSize& tileSize){    int pw;    int ph;    int left = 0;    int right = 0;    int top = 0;    int bottom = 0;    int cx;    int cy;    int rw = 0;    int rh = 0;    // CSS2 chapter 14.2.1    if (bgLayer->attachment()) {        // Scroll        if (bgLayer->origin() != BorderFillBox) {            left = borderLeft();            right = borderRight();            top = borderTop();            bottom = borderBottom();            if (bgLayer->origin() == ContentFillBox) {                left += paddingLeft();                right += paddingRight();                top += paddingTop();                bottom += paddingBottom();            }        }                // The background of the box generated by the root element covers the entire canvas including        // its margins.  Since those were added in already, we have to factor them out when computing the        // box used by background-origin/size/position.        if (isRoot()) {            rw = toRenderBox(this)->width() - left - right;            rh = toRenderBox(this)->height() - top - bottom;             left += marginLeft();            right += marginRight();            top += marginTop();            bottom += marginBottom();        }        cx = tx;        cy = ty;        pw = w - left - right;        ph = h - top - bottom;    } else {        // Fixed        IntRect vr = viewRect();        cx = vr.x();        cy = vr.y();        pw = vr.width();        ph = vr.height();    }    int sx = 0;    int sy = 0;    int cw;    int ch;    IntSize scaledImageSize;    if (isRoot() && bgLayer->attachment())        scaledImageSize = calculateBackgroundSize(bgLayer, rw, rh);    else        scaledImageSize = calculateBackgroundSize(bgLayer, pw, ph);            int scaledImageWidth = scaledImageSize.width();    int scaledImageHeight = scaledImageSize.height();    EFillRepeat backgroundRepeat = bgLayer->repeat();        int xPosition;    if (isRoot() && bgLayer->attachment())        xPosition = bgLayer->xPosition().calcMinValue(rw - scaledImageWidth, true);    else        xPosition = bgLayer->xPosition().calcMinValue(pw - scaledImageWidth, true);    if (backgroundRepeat == RepeatFill || backgroundRepeat == RepeatXFill) {        cw = pw + left + right;        sx = scaledImageWidth ? scaledImageWidth - (xPosition + left) % scaledImageWidth : 0;    } else {        cx += max(xPosition + left, 0);        sx = -min(xPosition + left, 0);        cw = scaledImageWidth + min(xPosition + left, 0);    }        int yPosition;    if (isRoot() && bgLayer->attachment())        yPosition = bgLayer->yPosition().calcMinValue(rh - scaledImageHeight, true);    else         yPosition = bgLayer->yPosition().calcMinValue(ph - scaledImageHeight, true);    if (backgroundRepeat == RepeatFill || backgroundRepeat == RepeatYFill) {        ch = ph + top + bottom;        sy = scaledImageHeight ? scaledImageHeight - (yPosition + top) % scaledImageHeight : 0;    } else {        cy += max(yPosition + top, 0);        sy = -min(yPosition + top, 0);        ch = scaledImageHeight + min(yPosition + top, 0);    }    if (!bgLayer->attachment()) {        sx += max(tx - cx, 0);        sy += max(ty - cy, 0);    }    destRect = IntRect(cx, cy, cw, ch);    destRect.intersect(IntRect(tx, ty, w, h));    phase = IntPoint(sx, sy);    tileSize = IntSize(scaledImageWidth, scaledImageHeight);}int RenderBoxModelObject::verticalPosition(bool firstLine) const{    // This method determines the vertical position for inline elements.    ASSERT(isInline());    if (!isInline())

⌨️ 快捷键说明

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