Skip to content

Commit

Permalink
This patch makes full page zoom work pretty well. It fixes repaintin…
Browse files Browse the repository at this point in the history
…g so that it works when transforms

        are set on the RenderView. It also implements the "smart layout" behavior that other browsers support when
        zooming. The page will still try to constrain to the viewport size even when zoomed.

        Reviewed by john

        * dom/Document.cpp:
        (WebCore::Document::recalcStyle):
        Make sure to test for transform changes even when there is no zoom.  This fixes repainting issues
        caused by jumping from a zoomed state back to the standard size.

        * page/FrameView.cpp:
        (WebCore::FrameView::adjustViewSize):
        Adjust for the zoom factor (the render tree is in unzoomed coordinates, but the scrollbars of the view
        need to handle zoomed coordinates).

        * rendering/RenderBox.cpp:
        (WebCore::RenderBox::calcHeight):
        Fix the body-sizing-to-the-view-height quirk so that it takes the zoom factor into account when
        stretching to fill the viewport.

        * rendering/RenderLayer.cpp:
        (WebCore::RenderLayer::updateLayerPositions):
        (WebCore::RenderLayer::setHasVisibleContent):
        Remove the FIXMEs now that absoluteClippedOverflowRect works with transforms on the RenderView.

        * rendering/RenderView.cpp:
        (WebCore::RenderView::calcHeight):
        (WebCore::RenderView::calcWidth):
        Make sure the calculated width/height take the zoom factor into account in order to get the "smart layout"
        behavior.

        (WebCore::RenderView::layout):
        When deciding whether children have to get a relayout, we need to check the zoomed width/height and not just
        the viewport size.

        (WebCore::RenderView::computeAbsoluteRepaintRect):
        Patched to take into account transforms set on the RenderView.

        (WebCore::RenderView::docHeight):
        (WebCore::RenderView::docWidth):
        Patched to just always use m_width and m_height initially, since those have already been adjusted for
        the zoom factor.

        (WebCore::RenderView::zoomedHeight):
        (WebCore::RenderView::zoomedWidth):
        * rendering/RenderView.h:
        New helper methods for obtaining the adjusted width/height of the viewport taking into account the
        zoom factor.



Canonical link: https://commits.webkit.org/24720@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@31037 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
David Hyatt committed Mar 13, 2008
1 parent 7187613 commit ab0deb3
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 33 deletions.
52 changes: 52 additions & 0 deletions WebCore/ChangeLog
@@ -1,3 +1,55 @@
2008-03-13 David Hyatt <hyatt@apple.com>

This patch makes full page zoom work pretty well. It fixes repainting so that it works when transforms
are set on the RenderView. It also implements the "smart layout" behavior that other browsers support when
zooming. The page will still try to constrain to the viewport size even when zoomed.

Reviewed by john

* dom/Document.cpp:
(WebCore::Document::recalcStyle):
Make sure to test for transform changes even when there is no zoom. This fixes repainting issues
caused by jumping from a zoomed state back to the standard size.

* page/FrameView.cpp:
(WebCore::FrameView::adjustViewSize):
Adjust for the zoom factor (the render tree is in unzoomed coordinates, but the scrollbars of the view
need to handle zoomed coordinates).

* rendering/RenderBox.cpp:
(WebCore::RenderBox::calcHeight):
Fix the body-sizing-to-the-view-height quirk so that it takes the zoom factor into account when
stretching to fill the viewport.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::updateLayerPositions):
(WebCore::RenderLayer::setHasVisibleContent):
Remove the FIXMEs now that absoluteClippedOverflowRect works with transforms on the RenderView.

* rendering/RenderView.cpp:
(WebCore::RenderView::calcHeight):
(WebCore::RenderView::calcWidth):
Make sure the calculated width/height take the zoom factor into account in order to get the "smart layout"
behavior.

(WebCore::RenderView::layout):
When deciding whether children have to get a relayout, we need to check the zoomed width/height and not just
the viewport size.

(WebCore::RenderView::computeAbsoluteRepaintRect):
Patched to take into account transforms set on the RenderView.

(WebCore::RenderView::docHeight):
(WebCore::RenderView::docWidth):
Patched to just always use m_width and m_height initially, since those have already been adjusted for
the zoom factor.

(WebCore::RenderView::zoomedHeight):
(WebCore::RenderView::zoomedWidth):
* rendering/RenderView.h:
New helper methods for obtaining the adjusted width/height of the viewport taking into account the
zoom factor.

2008-03-13 Anders Carlsson <andersca@apple.com>

