📄 renderlayer.cpp
字号:
} return clipRect; } // Note: we don't have to walk z-order lists since transparent elements always establish // a stacking context. This means we can just walk the layer tree directly. IntRect clipRect = l->boundingBox(rootLayer); // If we have a mask, then the clip is limited to the border box area (and there is // no need to examine child layers). if (!l->renderer()->hasMask()) { for (RenderLayer* curr = l->firstChild(); curr; curr = curr->nextSibling()) { if (!l->reflection() || l->reflectionLayer() != curr) clipRect.unite(transparencyClipBox(enclosingTransform, curr, rootLayer)); } } // Now map the clipRect via the enclosing transform return enclosingTransform.mapRect(clipRect);}void RenderLayer::beginTransparencyLayers(GraphicsContext* p, const RenderLayer* rootLayer){ if (p->paintingDisabled() || (paintsWithTransparency() && m_usedTransparency)) return; RenderLayer* ancestor = transparentPaintingAncestor(); if (ancestor) ancestor->beginTransparencyLayers(p, rootLayer); if (paintsWithTransparency()) { m_usedTransparency = true; p->save(); p->clip(transparencyClipBox(TransformationMatrix(), this, rootLayer)); p->beginTransparencyLayer(renderer()->opacity()); }}void* RenderLayer::operator new(size_t sz, RenderArena* renderArena) throw(){ return renderArena->allocate(sz);}void RenderLayer::operator delete(void* ptr, size_t sz){ // Stash size where destroy can find it. *(size_t *)ptr = sz;}void RenderLayer::destroy(RenderArena* renderArena){ delete this; // Recover the size left there for us by operator delete and free the memory. renderArena->free(*(size_t *)this, this);}void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild){ RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild(); if (prevSibling) { child->setPreviousSibling(prevSibling); prevSibling->setNextSibling(child); } else setFirstChild(child); if (beforeChild) { beforeChild->setPreviousSibling(child); child->setNextSibling(beforeChild); } else setLastChild(child); child->setParent(this); if (child->isNormalFlowOnly()) dirtyNormalFlowList(); if (!child->isNormalFlowOnly() || child->firstChild()) { // Dirty the z-order list in which we are contained. The stackingContext() can be null in the // case where we're building up generated content layers. This is ok, since the lists will start // off dirty in that case anyway. child->dirtyStackingContextZOrderLists(); } child->updateVisibilityStatus(); if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) childVisibilityChanged(true); #if USE(ACCELERATED_COMPOSITING) compositor()->layerWasAdded(this, child);#endif}RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild){#if USE(ACCELERATED_COMPOSITING) if (!renderer()->documentBeingDestroyed()) compositor()->layerWillBeRemoved(this, oldChild);#endif // remove the child if (oldChild->previousSibling()) oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); if (oldChild->nextSibling()) oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()); if (m_first == oldChild) m_first = oldChild->nextSibling(); if (m_last == oldChild) m_last = oldChild->previousSibling(); if (oldChild->isNormalFlowOnly()) dirtyNormalFlowList(); if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) { // Dirty the z-order list in which we are contained. When called via the // reattachment process in removeOnlyThisLayer, the layer may already be disconnected // from the main layer tree, so we need to null-check the |stackingContext| value. oldChild->dirtyStackingContextZOrderLists(); } oldChild->setPreviousSibling(0); oldChild->setNextSibling(0); oldChild->setParent(0); oldChild->updateVisibilityStatus(); if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant) childVisibilityChanged(false); return oldChild;}void RenderLayer::removeOnlyThisLayer(){ if (!m_parent) return; #if USE(ACCELERATED_COMPOSITING) compositor()->layerWillBeRemoved(m_parent, this);#endif // Dirty the clip rects. clearClipRectsIncludingDescendants(); // Remove us from the parent. RenderLayer* parent = m_parent; RenderLayer* nextSib = nextSibling(); parent->removeChild(this); if (reflection()) removeChild(reflectionLayer()); // Now walk our kids and reattach them to our parent. RenderLayer* current = m_first; while (current) { RenderLayer* next = current->nextSibling(); removeChild(current); parent->addChild(current, nextSib); current->updateLayerPositions(); current = next; } m_renderer->destroyLayer();}void RenderLayer::insertOnlyThisLayer(){ if (!m_parent && renderer()->parent()) { // We need to connect ourselves when our renderer() has a parent. // Find our enclosingLayer and add ourselves. RenderLayer* parentLayer = renderer()->parent()->enclosingLayer(); RenderLayer* beforeChild = parentLayer->reflectionLayer() != this ? renderer()->parent()->findNextLayer(parentLayer, renderer()) : 0; if (parentLayer) parentLayer->addChild(this, beforeChild); } // Remove all descendant layers from the hierarchy and add them to the new position. for (RenderObject* curr = renderer()->firstChild(); curr; curr = curr->nextSibling()) curr->moveLayers(m_parent, this); // Clear out all the clip rects. clearClipRectsIncludingDescendants();}void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, int& yPos) const{ if (ancestorLayer == this) return; if (renderer()->style()->position() == FixedPosition) { // Add in the offset of the view. We can obtain this by calling // localToAbsolute() on the RenderView. FloatPoint absPos = renderer()->localToAbsolute(FloatPoint(), true); xPos += absPos.x(); yPos += absPos.y(); return; } RenderLayer* parentLayer; if (renderer()->style()->position() == AbsolutePosition) parentLayer = enclosingPositionedAncestor(); else parentLayer = parent(); if (!parentLayer) return; parentLayer->convertToLayerCoords(ancestorLayer, xPos, yPos); xPos += x(); yPos += y();}void RenderLayer::panScrollFromPoint(const IntPoint& sourcePoint) { // We want to reduce the speed if we're close from the original point to improve the handleability of the scroll const int shortDistanceLimit = 100; // We delimit a 200 pixels long square enclosing the original point const int speedReducer = 2; // Within this square we divide the scrolling speed by 2 const int iconRadius = 10; Frame* frame = renderer()->document()->frame(); if (!frame) return; IntPoint currentMousePosition = frame->eventHandler()->currentMousePosition(); // We need to check if the current mouse position is out of the window. When the mouse is out of the window, the position is incoherent static IntPoint previousMousePosition; if (currentMousePosition.x() < 0 || currentMousePosition.y() < 0) currentMousePosition = previousMousePosition; else previousMousePosition = currentMousePosition; int xDelta = currentMousePosition.x() - sourcePoint.x(); int yDelta = currentMousePosition.y() - sourcePoint.y(); if (abs(xDelta) < iconRadius) // at the center we let the space for the icon xDelta = 0; if (abs(yDelta) < iconRadius) yDelta = 0; // Let's attenuate the speed for the short distances if (abs(xDelta) < shortDistanceLimit) xDelta /= speedReducer; if (abs(yDelta) < shortDistanceLimit) yDelta /= speedReducer; scrollByRecursively(xDelta, yDelta);}void RenderLayer::scrollByRecursively(int xDelta, int yDelta){ bool restrictedByLineClamp = false; if (renderer()->parent()) restrictedByLineClamp = renderer()->parent()->style()->lineClamp() >= 0; if (renderer()->hasOverflowClip() && !restrictedByLineClamp) { int newOffsetX = scrollXOffset() + xDelta; int newOffsetY = scrollYOffset() + yDelta; scrollToOffset(newOffsetX, newOffsetY); // If this layer can't do the scroll we ask its parent int leftToScrollX = newOffsetX - scrollXOffset(); int leftToScrollY = newOffsetY - scrollYOffset(); if ((leftToScrollX || leftToScrollY) && renderer()->parent()) { renderer()->parent()->enclosingLayer()->scrollByRecursively(leftToScrollX, leftToScrollY); Frame* frame = renderer()->document()->frame(); if (frame) frame->eventHandler()->updateAutoscrollRenderer(); } } else if (renderer()->view()->frameView()) renderer()->view()->frameView()->scrollBy(IntSize(xDelta, yDelta));}voidRenderLayer::addScrolledContentOffset(int& x, int& y) const{ x += scrollXOffset() + m_scrollLeftOverflow; y += scrollYOffset();}voidRenderLayer::subtractScrolledContentOffset(int& x, int& y) const{ x -= scrollXOffset() + m_scrollLeftOverflow; y -= scrollYOffset();}void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repaint){ RenderBox* box = renderBox(); if (!box) return; if (box->style()->overflowX() != OMARQUEE) { if (x < 0) x = 0; if (y < 0) y = 0; // Call the scrollWidth/Height functions so that the dimensions will be computed if they need // to be (for overflow:hidden blocks). int maxX = scrollWidth() - box->clientWidth(); int maxY = scrollHeight() - box->clientHeight(); if (x > maxX) x = maxX; if (y > maxY) y = maxY; } // FIXME: Eventually, we will want to perform a blit. For now never // blit, since the check for blitting is going to be very // complicated (since it will involve testing whether our layer // is either occluded by another layer or clipped by an enclosing // layer or contains fixed backgrounds, etc.). int newScrollX = x - m_scrollOriginX; if (m_scrollY == y && m_scrollX == newScrollX) return; m_scrollX = newScrollX; m_scrollY = y; // Update the positions of our child layers. for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) child->updateLayerPositions(false, false);#if USE(ACCELERATED_COMPOSITING) if (isComposited()) m_backing->updateGraphicsLayerGeometry();#endif RenderView* view = renderer()->view(); // We should have a RenderView if we're trying to scroll. ASSERT(view); if (view) {#if ENABLE(DASHBOARD_SUPPORT) // Update dashboard regions, scrolling may change the clip of a // particular region. view->frameView()->updateDashboardRegions();#endif view->updateWidgetPositions(); } // The caret rect needs to be invalidated after scrolling Frame* frame = renderer()->document()->frame(); if (frame) frame->invalidateSelection(); // Just schedule a full repaint of our object. if (repaint) renderer()->repaint(); if (updateScrollbars) { if (m_hBar) m_hBar->setValue(scrollXOffset()); if (m_vBar) m_vBar->setValue(m_scrollY); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -