Skip to content
Permalink
Browse files
<rdar://problem/9028929> REGRESSION (r75897): Scaling applied twice t…
…o an iframe with a transformed ancestor

Reviewed by Maciej Stachowiak.

Source/WebCore:

Test: fast/frames/iframe-scale-applied-twice.html

* page/FrameView.cpp:
(WebCore::FrameView::create): Set the initial bounds of the view to match the
frame size.
* platform/ScrollView.cpp:
(WebCore::ScrollView::visibleContentRect): Based on bounds, not frame size.
(WebCore::ScrollView::updateScrollbars): Ditto.
(WebCore::ScrollView::setFrameRect): Moved code that really handles bounds size
change to setBoundsSize().
(WebCore::ScrollView::setBoundsSize): Added.
(WebCore::ScrollView::setInitialBoundsSize): Added. Sets the bounds size but does
not update anything.
(WebCore::ScrollView::frameRectsChanged): Based on bounds, not frame size.
(WebCore::ScrollView::scrollbarCornerPresent): Ditto.
* platform/ScrollView.h:
(WebCore::ScrollView::boundsSize): Added this getter.
* platform/Widget.h:
(WebCore::Widget::resize): Set the bounds size to the frame size.
* platform/mac/ScrollbarThemeMac.mm:
(WebCore::ScrollbarThemeMac::paint): Fixed an error in the indirect drawing code
path where the buffer rect was resized to capture only the damaged part, but was
still drawn in the original location.

LayoutTests:

* fast/frames/iframe-scale-applied-twice-expected.txt: Added.
* fast/frames/iframe-scale-applied-twice.html: Added.



Canonical link: https://commits.webkit.org/69099@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@79167 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Dan Bernstein committed Feb 21, 2011
1 parent 1198692 commit 98f38f27808bedf3cbde21e9d33cca7c6deb3e6c
Showing 9 changed files with 100 additions and 26 deletions.
@@ -1,3 +1,12 @@
2011-02-20 Dan Bernstein <mitz@apple.com>

Reviewed by Maciej Stachowiak.

<rdar://problem/9028929> REGRESSION (r75897): Scaling applied twice to an iframe with a transformed ancestor

* fast/frames/iframe-scale-applied-twice-expected.txt: Added.
* fast/frames/iframe-scale-applied-twice.html: Added.

2011-02-20 Ami Fischman <fischman@chromium.org>

Reviewed by Kent Tamura.
@@ -0,0 +1,3 @@
PASS


@@ -0,0 +1,12 @@
<!DOCTYPE HTML>
<p id="result">Test did not run</p>
<div style="-webkit-transform: scale(2);">
<iframe id="target" style="width: 100px; height: 100px; border: none;"></iframe>
</div>
<script>
if (window.layoutTestController)
layoutTestController.dumpAsText();
var target = document.getElementById("target");
document.body.offsetTop;
document.getElementById("result").innerText = target.contentDocument.body.offsetWidth > 100 ? "FAIL" : "PASS";
</script>
@@ -1,3 +1,33 @@
2011-02-20 Dan Bernstein <mitz@apple.com>

Reviewed by Maciej Stachowiak.

<rdar://problem/9028929> REGRESSION (r75897): Scaling applied twice to an iframe with a transformed ancestor

Test: fast/frames/iframe-scale-applied-twice.html

* page/FrameView.cpp:
(WebCore::FrameView::create): Set the initial bounds of the view to match the
frame size.
* platform/ScrollView.cpp:
(WebCore::ScrollView::visibleContentRect): Based on bounds, not frame size.
(WebCore::ScrollView::updateScrollbars): Ditto.
(WebCore::ScrollView::setFrameRect): Moved code that really handles bounds size
change to setBoundsSize().
(WebCore::ScrollView::setBoundsSize): Added.
(WebCore::ScrollView::setInitialBoundsSize): Added. Sets the bounds size but does
not update anything.
(WebCore::ScrollView::frameRectsChanged): Based on bounds, not frame size.
(WebCore::ScrollView::scrollbarCornerPresent): Ditto.
* platform/ScrollView.h:
(WebCore::ScrollView::boundsSize): Added this getter.
* platform/Widget.h:
(WebCore::Widget::resize): Set the bounds size to the frame size.
* platform/mac/ScrollbarThemeMac.mm:
(WebCore::ScrollbarThemeMac::paint): Fixed an error in the indirect drawing code
path where the buffer rect was resized to capture only the damaged part, but was
still drawn in the original location.