Build fix.
Expand Down
12 changes: 5 additions & 7 deletions WebCore/dom/Document.cpp
Expand Up @@ -1079,24 +1079,22 @@ void Document::recalcStyle(StyleChange change)
_style->setDisplay(BLOCK);
_style->setVisuallyOrdered(visuallyOrdered);

if (frame() && frame()->shouldApplyPageZoom()) {
if (frame() && frame()->shouldApplyPageZoom() && !ownerElement()) {
// Set up our zoom transform on the document.
_style->setTransformOriginX(Length(0, Fixed));
_style->setTransformOriginY(Length(0, Fixed));
TransformOperations ops;
RefPtr<TransformOperation> transformOp = new ScaleTransformOperation(frame()->zoomFactor(), frame()->zoomFactor());
ops.append(transformOp);
_style->setTransform(ops);
setChanged(); // Necessary to force the view to relayout.
}

// FIXME: This code is necessary because RenderLayer is buggy regarding transform repainting (because it uses
// absoluteClippedOverflowRect).
// FIXME: This code is necessary because RenderLayer is buggy regarding transform repainting on the root (not sure why).
// We can remove it when those bugs are resolved.
if (oldStyle && oldStyle->transform() != _style->transform())
if (oldStyle && oldStyle->transform() != _style->transform()) {
setChanged(); // Necessary to force the view to relayout.
renderer()->repaint();

// ### make the font stuff _really_ work!!!!
}

FontDescription fontDescription;
fontDescription.setUsePrinterFont(printing());
Expand Down
10 changes: 9 additions & 1 deletion WebCore/page/FrameView.cpp
Expand Up @@ -254,7 +254,15 @@ void FrameView::adjustViewSize()
RenderView* root = static_cast<RenderView*>(m_frame->renderer());
if (!root)
return;
resizeContents(root->overflowWidth(), root->overflowHeight());

// Adjust for the zoom factor. The RenderView is scaled by the zoom, but our viewport is not.
int width = root->overflowWidth();
int height = root->overflowHeight();
if (m_frame->shouldApplyPageZoom()) {
width *= m_frame->zoomFactor(); // FIXME: Will have rounding errors.
height *= m_frame->zoomFactor(); // FIXME: Will have rounding errors.
}
resizeContents(width, height);
}

void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, ScrollbarMode& vMode)
Expand Down
4 changes: 2 additions & 2 deletions WebCore/rendering/RenderBox.cpp
Expand Up @@ -1315,9 +1315,9 @@ void RenderBox::calcHeight()
// WinIE quirk: The <html> block always fills the entire canvas in quirks mode. The <body> always fills the
// <html> block in quirks mode. Only apply this quirk if the block is normal flow and no height
// is specified.
if (stretchesToViewHeight()) {
if (stretchesToViewHeight() && !document()->printing()) {
int margins = collapsedMarginTop() + collapsedMarginBottom();
int visHeight = view()->frameView()->visibleHeight();
int visHeight = view()->zoomedHeight();
if (isRoot())
m_height = max(m_height, visHeight - margins);
else {
Expand Down
5 changes: 2 additions & 3 deletions WebCore/rendering/RenderFrameSet.cpp
Expand Up @@ -459,9 +459,8 @@ void RenderFrameSet::layout()
oldBounds = absoluteClippedOverflowRect();

if (!parent()->isFrameSet()) {
FrameView* v = view()->frameView();
m_width = v->visibleWidth();
m_height = v->visibleHeight();
m_width = view()->zoomedWidth();
m_height = view()->zoomedHeight();
}

size_t cols = frameSet()->totalCols();
Expand Down
8 changes: 4 additions & 4 deletions WebCore/rendering/RenderLayer.cpp
Expand Up @@ -206,8 +206,8 @@ void RenderLayer::updateLayerPositions(bool doFullRepaint, bool checkForRepaint)
// from updateScrollInfoAfterLayout().
ASSERT(!view->layoutState());

IntRect newRect = m_object->absoluteClippedOverflowRect(); // FIXME: This does not work correctly with transforms.
IntRect newOutlineBox = m_object->absoluteOutlineBox(); // FIXME: This does not work correctly with transforms.
IntRect newRect = m_object->absoluteClippedOverflowRect();
IntRect newOutlineBox = m_object->absoluteOutlineBox();
if (checkForRepaint) {
if (view && !view->printing()) {
if (m_needsFullRepaint) {
Expand Down Expand Up @@ -259,8 +259,8 @@ void RenderLayer::setHasVisibleContent(bool b)
m_visibleContentStatusDirty = false;
m_hasVisibleContent = b;
if (m_hasVisibleContent) {
m_repaintRect = renderer()->absoluteClippedOverflowRect(); // FIXME: This does not work correctly with transforms.
m_outlineBox = renderer()->absoluteOutlineBox(); // FIXME: This does not work correctly with transforms.
m_repaintRect = renderer()->absoluteClippedOverflowRect();
m_outlineBox = renderer()->absoluteOutlineBox();
if (!isOverflowOnly()) {
if (RenderLayer* sc = stackingContext())
sc->dirtyZOrderLists();
Expand Down
48 changes: 33 additions & 15 deletions WebCore/rendering/RenderView.cpp
Expand Up @@ -25,6 +25,7 @@

#include "Document.h"
#include "Element.h"
#include "Frame.h"
#include "FrameView.h"
#include "GraphicsContext.h"
#include "RenderLayer.h"
Expand Down Expand Up @@ -72,13 +73,13 @@ RenderView::~RenderView()
void RenderView::calcHeight()
{
if (!printing() && m_frameView)
m_height = m_frameView->visibleHeight();
m_height = zoomedHeight();
}

void RenderView::calcWidth()
{
if (!printing() && m_frameView)
m_width = m_frameView->visibleWidth();
m_width = zoomedWidth();
m_marginLeft = 0;
m_marginRight = 0;
}
Expand All @@ -97,7 +98,8 @@ void RenderView::layout()
if (printing())
m_minPrefWidth = m_maxPrefWidth = m_width;

bool relayoutChildren = !printing() && (!m_frameView || m_width != m_frameView->visibleWidth() || m_height != m_frameView->visibleHeight());
// Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account.
bool relayoutChildren = !printing() && (!m_frameView || m_width != zoomedWidth() || m_height != zoomedHeight());
if (relayoutChildren)
setChildNeedsLayout(true, false);

Expand Down Expand Up @@ -212,6 +214,10 @@ void RenderView::computeAbsoluteRepaintRect(IntRect& rect, bool fixed)

if (fixed && m_frameView)
rect.move(m_frameView->contentsX(), m_frameView->contentsY());

// Apply our transform if we have one (because of full page zooming).
if (m_layer && m_layer->transform())
rect = m_layer->transform()->mapRect(rect);
}

void RenderView::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool)
Expand Down Expand Up @@ -468,12 +474,7 @@ IntRect RenderView::viewRect() const

int RenderView::docHeight() const
{
int h;
if (printing() || !m_frameView)
h = m_height;
else
h = m_frameView->visibleHeight();

int h = m_height;
int lowestPos = lowestPosition();
if (lowestPos > h)
h = lowestPos;
Expand All @@ -493,12 +494,7 @@ int RenderView::docHeight() const

int RenderView::docWidth() const
{
int w;
if (printing() || !m_frameView)
w = m_width;
else
w = m_frameView->visibleWidth();

int w = m_width;
int rightmostPos = rightmostPosition();
if (rightmostPos > w)
w = rightmostPos;
Expand All @@ -512,6 +508,28 @@ int RenderView::docWidth() const
return w;
}

int RenderView::zoomedHeight() const
{
int height = 0;
if (!printing() && m_frameView) {
height = m_frameView->visibleHeight();
if (m_frameView->frame()->shouldApplyPageZoom())
height /= m_frameView->frame()->zoomFactor(); // FIXME: Will have rounding errors.
}
return height;
}

int RenderView::zoomedWidth() const
{
int width = 0;
if (!printing() && m_frameView) {
width = m_frameView->visibleWidth();
if (m_frameView->frame()->shouldApplyPageZoom())
width /= m_frameView->frame()->zoomFactor(); // FIXME: Will have rounding errors.
}
return width;
}

// The idea here is to take into account what object is moving the pagination point, and
// thus choose the best place to chop it.
void RenderView::setBestTruncatedAt(int y, RenderObject* forRenderer, bool forcedBreak)
Expand Down
6 changes: 5 additions & 1 deletion WebCore/rendering/RenderView.h
Expand Up @@ -44,10 +44,14 @@ class RenderView : public RenderBlock {
virtual void calcHeight();
virtual void calcPrefWidths();
virtual bool absolutePosition(int& xPos, int& yPos, bool fixed = false) const;

int docHeight() const;
int docWidth() const;

// The same as the FrameView's visibleHeight/visibleWidth with the zoom factor applied.
int zoomedHeight() const;
int zoomedWidth() const;

FrameView* frameView() const { return m_frameView; }

virtual bool hasOverhangingFloats() { return false; }
Expand Down

0 comments on commit ab0deb3

Please sign in to comment.