📄 renderlayer.cpp
字号:
/* * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. * * Portions are Copyright (C) 1998 Netscape Communications Corporation. * * Other contributors: * Robert O'Callahan <roc+@cs.cmu.edu> * David Baron <dbaron@fas.harvard.edu> * Christian Biesinger <cbiesinger@web.de> * Randall Jesup <rjesup@wgate.com> * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de> * Josh Soref <timeless@mac.com> * Boris Zbarsky <bzbarsky@mit.edu> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Alternatively, the contents of this file may be used under the terms * of either the Mozilla Public License Version 1.1, found at * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html * (the "GPL"), in which case the provisions of the MPL or the GPL are * applicable instead of those above. If you wish to allow use of your * version of this file only under the terms of one of those two * licenses (the MPL or the GPL) and not to allow others to use your * version of this file under the LGPL, indicate your decision by * deletingthe provisions above and replace them with the notice and * other provisions required by the MPL or the GPL, as the case may be. * If you do not delete the provisions above, a recipient may use your * version of this file under any of the LGPL, the MPL or the GPL. */#include "config.h"#include "RenderLayer.h"#include "CString.h"#include "CSSPropertyNames.h"#include "CSSStyleSelector.h"#include "Document.h"#include "EventHandler.h"#include "EventNames.h"#include "FloatPoint3D.h"#include "FloatRect.h"#include "FocusController.h"#include "Frame.h"#include "FrameTree.h"#include "FrameView.h"#include "Gradient.h"#include "GraphicsContext.h"#include "HTMLNames.h"#include "HitTestRequest.h"#include "HitTestResult.h"#include "OverflowEvent.h"#include "Page.h"#include "PlatformMouseEvent.h"#include "RenderArena.h"#include "RenderInline.h"#include "RenderMarquee.h"#include "RenderReplica.h"#include "RenderScrollbar.h"#include "RenderScrollbarPart.h"#include "RenderTheme.h"#include "RenderView.h"#include "ScaleTransformOperation.h"#include "Scrollbar.h"#include "ScrollbarTheme.h"#include "SelectionController.h"#include "TransformationMatrix.h"#include "TransformState.h"#include "TranslateTransformOperation.h"#include <wtf/StdLibExtras.h>#include <wtf/UnusedParam.h>#if USE(ACCELERATED_COMPOSITING)#include "RenderLayerBacking.h"#include "RenderLayerCompositor.h"#endif#if ENABLE(SVG)#include "SVGNames.h"#endif#define MIN_INTERSECT_FOR_REVEAL 32using namespace std;namespace WebCore {using namespace HTMLNames;const int MinimumWidthWhileResizing = 100;const int MinimumHeightWhileResizing = 40;void* ClipRects::operator new(size_t sz, RenderArena* renderArena) throw(){ return renderArena->allocate(sz);}void ClipRects::operator delete(void* ptr, size_t sz){ // Stash size where destroy can find it. *(size_t *)ptr = sz;}void ClipRects::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);}RenderLayer::RenderLayer(RenderBoxModelObject* renderer) : m_renderer(renderer) , m_parent(0) , m_previous(0) , m_next(0) , m_first(0) , m_last(0) , m_relX(0) , m_relY(0) , m_x(0) , m_y(0) , m_width(0) , m_height(0) , m_scrollX(0) , m_scrollY(0) , m_scrollOriginX(0) , m_scrollLeftOverflow(0) , m_scrollWidth(0) , m_scrollHeight(0) , m_inResizeMode(false) , m_posZOrderList(0) , m_negZOrderList(0) , m_normalFlowList(0) , m_clipRects(0) #ifndef NDEBUG , m_clipRectsRoot(0)#endif , m_scrollDimensionsDirty(true) , m_zOrderListsDirty(true) , m_normalFlowListDirty(true) , m_isNormalFlowOnly(shouldBeNormalFlowOnly()) , m_usedTransparency(false) , m_paintingInsideReflection(false) , m_inOverflowRelayout(false) , m_needsFullRepaint(false) , m_overflowStatusDirty(true) , m_visibleContentStatusDirty(true) , m_hasVisibleContent(false) , m_visibleDescendantStatusDirty(false) , m_hasVisibleDescendant(false) , m_3DTransformedDescendantStatusDirty(true) , m_has3DTransformedDescendant(false)#if USE(ACCELERATED_COMPOSITING) , m_hasCompositingDescendant(false)#endif , m_marquee(0) , m_staticX(0) , m_staticY(0) , m_reflection(0) , m_scrollCorner(0) , m_resizer(0){ if (!renderer->firstChild() && renderer->style()) { m_visibleContentStatusDirty = false; m_hasVisibleContent = renderer->style()->visibility() == VISIBLE; }}RenderLayer::~RenderLayer(){ if (inResizeMode() && !renderer()->documentBeingDestroyed()) { if (Frame* frame = renderer()->document()->frame()) frame->eventHandler()->resizeLayerDestroyed(); } destroyScrollbar(HorizontalScrollbar); destroyScrollbar(VerticalScrollbar); // Child layers will be deleted by their corresponding render objects, so // we don't need to delete them ourselves. delete m_posZOrderList; delete m_negZOrderList; delete m_normalFlowList; delete m_marquee;#if USE(ACCELERATED_COMPOSITING) clearBacking();#endif // Make sure we have no lingering clip rects. ASSERT(!m_clipRects); if (m_reflection) { if (!m_reflection->documentBeingDestroyed()) m_reflection->removeLayers(this); m_reflection->setParent(0); m_reflection->destroy(); } if (m_scrollCorner) m_scrollCorner->destroy(); if (m_resizer) m_resizer->destroy();}#if USE(ACCELERATED_COMPOSITING)RenderLayerCompositor* RenderLayer::compositor() const{ ASSERT(renderer()->view()); return renderer()->view()->compositor();}#endif // USE(ACCELERATED_COMPOSITING)void RenderLayer::setStaticY(int staticY){ if (m_staticY == staticY) return; m_staticY = staticY; renderer()->setChildNeedsLayout(true, false);}void RenderLayer::updateLayerPositions(bool doFullRepaint, bool checkForRepaint){ if (doFullRepaint) { renderer()->repaint();#if USE(ACCELERATED_COMPOSITING) checkForRepaint = false; // We need the full repaint to propagate to child layers if we are hardware compositing. if (!compositor()->inCompositingMode()) doFullRepaint = false;#else checkForRepaint = doFullRepaint = false;#endif } updateLayerPosition(); // For relpositioned layers or non-positioned layers, // we need to keep in sync, since we may have shifted relative // to our parent layer. int x = 0; int y = 0; convertToLayerCoords(root(), x, y); positionOverflowControls(x, y); updateVisibilityStatus(); updateTransform(); if (m_hasVisibleContent) { RenderView* view = renderer()->view(); ASSERT(view); // FIXME: Optimize using LayoutState and remove the disableLayoutState() call // from updateScrollInfoAfterLayout(). ASSERT(!view->layoutStateEnabled()); RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint(); IntRect newRect = renderer()->clippedOverflowRectForRepaint(repaintContainer); IntRect newOutlineBox = renderer()->outlineBoundsForRepaint(repaintContainer); if (checkForRepaint) { if (view && !view->printing()) { if (m_needsFullRepaint) { renderer()->repaintUsingContainer(repaintContainer, m_repaintRect); if (newRect != m_repaintRect) renderer()->repaintUsingContainer(repaintContainer, newRect); } else renderer()->repaintAfterLayoutIfNeeded(repaintContainer, m_repaintRect, m_outlineBox); } } m_repaintRect = newRect; m_outlineBox = newOutlineBox; } else { m_repaintRect = IntRect(); m_outlineBox = IntRect(); } m_needsFullRepaint = false; // Go ahead and update the reflection's position and size. if (m_reflection) m_reflection->layout(); for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) child->updateLayerPositions(doFullRepaint, checkForRepaint);#if USE(ACCELERATED_COMPOSITING) if (!parent()) compositor()->updateRootLayerPosition(); if (isComposited()) backing()->updateAfterLayout();#endif // With all our children positioned, now update our marquee if we need to. if (m_marquee) m_marquee->updateMarqueePosition();}void RenderLayer::updateTransform(){ // hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set, // so check style too. bool hasTransform = renderer()->hasTransform() && renderer()->style()->hasTransform(); bool had3DTransform = has3DTransform(); bool hadTransform = m_transform; if (hasTransform != hadTransform) { if (hasTransform) m_transform.set(new TransformationMatrix); else m_transform.clear(); } if (hasTransform) { RenderBox* box = renderBox(); ASSERT(box); m_transform->makeIdentity(); box->style()->applyTransform(*m_transform, box->borderBoxRect().size(), RenderStyle::IncludeTransformOrigin); } if (had3DTransform != has3DTransform()) dirty3DTransformedDescendantStatus();}TransformationMatrix RenderLayer::currentTransform() const{ if (!m_transform) return TransformationMatrix();#if USE(ACCELERATED_COMPOSITING) if (renderer()->style()->isRunningAcceleratedAnimation()) { TransformationMatrix currTransform; RefPtr<RenderStyle> style = renderer()->animation()->getAnimatedStyleForRenderer(renderer()); style->applyTransform(currTransform, renderBox()->borderBoxRect().size(), RenderStyle::IncludeTransformOrigin); return currTransform; }#endif return *m_transform;}void RenderLayer::setHasVisibleContent(bool b){ if (m_hasVisibleContent == b && !m_visibleContentStatusDirty)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -