#include "RuntimeEnabledFeatures.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLDialogElement.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/HTMLIFrameElement.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/page/Page.h"
-#include "core/platform/graphics/filters/custom/CustomFilterGlobalContext.h"
-#include "core/platform/graphics/GraphicsContext.h"
#include "core/rendering/ColumnInfo.h"
-#include "core/rendering/CompositedLayerMapping.h"
#include "core/rendering/FlowThreadController.h"
#include "core/rendering/GraphicsContextAnnotator.h"
#include "core/rendering/HitTestResult.h"
+#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderGeometryMap.h"
#include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
#include "core/rendering/RenderSelectionInfo.h"
-#include "core/rendering/RenderWidget.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "core/svg/SVGDocumentExtensions.h"
#include "platform/geometry/FloatQuad.h"
#include "platform/geometry/TransformState.h"
+#include "platform/graphics/GraphicsContext.h"
namespace WebCore {
, m_selectionEnd(0)
, m_selectionStartPos(-1)
, m_selectionEndPos(-1)
- , m_maximalOutlineSize(0)
, m_pageLogicalHeight(0)
, m_pageLogicalHeightChanged(false)
, m_layoutState(0)
RenderView::~RenderView()
{
- document().clearRenderView();
}
bool RenderView::hitTest(const HitTestRequest& request, HitTestResult& result)
// If we have columns, then the available logical height is reduced to the column height.
if (hasColumns())
return columnInfo()->columnHeight();
- return RenderBlock::availableLogicalHeight(heightType);
+ return RenderBlockFlow::availableLogicalHeight(heightType);
}
bool RenderView::isChildAllowed(RenderObject* child, RenderStyle*) const
return child->isBox();
}
-static bool dialogNeedsCentering(const RenderStyle* style)
+static bool canCenterDialog(const RenderStyle* style)
{
+ // FIXME: We must center for FixedPosition as well.
return style->position() == AbsolutePosition && style->hasAutoTopAndBottom();
}
if (dialog->centeringMode() == HTMLDialogElement::NotCentered)
return;
if (dialog->centeringMode() == HTMLDialogElement::Centered) {
- if (dialogNeedsCentering(box->style()))
+ if (canCenterDialog(box->style()))
box->setY(dialog->centeredPosition());
return;
}
- if (!dialogNeedsCentering(box->style())) {
+ ASSERT(dialog->centeringMode() == HTMLDialogElement::NeedsCentering);
+ if (!canCenterDialog(box->style())) {
dialog->setNotCentered();
return;
}
FrameView* frameView = document().view();
int scrollTop = frameView->scrollOffset().height();
- int visibleHeight = frameView->visibleContentRect(ScrollableArea::IncludeScrollbars).height();
+ int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height();
LayoutUnit top = scrollTop;
if (box->height() < visibleHeight)
top += (visibleHeight - box->height()) / 2;
TrackedRendererListHashSet::iterator end = positionedDescendants->end();
for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
RenderBox* box = *it;
- if (box->node() && box->node()->hasTagName(HTMLNames::dialogTag))
+ if (isHTMLDialogElement(box->node()))
positionDialog(box);
}
}
-void RenderView::layoutContent(const LayoutState& state)
+void RenderView::layoutContent()
{
- UNUSED_PARAM(state);
ASSERT(needsLayout());
- RenderBlock::layout();
+ LayoutRectRecorder recorder(*this);
+ RenderBlockFlow::layout();
if (RuntimeEnabledFeatures::dialogElementEnabled())
positionDialogs();
- if (m_frameView->partialLayout().isStopping())
- return;
-
- if (hasRenderNamedFlowThreads())
- flowThreadController()->layoutRenderNamedFlowThreads();
-
#ifndef NDEBUG
- checkLayoutState(state);
+ checkLayoutState();
#endif
}
#ifndef NDEBUG
-void RenderView::checkLayoutState(const LayoutState& state)
+void RenderView::checkLayoutState()
{
- ASSERT(layoutDeltaMatches(LayoutSize()));
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
+ ASSERT(layoutDeltaMatches(LayoutSize()));
+ }
ASSERT(!m_layoutStateDisableCount);
- ASSERT(m_layoutState == &state);
+ ASSERT(!m_layoutState->next());
}
#endif
-static RenderBox* enclosingSeamlessRenderer(const Document& doc)
-{
- Element* ownerElement = doc.seamlessParentIFrame();
- if (!ownerElement)
- return 0;
- return ownerElement->renderBox();
-}
-
-void RenderView::addChild(RenderObject* newChild, RenderObject* beforeChild)
-{
- // Seamless iframes are considered part of an enclosing render flow thread from the parent document. This is necessary for them to look
- // up regions in the parent document during layout.
- if (newChild && !newChild->isRenderFlowThread()) {
- RenderBox* seamlessBox = enclosingSeamlessRenderer(document());
- if (seamlessBox && seamlessBox->flowThreadContainingBlock())
- newChild->setFlowThreadState(seamlessBox->flowThreadState());
- }
- RenderBlock::addChild(newChild, beforeChild);
-}
-
-bool RenderView::initializeLayoutState(LayoutState& state)
-{
- bool isSeamlessAncestorInFlowThread = false;
-
- // FIXME: May be better to push a clip and avoid issuing offscreen repaints.
- state.m_clipped = false;
-
- // Check the writing mode of the seamless ancestor. It has to match our document's writing mode, or we won't inherit any
- // pagination information.
- RenderBox* seamlessAncestor = enclosingSeamlessRenderer(document());
- LayoutState* seamlessLayoutState = seamlessAncestor ? seamlessAncestor->view()->layoutState() : 0;
- bool shouldInheritPagination = seamlessLayoutState && !m_pageLogicalHeight && seamlessAncestor->style()->writingMode() == style()->writingMode();
-
- state.m_pageLogicalHeight = shouldInheritPagination ? seamlessLayoutState->m_pageLogicalHeight : m_pageLogicalHeight;
- state.m_pageLogicalHeightChanged = shouldInheritPagination ? seamlessLayoutState->m_pageLogicalHeightChanged : m_pageLogicalHeightChanged;
- state.m_isPaginated = state.m_pageLogicalHeight;
- if (state.m_isPaginated && shouldInheritPagination) {
- // Set up the correct pagination offset. We can use a negative offset in order to push the top of the RenderView into its correct place
- // on a page. We can take the iframe's offset from the logical top of the first page and make the negative into the pagination offset within the child
- // view.
- bool isFlipped = seamlessAncestor->style()->isFlippedBlocksWritingMode();
- LayoutSize layoutOffset = seamlessLayoutState->layoutOffset();
- LayoutSize iFrameOffset(layoutOffset.width() + seamlessAncestor->x() + (!isFlipped ? seamlessAncestor->borderLeft() + seamlessAncestor->paddingLeft() :
- seamlessAncestor->borderRight() + seamlessAncestor->paddingRight()),
- layoutOffset.height() + seamlessAncestor->y() + (!isFlipped ? seamlessAncestor->borderTop() + seamlessAncestor->paddingTop() :
- seamlessAncestor->borderBottom() + seamlessAncestor->paddingBottom()));
-
- LayoutSize offsetDelta = seamlessLayoutState->m_pageOffset - iFrameOffset;
- state.m_pageOffset = offsetDelta;
-
- // Set the current render flow thread to point to our ancestor. This will allow the seamless document to locate the correct
- // regions when doing a layout.
- if (seamlessAncestor->flowThreadContainingBlock()) {
- flowThreadController()->setCurrentRenderFlowThread(seamlessAncestor->view()->flowThreadController()->currentRenderFlowThread());
- isSeamlessAncestorInFlowThread = true;
- }
- }
-
- // FIXME: We need to make line grids and exclusions work with seamless iframes as well here. Basically all layout state information needs
- // to propagate here and not just pagination information.
- return isSeamlessAncestorInFlowThread;
-}
-
-// The algorithm below assumes this is a full layout. In case there are previously computed values for regions, supplemental steps are taken
-// to ensure the results are the same as those obtained from a full layout (i.e. the auto-height regions from all the flows are marked as needing
-// layout).
-// 1. The flows are laid out from the outer flow to the inner flow. This successfully computes the outer non-auto-height regions size so the
-// inner flows have the necessary information to correctly fragment the content.
-// 2. The flows are laid out from the inner flow to the outer flow. After an inner flow is laid out it goes into the constrained layout phase
-// and marks the auto-height regions they need layout. This means the outer flows will relayout if they depend on regions with auto-height regions
-// belonging to inner flows. This step will correctly set the computedAutoHeight for the auto-height regions. It's possible for non-auto-height
-// regions to relayout if they depend on auto-height regions. This will invalidate the inner flow threads and mark them as needing layout.
-// 3. The last step is to do one last layout if there are pathological dependencies between non-auto-height regions and auto-height regions
-// as detected in the previous step.
-void RenderView::layoutContentInAutoLogicalHeightRegions(const LayoutState& state)
-{
- if (!m_frameView->partialLayout().isStopping()) {
- // Disable partial layout for any two-pass layout algorithm.
- m_frameView->partialLayout().reset();
- }
-
- // We need to invalidate all the flows with auto-height regions if one such flow needs layout.
- // If none is found we do a layout a check back again afterwards.
- if (!flowThreadController()->updateFlowThreadsNeedingLayout()) {
- // Do a first layout of the content. In some cases more layouts are not needed (e.g. only flows with non-auto-height regions have changed).
- layoutContent(state);
-
- // If we find no named flow needing a two step layout after the first layout, exit early.
- // Otherwise, initiate the two step layout algorithm and recompute all the flows.
- if (!flowThreadController()->updateFlowThreadsNeedingTwoStepLayout())
- return;
- }
-
- // Layout to recompute all the named flows with auto-height regions.
- layoutContent(state);
-
- // Propagate the computed auto-height values upwards.
- // Non-auto-height regions may invalidate the flow thread because they depended on auto-height regions, but that's ok.
- flowThreadController()->updateFlowThreadsIntoConstrainedPhase();
-
- // Do one last layout that should update the auto-height regions found in the main flow
- // and solve pathological dependencies between regions (e.g. a non-auto-height region depending
- // on an auto-height one).
- if (needsLayout())
- layoutContent(state);
-}
-
void RenderView::layout()
{
- if (!configuration().paginated())
+ if (!document().paginated())
setPageLogicalHeight(0);
if (shouldUsePrintingLayout())
if ((child->isBox() && toRenderBox(child)->hasRelativeLogicalHeight())
|| child->style()->logicalHeight().isPercent()
|| child->style()->logicalMinHeight().isPercent()
- || child->style()->logicalMaxHeight().isPercent()
- || child->style()->logicalHeight().isViewportPercentage()
- || child->style()->logicalMinHeight().isViewportPercentage()
- || child->style()->logicalMaxHeight().isViewportPercentage())
+ || child->style()->logicalMaxHeight().isPercent())
layoutScope.setChildNeedsLayout(child);
}
if (document().svgExtensions())
- document().accessSVGExtensions()->invalidateSVGRootsWithRelativeLengthDescendents(&layoutScope);
+ document().accessSVGExtensions().invalidateSVGRootsWithRelativeLengthDescendents(&layoutScope);
}
ASSERT(!m_layoutState);
if (!needsLayout())
return;
- LayoutState state;
- bool isSeamlessAncestorInFlowThread = initializeLayoutState(state);
+ RootLayoutStateScope rootLayoutStateScope(*this);
m_pageLogicalHeightChanged = false;
- m_layoutState = &state;
- if (checkTwoPassLayoutForAutoHeightRegions())
- layoutContentInAutoLogicalHeightRegions(state);
- else
- layoutContent(state);
-
- if (m_frameView->partialLayout().isStopping()) {
- m_layoutState = 0;
- return;
- }
+ layoutContent();
#ifndef NDEBUG
- checkLayoutState(state);
+ checkLayoutState();
#endif
- m_layoutState = 0;
clearNeedsLayout();
-
- if (isSeamlessAncestorInFlowThread)
- flowThreadController()->setCurrentRenderFlowThread(0);
}
void RenderView::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
{
- ASSERT_UNUSED(wasFixed, !wasFixed || *wasFixed == (mode & IsFixed));
+ ASSERT_UNUSED(wasFixed, !wasFixed || *wasFixed == static_cast<bool>(mode & IsFixed));
if (!repaintContainer && mode & UseTransforms && shouldUseTransformFromContainer(0)) {
TransformationMatrix t;
rects.append(LayoutRect(LayoutPoint::zero(), frameView()->contentsSize()));
}
-bool RenderView::requiresColumns(int desiredColumnCount) const
-{
- if (m_frameView)
- return m_frameView->pagination().mode != Pagination::Unpaginated;
-
- return RenderBlock::requiresColumns(desiredColumnCount);
-}
-
-void RenderView::calcColumnWidth()
-{
- int columnWidth = contentLogicalWidth();
- if (m_frameView && style()->hasInlineColumnAxis()) {
- if (int pageLength = m_frameView->pagination().pageLength)
- columnWidth = pageLength;
- }
- setDesiredColumnCountAndWidth(1, columnWidth);
-}
-
-ColumnInfo::PaginationUnit RenderView::paginationUnit() const
-{
- if (m_frameView)
- return m_frameView->pagination().behavesLikeColumns ? ColumnInfo::Column : ColumnInfo::Page;
-
- return ColumnInfo::Page;
-}
-
void RenderView::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
// If we ever require layout but receive a paint anyway, something has gone horribly wrong.
ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);
// This avoids painting garbage between columns if there is a column gap.
- if (m_frameView && m_frameView->pagination().mode != Pagination::Unpaginated)
+ if (m_frameView && style()->isOverflowPaged())
paintInfo.context->fillRect(paintInfo.rect, m_frameView->baseBackgroundColor());
paintObject(paintInfo, paintOffset);
}
-static inline bool rendererObscuresBackground(RenderObject* rootObject)
+static inline bool rendererObscuresBackground(RenderBox* rootBox)
{
- if (!rootObject)
- return false;
-
- RenderStyle* style = rootObject->style();
+ ASSERT(rootBox);
+ RenderStyle* style = rootBox->style();
if (style->visibility() != VISIBLE
|| style->opacity() != 1
+ || style->hasFilter()
|| style->hasTransform())
return false;
- if (rootObject->compositingState() == PaintsIntoOwnBacking)
+ if (rootBox->compositingState() == PaintsIntoOwnBacking)
return false;
- const RenderObject* rootRenderer = rootObject->rendererForRootBackground();
+ const RenderObject* rootRenderer = rootBox->rendererForRootBackground();
if (rootRenderer->style()->backgroundClip() == TextFillBox)
return false;
return true;
}
+bool RenderView::rootFillsViewportBackground(RenderBox* rootBox) const
+{
+ ASSERT(rootBox);
+ // CSS Boxes always fill the viewport background (see paintRootBoxFillLayers)
+ if (!rootBox->isSVG())
+ return true;
+
+ return rootBox->frameRect().contains(frameRect());
+}
+
void RenderView::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&)
{
// Check to see if we are enclosed by a layer that requires complex painting rules. If so, we cannot blit
if (paintInfo.skipRootBackground())
return;
- bool rootFillsViewport = false;
- bool rootObscuresBackground = false;
+ bool shouldPaintBackground = true;
Node* documentElement = document().documentElement();
- if (RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0) {
- // The document element's renderer is currently forced to be a block, but may not always be.
- RenderBox* rootBox = rootRenderer->isBox() ? toRenderBox(rootRenderer) : 0;
- rootFillsViewport = rootBox && !rootBox->x() && !rootBox->y() && rootBox->width() >= width() && rootBox->height() >= height();
- rootObscuresBackground = rendererObscuresBackground(rootRenderer);
- }
-
- Page* page = document().page();
- float pageScaleFactor = page ? page->pageScaleFactor() : 1;
+ if (RenderBox* rootBox = documentElement ? toRenderBox(documentElement->renderer()) : 0)
+ shouldPaintBackground = !rootFillsViewportBackground(rootBox) || !rendererObscuresBackground(rootBox);
// If painting will entirely fill the view, no need to fill the background.
- if (rootFillsViewport && rootObscuresBackground && pageScaleFactor >= 1)
+ if (!shouldPaintBackground)
return;
// This code typically only executes if the root element's visibility has been set to hidden,
}
}
-void RenderView::repaintRectangleInViewAndCompositedLayers(const LayoutRect& ur)
-{
- if (!shouldRepaint(ur))
- return;
-
- repaintViewRectangle(ur);
-
- if (compositor()->inCompositingMode()) {
- IntRect repaintRect = pixelSnappedIntRect(ur);
- compositor()->repaintCompositedLayers(&repaintRect);
- }
-}
-
void RenderView::repaintViewAndCompositedLayers()
{
repaint();
+ // The only way we know how to hit these ASSERTS below this point is via the Chromium OS login screen.
+ DisableCompositingQueryAsserts disabler;
+
if (compositor()->inCompositingMode())
compositor()->repaintCompositedLayers();
}
selectedObjects.set(os, adoptPtr(new RenderSelectionInfo(os, clipToVisibleContent)));
RenderBlock* cb = os->containingBlock();
while (cb && !cb->isRenderView()) {
- OwnPtr<RenderSelectionInfo>& blockInfo = selectedObjects.add(cb, nullptr).iterator->value;
+ OwnPtr<RenderSelectionInfo>& blockInfo = selectedObjects.add(cb, nullptr).storedValue->value;
if (blockInfo)
break;
blockInfo = adoptPtr(new RenderSelectionInfo(cb, clipToVisibleContent));
}
}
-// Compositing layer dimensions take outline size into account, so we have to recompute layer
-// bounds when it changes.
-// FIXME: This is ugly; it would be nice to have a better way to do this.
-void RenderView::setMaximalOutlineSize(int o)
-{
- if (o != m_maximalOutlineSize) {
- m_maximalOutlineSize = o;
-
- // maximalOutlineSize affects compositing layer dimensions.
- compositor()->setCompositingLayersNeedRebuild(); // FIXME: this really just needs to be a geometry update.
- }
-}
-
// When exploring the RenderTree looking for the nodes involved in the Selection, sometimes it's
// required to change the traversing direction because the "start" position is below the "end" one.
static inline RenderObject* getNextOrPrevRenderObjectBasedOnDirection(const RenderObject* o, const RenderObject* stop, bool& continueExploring, bool& exploringBackwards)
void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode blockRepaintMode)
{
+ // This code makes no assumptions as to if the rendering tree is up to date or not
+ // and will not try to update it. Currently clearSelection calls this
+ // (intentionally) without updating the rendering tree as it doesn't care.
+ // Other callers may want to force recalc style before calling this.
+
// Make sure both our start and end objects are defined.
// Check www.msnbc.com and try clicking around to find the case where this happened.
if ((start && !end) || (end && !start))
if (blockRepaintMode == RepaintNewXOROld) {
RenderBlock* cb = os->containingBlock();
while (cb && !cb->isRenderView()) {
- OwnPtr<RenderBlockSelectionInfo>& blockInfo = oldSelectedBlocks.add(cb, nullptr).iterator->value;
+ OwnPtr<RenderBlockSelectionInfo>& blockInfo = oldSelectedBlocks.add(cb, nullptr).storedValue->value;
if (blockInfo)
break;
blockInfo = adoptPtr(new RenderBlockSelectionInfo(cb));
newSelectedObjects.set(o, adoptPtr(new RenderSelectionInfo(o, true)));
RenderBlock* cb = o->containingBlock();
while (cb && !cb->isRenderView()) {
- OwnPtr<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(cb, nullptr).iterator->value;
+ OwnPtr<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(cb, nullptr).storedValue->value;
if (blockInfo)
break;
blockInfo = adoptPtr(new RenderBlockSelectionInfo(cb));
if (!m_frameView || blockRepaintMode == RepaintNothing)
return;
- FrameView::DeferredRepaintScope deferRepaints(*m_frameView);
-
// Have any of the old selected objects changed compared to the new selection?
for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i) {
RenderObject* obj = i->key;
endPos = m_selectionEndPos;
}
-void RenderView::updateConfiguration()
-{
- m_configuration.update(document());
-}
-
bool RenderView::shouldUsePrintingLayout() const
{
if (!document().printing() || !m_frameView)
return m_frameView->frame().shouldUsePrintingLayout();
}
-size_t RenderView::getRetainedWidgets(Vector<RenderWidget*>& renderWidgets)
-{
- size_t size = m_widgets.size();
-
- renderWidgets.reserveCapacity(size);
-
- RenderWidgetSet::const_iterator end = m_widgets.end();
- for (RenderWidgetSet::const_iterator it = m_widgets.begin(); it != end; ++it) {
- renderWidgets.uncheckedAppend(*it);
- (*it)->ref();
- }
-
- return size;
-}
-
-void RenderView::releaseWidgets(Vector<RenderWidget*>& renderWidgets)
-{
- size_t size = renderWidgets.size();
-
- for (size_t i = 0; i < size; ++i)
- renderWidgets[i]->deref();
-}
-
-void RenderView::updateWidgetPositions()
-{
- // updateWidgetPosition() can possibly cause layout to be re-entered (via plug-ins running
- // scripts in response to NPP_SetWindow, for example), so we need to keep the Widgets
- // alive during enumeration.
-
- Vector<RenderWidget*> renderWidgets;
- size_t size = getRetainedWidgets(renderWidgets);
-
- for (size_t i = 0; i < size; ++i)
- renderWidgets[i]->updateWidgetPosition();
-
- for (size_t i = 0; i < size; ++i)
- renderWidgets[i]->widgetPositionsUpdated();
-
- releaseWidgets(renderWidgets);
-}
-
-void RenderView::addWidget(RenderWidget* o)
-{
- m_widgets.add(o);
-}
-
-void RenderView::removeWidget(RenderWidget* o)
-{
- m_widgets.remove(o);
-}
-
LayoutRect RenderView::viewRect() const
{
if (shouldUsePrintingLayout())
return IntRect(overflowRect);
}
-int RenderView::viewHeight(ScrollableArea::IncludeScrollbarsInRect scrollbarInclusion) const
+int RenderView::viewHeight(IncludeScrollbarsInRect scrollbarInclusion) const
{
int height = 0;
if (!shouldUsePrintingLayout() && m_frameView)
return height;
}
-int RenderView::viewWidth(ScrollableArea::IncludeScrollbarsInRect scrollbarInclusion) const
+int RenderView::viewWidth(IncludeScrollbarsInRect scrollbarInclusion) const
{
int width = 0;
if (!shouldUsePrintingLayout() && m_frameView)
return width;
}
-int RenderView::viewLogicalHeight(ScrollableArea::IncludeScrollbarsInRect scrollbarInclusion) const
+int RenderView::viewLogicalHeight() const
{
- int height = style()->isHorizontalWritingMode() ? viewHeight(scrollbarInclusion) : viewWidth(scrollbarInclusion);
-
- if (hasColumns() && !style()->hasInlineColumnAxis()) {
- if (int pageLength = m_frameView->pagination().pageLength)
- height = pageLength;
- }
-
- return height;
+ return style()->isHorizontalWritingMode() ? viewHeight(ExcludeScrollbars) : viewWidth(ExcludeScrollbars);
}
float RenderView::zoomFactor() const
return m_frameView->frame().pageZoomFactor();
}
-void RenderView::pushLayoutState(RenderObject* root)
+void RenderView::pushLayoutState(RenderObject& root)
{
ASSERT(m_layoutStateDisableCount == 0);
ASSERT(m_layoutState == 0);
m_layoutState = new LayoutState(root);
}
-bool RenderView::shouldDisableLayoutStateForSubtree(RenderObject* renderer) const
+bool RenderView::shouldDisableLayoutStateForSubtree(RenderObject& renderer) const
{
- RenderObject* o = renderer;
+ RenderObject* o = &renderer;
while (o) {
- if (o->hasColumns() || o->hasTransform() || o->hasReflection())
+ if (o->shouldDisableLayoutState())
return true;
o = o->container();
}
RenderLayerCompositor* RenderView::compositor()
{
if (!m_compositor)
- m_compositor = adoptPtr(new RenderLayerCompositor(this));
+ m_compositor = adoptPtr(new RenderLayerCompositor(*this));
return m_compositor.get();
}
m_compositor->setIsInWindow(isInWindow);
}
-CustomFilterGlobalContext* RenderView::customFilterGlobalContext()
-{
- if (!m_customFilterGlobalContext)
- m_customFilterGlobalContext = adoptPtr(new CustomFilterGlobalContext());
- return m_customFilterGlobalContext.get();
-}
-
-void RenderView::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
-{
- RenderBlock::styleDidChange(diff, oldStyle);
- if (hasRenderNamedFlowThreads())
- flowThreadController()->styleDidChange();
-}
-
-bool RenderView::hasRenderNamedFlowThreads() const
-{
- return m_flowThreadController && m_flowThreadController->hasRenderNamedFlowThreads();
-}
-
-bool RenderView::checkTwoPassLayoutForAutoHeightRegions() const
-{
- return hasRenderNamedFlowThreads() && m_flowThreadController->hasFlowThreadsWithAutoLogicalHeightRegions();
-}
-
FlowThreadController* RenderView::flowThreadController()
{
if (!m_flowThreadController)
- m_flowThreadController = FlowThreadController::create(this);
+ m_flowThreadController = FlowThreadController::create();
return m_flowThreadController.get();
}
-void RenderView::pushLayoutStateForCurrentFlowThread(const RenderObject* object)
+void RenderView::pushLayoutStateForCurrentFlowThread(const RenderObject& object)
{
if (!m_flowThreadController)
return;
bool RenderView::backgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const
{
// FIXME: Remove this main frame check. Same concept applies to subframes too.
- Page* page = document().page();
- Frame* mainFrame = page ? page->mainFrame() : 0;
- if (!m_frameView || &m_frameView->frame() != mainFrame)
+ if (!m_frameView || !m_frameView->isMainFrame())
return false;
return m_frameView->hasOpaqueBackground();
}
-LayoutUnit RenderView::viewportPercentageWidth(float percentage) const
-{
- return viewLogicalWidth(ScrollableArea::IncludeScrollbars) * percentage / 100.f;
-}
-
-LayoutUnit RenderView::viewportPercentageHeight(float percentage) const
-{
- return viewLogicalHeight(ScrollableArea::IncludeScrollbars) * percentage / 100.f;
-}
-
-LayoutUnit RenderView::viewportPercentageMin(float percentage) const
+double RenderView::layoutViewportWidth() const
{
- return std::min(viewLogicalWidth(ScrollableArea::IncludeScrollbars), viewLogicalHeight(ScrollableArea::IncludeScrollbars))
- * percentage / 100.f;
+ float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1;
+ return viewWidth(IncludeScrollbars) / scale;
}
-LayoutUnit RenderView::viewportPercentageMax(float percentage) const
+double RenderView::layoutViewportHeight() const
{
- return std::max(viewLogicalWidth(ScrollableArea::IncludeScrollbars), viewLogicalHeight(ScrollableArea::IncludeScrollbars))
- * percentage / 100.f;
-}
-
-FragmentationDisabler::FragmentationDisabler(RenderObject* root)
-{
- RenderView* renderView = root->view();
- ASSERT(renderView);
-
- LayoutState* layoutState = renderView->layoutState();
-
- m_root = root;
- m_fragmenting = layoutState && layoutState->isPaginated();
- m_flowThreadState = m_root->flowThreadState();
-#ifndef NDEBUG
- m_layoutState = layoutState;
-#endif
-
- if (layoutState)
- layoutState->m_isPaginated = false;
-
- if (m_flowThreadState != RenderObject::NotInsideFlowThread)
- m_root->setFlowThreadStateIncludingDescendants(RenderObject::NotInsideFlowThread);
-}
-
-FragmentationDisabler::~FragmentationDisabler()
-{
- RenderView* renderView = m_root->view();
- ASSERT(renderView);
-
- LayoutState* layoutState = renderView->layoutState();
-#ifndef NDEBUG
- ASSERT(m_layoutState == layoutState);
-#endif
-
- if (layoutState)
- layoutState->m_isPaginated = m_fragmenting;
-
- if (m_flowThreadState != RenderObject::NotInsideFlowThread)
- m_root->setFlowThreadStateIncludingDescendants(m_flowThreadState);
+ float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1;
+ return viewHeight(IncludeScrollbars) / scale;
}
} // namespace WebCore