2011-02-20 Alexey Proskuryakov <ap@apple.com>

Reviewed by Eric Seidel.
@@ -156,6 +156,7 @@ PassRefPtr<FrameView> FrameView::create(Frame* frame, const IntSize& initialSize
{
RefPtr<FrameView> view = adoptRef(new FrameView(frame));
view->Widget::setFrameRect(IntRect(view->pos(), initialSize));
view->setInitialBoundsSize(initialSize);
view->show();
return view.release();
}
@@ -240,8 +240,8 @@ IntRect ScrollView::visibleContentRect(bool includeScrollbars) const
? horizontalScrollbar()->height() : 0;

return IntRect(IntPoint(m_scrollOffset.width(), m_scrollOffset.height()),
IntSize(max(0, width() - verticalScrollbarWidth),
max(0, height() - horizontalScrollbarHeight)));
IntSize(max(0, m_boundsSize.width() - verticalScrollbarWidth),
max(0, m_boundsSize.height() - horizontalScrollbarHeight)));
}
#endif

@@ -470,7 +470,7 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
bool sendContentResizedNotification = false;

IntSize docSize = contentsSize();
IntSize frameSize = frameRect().size();
IntSize frameSize = m_boundsSize;

if (hScroll == ScrollbarAuto) {
newHasHorizontalScrollbar = docSize.width() > visibleWidth();
@@ -535,8 +535,8 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
int pageStep = max(max<int>(clientWidth * Scrollbar::minFractionToStepWhenPaging(), clientWidth - Scrollbar::maxOverlapBetweenPages()), 1);
IntRect oldRect(m_horizontalScrollbar->frameRect());
IntRect hBarRect = IntRect(0,
height() - m_horizontalScrollbar->height(),
width() - (m_verticalScrollbar ? m_verticalScrollbar->width() : 0),
m_boundsSize.height() - m_horizontalScrollbar->height(),
m_boundsSize.width() - (m_verticalScrollbar ? m_verticalScrollbar->width() : 0),
m_horizontalScrollbar->height());
m_horizontalScrollbar->setFrameRect(hBarRect);
if (!m_scrollbarsSuppressed && oldRect != m_horizontalScrollbar->frameRect())
@@ -555,10 +555,10 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset)
m_verticalScrollbar->setEnabled(contentsHeight() > clientHeight);
int pageStep = max(max<int>(clientHeight * Scrollbar::minFractionToStepWhenPaging(), clientHeight - Scrollbar::maxOverlapBetweenPages()), 1);
IntRect oldRect(m_verticalScrollbar->frameRect());
IntRect vBarRect = IntRect(width() - m_verticalScrollbar->width(),
IntRect vBarRect = IntRect(m_boundsSize.width() - m_verticalScrollbar->width(),
0,
m_verticalScrollbar->width(),
height() - (m_horizontalScrollbar ? m_horizontalScrollbar->height() : 0));
m_boundsSize.height() - (m_horizontalScrollbar ? m_horizontalScrollbar->height() : 0));
m_verticalScrollbar->setFrameRect(vBarRect);
if (!m_scrollbarsSuppressed && oldRect != m_verticalScrollbar->frameRect())
m_verticalScrollbar->invalidate();
@@ -794,19 +794,32 @@ void ScrollView::setFrameRect(const IntRect& newRect)
return;

Widget::setFrameRect(newRect);
}

void ScrollView::setBoundsSize(const IntSize& newSize)
{
if (newSize == m_boundsSize)
return;

Widget::setBoundsSize(newSize);
m_boundsSize = newSize;

if (platformWidget())
return;

if (newRect.width() != oldRect.width() || newRect.height() != oldRect.height()) {
updateScrollbars(m_scrollOffset);
if (!m_useFixedLayout)
contentsResized();
}

updateScrollbars(m_scrollOffset);
if (!m_useFixedLayout)
contentsResized();

frameRectsChanged();
}

void ScrollView::setInitialBoundsSize(const IntSize& newSize)
{
ASSERT(m_boundsSize.isZero());
m_boundsSize = newSize;
}

void ScrollView::frameRectsChanged()
{
if (platformWidget())
@@ -841,18 +854,18 @@ IntRect ScrollView::scrollCornerRect() const
if (ScrollbarTheme::nativeTheme()->usesOverlayScrollbars())
return cornerRect;

if (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) {
if (m_horizontalScrollbar && m_boundsSize.width() - m_horizontalScrollbar->width() > 0) {
cornerRect.unite(IntRect(m_horizontalScrollbar->width(),
height() - m_horizontalScrollbar->height(),
width() - m_horizontalScrollbar->width(),
m_boundsSize.height() - m_horizontalScrollbar->height(),
m_boundsSize.width() - m_horizontalScrollbar->width(),
m_horizontalScrollbar->height()));
}

if (m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0) {
cornerRect.unite(IntRect(width() - m_verticalScrollbar->width(),
if (m_verticalScrollbar && m_boundsSize.height() - m_verticalScrollbar->height() > 0) {
cornerRect.unite(IntRect(m_boundsSize.width() - m_verticalScrollbar->width(),
m_verticalScrollbar->height(),
m_verticalScrollbar->width(),
height() - m_verticalScrollbar->height()));
m_boundsSize.height() - m_verticalScrollbar->height()));
}

return cornerRect;
@@ -1012,8 +1025,8 @@ bool ScrollView::isPointInScrollbarCorner(const IntPoint& windowPoint)

bool ScrollView::scrollbarCornerPresent() const
{
return (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) ||
(m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0);
return (m_horizontalScrollbar && m_boundsSize.width() - m_horizontalScrollbar->width() > 0) ||
(m_verticalScrollbar && m_boundsSize.height() - m_verticalScrollbar->height() > 0);
}

IntRect ScrollView::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& localRect) const
@@ -222,6 +222,7 @@ class ScrollView : public Widget, public ScrollableArea {

// Widget override to update our scrollbars and notify our contents of the resize.
virtual void setFrameRect(const IntRect&);
virtual void setBoundsSize(const IntSize&);

// For platforms that need to hit test scrollbars from within the engine's event handlers (like Win32).
Scrollbar* scrollbarAtPoint(const IntPoint& windowPoint);
@@ -287,6 +288,9 @@ class ScrollView : public Widget, public ScrollableArea {
virtual void contentsResized() = 0;
virtual void visibleContentsResized() = 0;

IntSize boundsSize() const { return m_boundsSize; }
void setInitialBoundsSize(const IntSize&);

// These functions are used to create/destroy scrollbars.
void setHasHorizontalScrollbar(bool);
void setHasVerticalScrollbar(bool);
@@ -356,6 +360,8 @@ class ScrollView : public Widget, public ScrollableArea {
// vertical-rl / rtl YES YES
IntPoint m_scrollOrigin;

IntSize m_boundsSize;

void init();
void destroy();

@@ -157,8 +157,8 @@ class Widget : public RefCounted<Widget> {
virtual IntRect frameRect() const;
IntRect boundsRect() const { return IntRect(0, 0, width(), height()); }

void resize(int w, int h) { setFrameRect(IntRect(x(), y(), w, h)); }
void resize(const IntSize& s) { setFrameRect(IntRect(pos(), s)); }
void resize(int w, int h) { setFrameRect(IntRect(x(), y(), w, h)); setBoundsSize(IntSize(w, h)); }
void resize(const IntSize& s) { setFrameRect(IntRect(pos(), s)); setBoundsSize(s); }
void move(int x, int y) { setFrameRect(IntRect(x, y, width(), height())); }
void move(const IntPoint& p) { setFrameRect(IntRect(p, size())); }

@@ -513,14 +513,14 @@ static int scrollbarPartToHIPressedState(ScrollbarPart part)

IntRect bufferRect(scrollbar->frameRect());
bufferRect.intersect(damageRect);
bufferRect.move(-scrollbar->frameRect().x(), -scrollbar->frameRect().y());

OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(bufferRect.size());
if (!imageBuffer)
return true;


imageBuffer->context()->translate(scrollbar->frameRect().x() - bufferRect.x(), scrollbar->frameRect().y() - bufferRect.y());
HIThemeDrawTrack(&trackInfo, 0, imageBuffer->context()->platformContext(), kHIThemeOrientationNormal);
context->drawImageBuffer(imageBuffer.get(), ColorSpaceDeviceRGB, scrollbar->frameRect().location());
context->drawImageBuffer(imageBuffer.get(), ColorSpaceDeviceRGB, bufferRect.location());
}

return true;

0 comments on commit 98f38f2

Please sign in to comment.