📄 renderlayer.cpp
字号:
return; m_visibleContentStatusDirty = false; m_hasVisibleContent = b; if (m_hasVisibleContent) { RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint(); m_repaintRect = renderer()->clippedOverflowRectForRepaint(repaintContainer); m_outlineBox = renderer()->outlineBoundsForRepaint(repaintContainer); if (!isNormalFlowOnly()) dirtyStackingContextZOrderLists(); } if (parent()) parent()->childVisibilityChanged(m_hasVisibleContent);}void RenderLayer::dirtyVisibleContentStatus() { m_visibleContentStatusDirty = true; if (parent()) parent()->dirtyVisibleDescendantStatus();}void RenderLayer::childVisibilityChanged(bool newVisibility) { if (m_hasVisibleDescendant == newVisibility || m_visibleDescendantStatusDirty) return; if (newVisibility) { RenderLayer* l = this; while (l && !l->m_visibleDescendantStatusDirty && !l->m_hasVisibleDescendant) { l->m_hasVisibleDescendant = true; l = l->parent(); } } else dirtyVisibleDescendantStatus();}void RenderLayer::dirtyVisibleDescendantStatus(){ RenderLayer* l = this; while (l && !l->m_visibleDescendantStatusDirty) { l->m_visibleDescendantStatusDirty = true; l = l->parent(); }}void RenderLayer::updateVisibilityStatus(){ if (m_visibleDescendantStatusDirty) { m_hasVisibleDescendant = false; for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) { child->updateVisibilityStatus(); if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) { m_hasVisibleDescendant = true; break; } } m_visibleDescendantStatusDirty = false; } if (m_visibleContentStatusDirty) { if (renderer()->style()->visibility() == VISIBLE) m_hasVisibleContent = true; else { // layer may be hidden but still have some visible content, check for this m_hasVisibleContent = false; RenderObject* r = renderer()->firstChild(); while (r) { if (r->style()->visibility() == VISIBLE && !r->hasLayer()) { m_hasVisibleContent = true; break; } if (r->firstChild() && !r->hasLayer()) r = r->firstChild(); else if (r->nextSibling()) r = r->nextSibling(); else { do { r = r->parent(); if (r==renderer()) r = 0; } while (r && !r->nextSibling()); if (r) r = r->nextSibling(); } } } m_visibleContentStatusDirty = false; }}void RenderLayer::dirty3DTransformedDescendantStatus(){ RenderLayer* curr = stackingContext(); if (curr) curr->m_3DTransformedDescendantStatusDirty = true; // This propagates up through preserve-3d hierarchies to the enclosing flattening layer. // Note that preserves3D() creates stacking context, so we can just run up the stacking contexts. while (curr && curr->preserves3D()) { curr->m_3DTransformedDescendantStatusDirty = true; curr = curr->stackingContext(); }}// Return true if this layer or any preserve-3d descendants have 3d.bool RenderLayer::update3DTransformedDescendantStatus(){ if (m_3DTransformedDescendantStatusDirty) { m_has3DTransformedDescendant = false; // Transformed or preserve-3d descendants can only be in the z-order lists, not // in the normal flow list, so we only need to check those. if (m_posZOrderList) { for (unsigned i = 0; i < m_posZOrderList->size(); ++i) m_has3DTransformedDescendant |= m_posZOrderList->at(i)->update3DTransformedDescendantStatus(); } // Now check our negative z-index children. if (m_negZOrderList) { for (unsigned i = 0; i < m_negZOrderList->size(); ++i) m_has3DTransformedDescendant |= m_negZOrderList->at(i)->update3DTransformedDescendantStatus(); } } // If we live in a 3d hierarchy, then the layer at the root of that hierarchy needs // the m_has3DTransformedDescendant set. if (preserves3D()) return has3DTransform() || m_has3DTransformedDescendant; return has3DTransform();}void RenderLayer::updateLayerPosition(){ // Clear our cached clip rect information. clearClipRects(); RenderBox* rendererBox = renderBox(); int x = rendererBox ? rendererBox->x() : 0; int y = rendererBox ? rendererBox->y() : 0; if (!renderer()->isPositioned() && renderer()->parent()) { // We must adjust our position by walking up the render tree looking for the // nearest enclosing object with a layer. RenderObject* curr = renderer()->parent(); while (curr && !curr->hasLayer()) { if (curr->isBox() && !curr->isTableRow()) { // Rows and cells share the same coordinate space (that of the section). // Omit them when computing our xpos/ypos. RenderBox* currBox = toRenderBox(curr); x += currBox->x(); y += currBox->y(); } curr = curr->parent(); } if (curr->isBox() && curr->isTableRow()) { // Put ourselves into the row coordinate space. RenderBox* currBox = toRenderBox(curr); x -= currBox->x(); y -= currBox->y(); } } m_relX = m_relY = 0; if (renderer()->isRelPositioned()) { m_relX = renderer()->relativePositionOffsetX(); m_relY = renderer()->relativePositionOffsetY(); x += m_relX; y += m_relY; } // Subtract our parent's scroll offset. if (renderer()->isPositioned() && enclosingPositionedAncestor()) { RenderLayer* positionedParent = enclosingPositionedAncestor(); // For positioned layers, we subtract out the enclosing positioned layer's scroll offset. positionedParent->subtractScrolledContentOffset(x, y); if (renderer()->isPositioned() && positionedParent->renderer()->isRelPositioned() && positionedParent->renderer()->isRenderInline()) { IntSize offset = toRenderInline(positionedParent->renderer())->relativePositionedInlineOffset(toRenderBox(renderer())); x += offset.width(); y += offset.height(); } } else if (parent()) parent()->subtractScrolledContentOffset(x, y); // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers. setLocation(x, y); if (renderer()->isRenderInline()) { RenderInline* inlineFlow = toRenderInline(renderer()); IntRect lineBox = inlineFlow->linesBoundingBox(); setWidth(lineBox.width()); setHeight(lineBox.height()); } else if (RenderBox* box = renderBox()) { setWidth(box->width()); setHeight(box->height()); if (!box->hasOverflowClip()) { if (box->overflowWidth() > box->width()) setWidth(box->overflowWidth()); if (box->overflowHeight() > box->height()) setHeight(box->overflowHeight()); } }}TransformationMatrix RenderLayer::perspectiveTransform() const{ if (!renderer()->hasTransform()) return TransformationMatrix(); RenderStyle* style = renderer()->style(); if (!style->hasPerspective()) return TransformationMatrix(); // Maybe fetch the perspective from the backing? const IntRect borderBox = toRenderBox(renderer())->borderBoxRect(); const float boxWidth = borderBox.width(); const float boxHeight = borderBox.height(); float perspectiveOriginX = style->perspectiveOriginX().calcFloatValue(boxWidth); float perspectiveOriginY = style->perspectiveOriginY().calcFloatValue(boxHeight); // A perspective origin of 0,0 makes the vanishing point in the center of the element. // We want it to be in the top-left, so subtract half the height and width. perspectiveOriginX -= boxWidth / 2.0f; perspectiveOriginY -= boxHeight / 2.0f; TransformationMatrix t; t.translate(perspectiveOriginX, perspectiveOriginY); t.applyPerspective(style->perspective()); t.translate(-perspectiveOriginX, -perspectiveOriginY); return t;}FloatPoint RenderLayer::perspectiveOrigin() const{ if (!renderer()->hasTransform()) return FloatPoint(); const IntRect borderBox = toRenderBox(renderer())->borderBoxRect(); RenderStyle* style = renderer()->style(); return FloatPoint(style->perspectiveOriginX().calcFloatValue(borderBox.width()), style->perspectiveOriginY().calcFloatValue(borderBox.height()));}RenderLayer* RenderLayer::stackingContext() const{ RenderLayer* layer = parent(); while (layer && !layer->renderer()->isRenderView() && !layer->renderer()->isRoot() && layer->renderer()->style()->hasAutoZIndex()) layer = layer->parent(); return layer;}RenderLayer* RenderLayer::enclosingPositionedAncestor() const{ RenderLayer* curr = parent(); for ( ; curr && !curr->renderer()->isRenderView() && !curr->renderer()->isPositioned() && !curr->renderer()->isRelPositioned() && !curr->hasTransform(); curr = curr->parent()) { } return curr;}RenderLayer* RenderLayer::enclosingTransformedAncestor() const{ RenderLayer* curr = parent(); for ( ; curr && !curr->renderer()->isRenderView() && !curr->transform(); curr = curr->parent()) { } return curr;}#if USE(ACCELERATED_COMPOSITING)RenderLayer* RenderLayer::enclosingCompositingLayer(bool includeSelf) const{ if (includeSelf && isComposited()) return const_cast<RenderLayer*>(this); // Compositing layers are parented according to stacking order and overflow list, // so we have to check whether the parent is a stacking context, or whether // the child is overflow-only. bool inNormalFlowList = isNormalFlowOnly(); for (RenderLayer* curr = parent(); curr; curr = curr->parent()) { if (curr->isComposited() && (inNormalFlowList || curr->isStackingContext())) return curr; inNormalFlowList = curr->isNormalFlowOnly(); } return 0;}#endifIntPoint RenderLayer::absoluteToContents(const IntPoint& absolutePoint) const{ // We don't use convertToLayerCoords because it doesn't know about transforms return roundedIntPoint(renderer()->absoluteToLocal(absolutePoint, false, true));}bool RenderLayer::requiresSlowRepaints() const{ if (isTransparent() || hasReflection() || hasTransform()) return true; if (!parent()) return false; return parent()->requiresSlowRepaints();}bool RenderLayer::isTransparent() const{#if ENABLE(SVG) if (renderer()->node() && renderer()->node()->namespaceURI() == SVGNames::svgNamespaceURI) return false;#endif return renderer()->isTransparent() || renderer()->hasMask();}RenderLayer* RenderLayer::transparentPaintingAncestor(){ if (isComposited()) return 0; for (RenderLayer* curr = parent(); curr; curr = curr->parent()) { if (curr->isComposited()) return 0; if (curr->isTransparent()) return curr; } return 0;}static IntRect transparencyClipBox(const TransformationMatrix& enclosingTransform, const RenderLayer* l, const RenderLayer* rootLayer){ // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the // paintDirtyRect, and that should cut down on the amount we have to paint. Still it // would be better to respect clips. if (rootLayer != l && l->paintsWithTransform()) { // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass // the transformed layer and all of its children. int x = 0; int y = 0; l->convertToLayerCoords(rootLayer, x, y); TransformationMatrix transform; transform.translate(x, y); transform = *l->transform() * transform; transform = transform * enclosingTransform; // We now have a transform that will produce a rectangle in our view's space. IntRect clipRect = transform.mapRect(l->boundingBox(l)); // Now shift the root layer to be us and pass down the new enclosing transform. for (RenderLayer* curr = l->firstChild(); curr; curr = curr->nextSibling()) { if (!l->reflection() || l->reflectionLayer() != curr) clipRect.unite(transparencyClipBox(transform, curr, l));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -