📄 renderbox.cpp
字号:
// We have to use an extra image buffer to hold the mask. Multiple mask images need // to composite together using source-over so that they can then combine into a single unified mask that // can be composited with the content using destination-in. SVG images need to be able to set compositing modes // as they draw images contained inside their sub-document, so we paint all our images into a separate buffer // and composite that buffer as the mask. pushTransparencyLayer = true; CompositeOperator compositeOp = CompositeDestinationIn; if (pushTransparencyLayer) { paintInfo.context->setCompositeOperation(CompositeDestinationIn); paintInfo.context->beginTransparencyLayer(1.0f); compositeOp = CompositeSourceOver; } paintFillLayers(paintInfo, Color(), style()->maskLayers(), my, mh, tx, ty, w, h, compositeOp); paintNinePieceImage(paintInfo.context, tx, ty, w, h, style(), style()->maskBoxImage(), compositeOp); if (pushTransparencyLayer) paintInfo.context->endTransparencyLayer();}IntRect RenderBox::maskClipRect(){ IntRect bbox = borderBoxRect(); if (style()->maskBoxImage().image()) return bbox; IntRect result; for (const FillLayer* maskLayer = style()->maskLayers(); maskLayer; maskLayer = maskLayer->next()) { if (maskLayer->image()) { IntRect maskRect; IntPoint phase; IntSize tileSize; calculateBackgroundImageGeometry(maskLayer, bbox.x(), bbox.y(), bbox.width(), bbox.height(), maskRect, phase, tileSize); result.unite(maskRect); } } return result;}void RenderBox::paintFillLayers(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, int clipY, int clipH, int tx, int ty, int width, int height, CompositeOperator op){ if (!fillLayer) return; paintFillLayers(paintInfo, c, fillLayer->next(), clipY, clipH, tx, ty, width, height, op); paintFillLayer(paintInfo, c, fillLayer, clipY, clipH, tx, ty, width, height, op);}void RenderBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, int clipY, int clipH, int tx, int ty, int width, int height, CompositeOperator op){ paintFillLayerExtended(paintInfo, c, fillLayer, clipY, clipH, tx, ty, width, height, 0, op);}void RenderBox::imageChanged(WrappedImagePtr image, const IntRect*){ if (!parent()) return; if (style()->borderImage().image() && style()->borderImage().image()->data() == image || style()->maskBoxImage().image() && style()->maskBoxImage().image()->data() == image) { repaint(); return; } bool didFullRepaint = repaintLayerRectsForImage(image, style()->backgroundLayers(), true); if (!didFullRepaint) repaintLayerRectsForImage(image, style()->maskLayers(), false);}bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer* layers, bool drawingBackground){ IntRect rendererRect; RenderBox* layerRenderer = 0; for (const FillLayer* curLayer = layers; curLayer; curLayer = curLayer->next()) { if (curLayer->image() && image == curLayer->image()->data() && curLayer->image()->canRender(style()->effectiveZoom())) { // Now that we know this image is being used, compute the renderer and the rect // if we haven't already if (!layerRenderer) { bool drawingRootBackground = drawingBackground && (isRoot() || (isBody() && !document()->documentElement()->renderer()->style()->hasBackground())); if (drawingRootBackground) { layerRenderer = view(); int rw; int rh; if (FrameView* frameView = toRenderView(layerRenderer)->frameView()) { rw = frameView->contentsWidth(); rh = frameView->contentsHeight(); } else { rw = layerRenderer->width(); rh = layerRenderer->height(); } rendererRect = IntRect(-layerRenderer->marginLeft(), -layerRenderer->marginTop(), max(layerRenderer->width() + layerRenderer->marginLeft() + layerRenderer->marginRight() + layerRenderer->borderLeft() + layerRenderer->borderRight(), rw), max(layerRenderer->height() + layerRenderer->marginTop() + layerRenderer->marginBottom() + layerRenderer->borderTop() + layerRenderer->borderBottom(), rh)); } else { layerRenderer = this; rendererRect = borderBoxRect(); } } IntRect repaintRect; IntPoint phase; IntSize tileSize; layerRenderer->calculateBackgroundImageGeometry(curLayer, rendererRect.x(), rendererRect.y(), rendererRect.width(), rendererRect.height(), repaintRect, phase, tileSize); layerRenderer->repaintRectangle(repaintRect); if (repaintRect == rendererRect) return true; } } return false;}#if PLATFORM(MAC)void RenderBox::paintCustomHighlight(int tx, int ty, const AtomicString& type, bool behindText){ Frame* frame = document()->frame(); if (!frame) return; Page* page = frame->page(); if (!page) return; InlineBox* boxWrap = inlineBoxWrapper(); RootInlineBox* r = boxWrap ? boxWrap->root() : 0; if (r) { FloatRect rootRect(tx + r->x(), ty + r->selectionTop(), r->width(), r->selectionHeight()); FloatRect imageRect(tx + x(), rootRect.y(), width(), rootRect.height()); page->chrome()->client()->paintCustomHighlight(node(), type, imageRect, rootRect, behindText, false); } else { FloatRect imageRect(tx + x(), ty + y(), width(), height()); page->chrome()->client()->paintCustomHighlight(node(), type, imageRect, imageRect, behindText, false); }}#endifbool RenderBox::pushContentsClip(PaintInfo& paintInfo, int tx, int ty){ if (paintInfo.phase == PaintPhaseBlockBackground || paintInfo.phase == PaintPhaseSelfOutline || paintInfo.phase == PaintPhaseMask) return false; bool isControlClip = hasControlClip(); bool isOverflowClip = hasOverflowClip() && !layer()->isSelfPaintingLayer(); if (!isControlClip && !isOverflowClip) return false; if (paintInfo.phase == PaintPhaseOutline) paintInfo.phase = PaintPhaseChildOutlines; else if (paintInfo.phase == PaintPhaseChildBlockBackground) { paintInfo.phase = PaintPhaseBlockBackground; paintObject(paintInfo, tx, ty); paintInfo.phase = PaintPhaseChildBlockBackgrounds; } IntRect clipRect(isControlClip ? controlClipRect(tx, ty) : overflowClipRect(tx, ty)); paintInfo.context->save(); paintInfo.context->clip(clipRect); return true;}void RenderBox::popContentsClip(PaintInfo& paintInfo, PaintPhase originalPhase, int tx, int ty){ ASSERT(hasControlClip() || (hasOverflowClip() && !layer()->isSelfPaintingLayer())); paintInfo.context->restore(); if (originalPhase == PaintPhaseOutline) { paintInfo.phase = PaintPhaseSelfOutline; paintObject(paintInfo, tx, ty); paintInfo.phase = originalPhase; } else if (originalPhase == PaintPhaseChildBlockBackground) paintInfo.phase = originalPhase;}IntRect RenderBox::overflowClipRect(int tx, int ty){ // FIXME: When overflow-clip (CSS3) is implemented, we'll obtain the property // here. int bLeft = borderLeft(); int bTop = borderTop(); int clipX = tx + bLeft; int clipY = ty + bTop; int clipWidth = width() - bLeft - borderRight(); int clipHeight = height() - bTop - borderBottom(); // Subtract out scrollbars if we have them. if (layer()) { clipWidth -= layer()->verticalScrollbarWidth(); clipHeight -= layer()->horizontalScrollbarHeight(); } return IntRect(clipX, clipY, clipWidth, clipHeight);}IntRect RenderBox::clipRect(int tx, int ty){ int clipX = tx; int clipY = ty; int clipWidth = width(); int clipHeight = height(); if (!style()->clipLeft().isAuto()) { int c = style()->clipLeft().calcValue(width()); clipX += c; clipWidth -= c; } if (!style()->clipRight().isAuto()) clipWidth -= width() - style()->clipRight().calcValue(width()); if (!style()->clipTop().isAuto()) { int c = style()->clipTop().calcValue(height()); clipY += c; clipHeight -= c; } if (!style()->clipBottom().isAuto()) clipHeight -= height() - style()->clipBottom().calcValue(height()); return IntRect(clipX, clipY, clipWidth, clipHeight);}int RenderBox::containingBlockWidthForContent() const{ RenderBlock* cb = containingBlock(); if (shrinkToAvoidFloats()) return cb->lineWidth(y(), false); return cb->availableWidth();}void RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const{ if (repaintContainer == this) return; if (RenderView* v = view()) { if (v->layoutStateEnabled()) { LayoutState* layoutState = v->layoutState(); IntSize offset = layoutState->m_offset; offset.expand(x(), y()); if (style()->position() == RelativePosition && layer()) offset += layer()->relativePositionOffset(); transformState.move(offset); return; } } if (style()->position() == FixedPosition) fixed = true; RenderObject* o = container(); if (!o) return; bool hasTransform = hasLayer() && layer()->transform(); if (hasTransform) fixed = false; // Elements with transforms act as a containing block for fixed position descendants IntSize containerOffset = offsetFromContainer(o); bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D()); if (useTransforms && hasTransform) transformState.applyTransform(transformFromContainer(o, containerOffset), preserve3D); else transformState.move(containerOffset.width(), containerOffset.height(), preserve3D); o->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState);}void RenderBox::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const{ // We don't expect absoluteToLocal() to be called during layout (yet) ASSERT(!view() || !view()->layoutStateEnabled()); if (style()->position() == FixedPosition) fixed = true; bool hasTransform = hasLayer() && layer()->transform(); if (hasTransform) fixed = false; // Elements with transforms act as a containing block for fixed position descendants RenderObject* o = container(); if (!o) return; o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState); IntSize containerOffset = offsetFromContainer(o); bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D()); if (useTransforms && hasTransform) transformState.applyTransform(transformFromContainer(o, containerOffset), preserve3D); else transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D);}IntSize RenderBox::offsetFromContainer(RenderObject* o) const{ ASSERT(o == container()); IntSize offset; if (isRelPositioned()) offset += relativePositionOffset(); if (!isInline() || isReplaced()) { RenderBlock* cb; if (o->isBlockFlow() && style()->position() != AbsolutePosition && style()->position() != FixedPosition && (cb = toRenderBlock(o))->hasColumns()) { IntRect rect(x(), y(), 1, 1); cb->adjustRectForColumns(rect); offset.expand(rect.x(), rect.y()); } else offset.expand(x(), y()); } if (o->hasOverflowClip()) offset -= toRenderBox(o)->layer()->scrolledContentOffset(); if (style()->position() == AbsolutePosition && o->isRelPositioned() && o->isRenderInline()) offset += toRenderInline(o)->relativePositionedInlineOffset(this); return offset;}InlineBox* RenderBox::createInlineBox(){ return new (renderArena()) InlineBox(this);}void RenderBox::dirtyLineBoxes(bool fullLayout){ if (m_inlineBoxWrapper) { if (fullLayout) { m_inlineBoxWrapper->destroy(renderArena()); m_inlineBoxWrapper = 0; } else m_inlineBoxWrapper->dirtyLineBoxes(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -