Commit db00ad98 authored by hyatt@apple.com's avatar hyatt@apple.com
Browse files

Make full page zoom vaguely work. This patch uses the CSS transform...

        Make full page zoom vaguely work.  This patch uses the CSS transform system to turn on full page zoom at the
        document level.  There are many many bugs that I'm going to file to track all the issues (most of the issues
        are just bugs with transforms themselves).

        Reviewed by Adam Roben

        * css/CSSStyleSelector.cpp:
        (WebCore::CSSStyleSelector::applyProperty):
        (WebCore::CSSStyleSelector::getComputedSizeFromSpecifiedSize):
        * dom/Document.cpp:
        (WebCore::Document::recalcStyle):
        * page/Frame.cpp:
        (WebCore::Frame::shouldApplyTextZoom):
        (WebCore::Frame::shouldApplyPageZoom):
        * page/Frame.h:
        * rendering/RenderLayer.cpp:
        (WebCore::RenderLayer::updateLayerPositions):
        (WebCore::RenderLayer::setHasVisibleContent):
        (WebCore::RenderLayer::paintLayer):
        (WebCore::RenderLayer::hitTestLayer):
        * rendering/RenderLayer.h:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@31007 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 61eb36ed
2008-03-12 David Hyatt <hyatt@apple.com>
Make full page zoom vaguely work. This patch uses the CSS transform system to turn on full page zoom at the
document level. There are many many bugs that I'm going to file to track all the issues (most of the issues
are just bugs with transforms themselves).
Reviewed by Adam Roben
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::applyProperty):
(WebCore::CSSStyleSelector::getComputedSizeFromSpecifiedSize):
* dom/Document.cpp:
(WebCore::Document::recalcStyle):
* page/Frame.cpp:
(WebCore::Frame::shouldApplyTextZoom):
(WebCore::Frame::shouldApplyPageZoom):
* page/Frame.h:
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::updateLayerPositions):
(WebCore::RenderLayer::setHasVisibleContent):
(WebCore::RenderLayer::paintLayer):
(WebCore::RenderLayer::hitTestLayer):
* rendering/RenderLayer.h:
2008-03-12 David Hyatt <hyatt@apple.com>
 
Make the zoom factor a float and not a percent.
......@@ -3265,7 +3265,8 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
double multiplier = 1.0;
// Scale for the font zoom factor only for types other than "em" and "ex", since those are
// already based on the font size.
if (type != CSSPrimitiveValue::CSS_EMS && type != CSSPrimitiveValue::CSS_EXS && m_style->textSizeAdjust() && m_document->frame()) {
if (type != CSSPrimitiveValue::CSS_EMS && type != CSSPrimitiveValue::CSS_EXS && m_style->textSizeAdjust() &&
m_document->frame() && m_document->frame()->shouldApplyTextZoom()) {
multiplier = m_document->frame()->zoomFactor();
}
lineHeight = Length(primitiveValue->computeLengthIntForLength(m_style, multiplier), Fixed);
......@@ -4885,7 +4886,7 @@ float CSSStyleSelector::getComputedSizeFromSpecifiedSize(bool isAbsoluteSize, fl
int minSize = settings->minimumFontSize();
int minLogicalSize = settings->minimumLogicalFontSize();
float zoomPercent = m_document->frame() ? m_document->frame()->zoomFactor() : 1.0f;
float zoomPercent = m_document->frame() && m_document->frame()->shouldApplyTextZoom() ? m_document->frame()->zoomFactor() : 1.0f;
float zoomedSize = specifiedSize * zoomPercent;
// Apply the hard minimum first. We only apply the hard minimum if after zooming we're still too small.
......
......@@ -1078,6 +1078,24 @@ void Document::recalcStyle(StyleChange change)
_style->ref();
_style->setDisplay(BLOCK);
_style->setVisuallyOrdered(visuallyOrdered);
if (frame() && frame()->shouldApplyPageZoom()) {
// 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).
// We can remove it when those bugs are resolved.
if (oldStyle && oldStyle->transform() != _style->transform())
renderer()->repaint();
// ### make the font stuff _really_ work!!!!
FontDescription fontDescription;
......
......@@ -649,6 +649,24 @@ bool Frame::isZoomFactorTextOnly() const
return d->m_zoomFactorIsTextOnly;
}
bool Frame::shouldApplyTextZoom() const
{
if (d->m_zoomFactor == 1.0f || !d->m_zoomFactorIsTextOnly)
return false;
if (d->m_doc && d->m_doc->isSVGDocument())
return false;
return true;
}
bool Frame::shouldApplyPageZoom() const
{
if (d->m_zoomFactor == 1.0f || d->m_zoomFactorIsTextOnly)
return false;
if (d->m_doc && d->m_doc->isSVGDocument())
return false;
return true;
}
void Frame::setZoomFactor(float percent, bool isTextOnly)
{
if (d->m_zoomFactor == percent && d->m_zoomFactorIsTextOnly == isTextOnly)
......
......@@ -204,6 +204,8 @@ public:
void setZoomFactor(float scale, bool isTextOnly);
float zoomFactor() const;
bool isZoomFactorTextOnly() const;
bool shouldApplyTextZoom() const;
bool shouldApplyPageZoom() const;
bool prohibitsScrolling() const;
void setProhibitsScrolling(const bool);
......
......@@ -206,8 +206,8 @@ void RenderLayer::updateLayerPositions(bool doFullRepaint, bool checkForRepaint)
// from updateScrollInfoAfterLayout().
ASSERT(!view->layoutState());
IntRect newRect = m_object->absoluteClippedOverflowRect();
IntRect newOutlineBox = m_object->absoluteOutlineBox();
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.
if (checkForRepaint) {
if (view && !view->printing()) {
if (m_needsFullRepaint) {
......@@ -259,8 +259,8 @@ void RenderLayer::setHasVisibleContent(bool b)
m_visibleContentStatusDirty = false;
m_hasVisibleContent = b;
if (m_hasVisibleContent) {
m_repaintRect = renderer()->absoluteClippedOverflowRect();
m_outlineBox = renderer()->absoluteOutlineBox();
m_repaintRect = renderer()->absoluteClippedOverflowRect(); // FIXME: This does not work correctly with transforms.
m_outlineBox = renderer()->absoluteOutlineBox(); // FIXME: This does not work correctly with transforms.
if (!isOverflowOnly()) {
if (RenderLayer* sc = stackingContext())
sc->dirtyZOrderLists();
......@@ -1462,7 +1462,7 @@ static void restoreClip(GraphicsContext* p, const IntRect& paintDirtyRect, const
void
RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
const IntRect& paintDirtyRect, bool haveTransparency, PaintRestriction paintRestriction,
RenderObject *paintingRoot)
RenderObject* paintingRoot, bool appliedTransform)
{
// Avoid painting layers when stylesheets haven't loaded. This eliminates FOUC.
// It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
......@@ -1478,7 +1478,7 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
haveTransparency = true;
// Apply a transform if we have one.
if (m_transform && rootLayer != this) {
if (m_transform && !appliedTransform) {
// If the transform can't be inverted, then don't paint anything.
if (!m_transform->isInvertible())
return;
......@@ -1489,10 +1489,13 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
parent()->beginTransparencyLayers(p, rootLayer);
// Make sure the parent's clip rects have been calculated.
parent()->calculateClipRects(rootLayer);
IntRect clipRect = parent()->clipRects()->overflowClipRect();
clipRect.intersect(paintDirtyRect);
IntRect clipRect = paintDirtyRect;
if (parent()) {
parent()->calculateClipRects(rootLayer);
clipRect = parent()->clipRects()->overflowClipRect();
clipRect.intersect(paintDirtyRect);
}
// Push the parent coordinate space's clip.
setClip(p, paintDirtyRect, clipRect);
......@@ -1510,7 +1513,7 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
p->concatCTM(transform);
// Now do a paint with the root layer shifted to be us.
paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), haveTransparency, paintRestriction, paintingRoot);
paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), haveTransparency, paintRestriction, paintingRoot, true);
p->restore();
......@@ -1669,21 +1672,24 @@ Node* RenderLayer::enclosingElement() const
return 0;
}
RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result, const IntRect& hitTestRect, const IntPoint& hitTestPoint)
RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
const IntRect& hitTestRect, const IntPoint& hitTestPoint, bool appliedTransform)
{
// Apply a transform if we have one.
if (m_transform && rootLayer != this) {
if (m_transform && !appliedTransform) {
// If the transform can't be inverted, then don't hit test this layer at all.
if (!m_transform->isInvertible())
return 0;
// Make sure the parent's clip rects have been calculated.
parent()->calculateClipRects(rootLayer);
if (parent()) {
parent()->calculateClipRects(rootLayer);
// Go ahead and test the enclosing clip now.
IntRect clipRect = parent()->clipRects()->overflowClipRect();
if (!clipRect.contains(hitTestPoint))
return 0;
// Go ahead and test the enclosing clip now.
IntRect clipRect = parent()->clipRects()->overflowClipRect();
if (!clipRect.contains(hitTestPoint))
return 0;
}
// Adjust the transform such that the renderer's upper left corner is at (0,0) in user space.
// This involves subtracting out the position of the layer in our current coordinate space.
......@@ -1695,7 +1701,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, const HitTestRequ
transform = *m_transform * transform;
// Map the hit test point into the transformed space and then do a hit test with the root layer shifted to be us.
return hitTestLayer(this, request, result, transform.inverse().mapRect(hitTestRect), transform.inverse().mapPoint(hitTestPoint));
return hitTestLayer(this, request, result, transform.inverse().mapRect(hitTestRect), transform.inverse().mapPoint(hitTestPoint), true);
}
// Calculate the clip rects we should use.
......
......@@ -374,8 +374,8 @@ private:
void collectLayers(Vector<RenderLayer*>*&, Vector<RenderLayer*>*&);
void paintLayer(RenderLayer* rootLayer, GraphicsContext*, const IntRect& paintDirtyRect,
bool haveTransparency, PaintRestriction, RenderObject* paintingRoot);
RenderLayer* hitTestLayer(RenderLayer* rootLayer, const HitTestRequest&, HitTestResult&, const IntRect& hitTestRect, const IntPoint& hitTestPoint);
bool haveTransparency, PaintRestriction, RenderObject* paintingRoot, bool appliedTransform = false);
RenderLayer* hitTestLayer(RenderLayer* rootLayer, const HitTestRequest&, HitTestResult&, const IntRect& hitTestRect, const IntPoint& hitTestPoint, bool appliedTransform = false);
void computeScrollDimensions(bool* needHBar = 0, bool* needVBar = 0);
bool shouldBeOverflowOnly() const;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment