Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(913)

Unified Diff: Source/core/paint/ScrollableAreaPainter.cpp

Issue 776943003: Factor painting code from RenderLayerScrollableArea into ScrollableAreaPainter (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/paint/ScrollableAreaPainter.h ('k') | Source/core/rendering/RenderLayer.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/paint/ScrollableAreaPainter.cpp
diff --git a/Source/core/paint/ScrollableAreaPainter.cpp b/Source/core/paint/ScrollableAreaPainter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..525a5215155b1d60086069f9062a5eb58a62c7ca
--- /dev/null
+++ b/Source/core/paint/ScrollableAreaPainter.cpp
@@ -0,0 +1,181 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/paint/ScrollableAreaPainter.h"
+
+#include "core/page/Page.h"
+#include "core/paint/ScrollbarPainter.h"
+#include "core/rendering/PaintInfo.h"
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/RenderLayerScrollableArea.h"
+#include "core/rendering/RenderView.h"
+#include "platform/graphics/GraphicsContext.h"
+#include "platform/graphics/GraphicsContextStateSaver.h"
+
+namespace blink {
+
+void ScrollableAreaPainter::paintResizer(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect)
+{
+ if (m_renderLayerScrollableArea.box().style()->resize() == RESIZE_NONE)
+ return;
+
+ IntRect absRect = m_renderLayerScrollableArea.resizerCornerRect(m_renderLayerScrollableArea.box().pixelSnappedBorderBoxRect(), ResizerForPointer);
+ absRect.moveBy(paintOffset);
+ if (!absRect.intersects(damageRect))
+ return;
+
+ if (m_renderLayerScrollableArea.resizer()) {
+ ScrollbarPainter::paintIntoRect(m_renderLayerScrollableArea.resizer(), context, paintOffset, absRect);
+ return;
+ }
+
+ drawPlatformResizerImage(context, absRect);
+
+ // Draw a frame around the resizer (1px grey line) if there are any scrollbars present.
+ // Clipping will exclude the right and bottom edges of this frame.
+ if (!m_renderLayerScrollableArea.hasOverlayScrollbars() && m_renderLayerScrollableArea.hasScrollbar()) {
+ GraphicsContextStateSaver stateSaver(*context);
+ context->clip(absRect);
+ IntRect largerCorner = absRect;
+ largerCorner.setSize(IntSize(largerCorner.width() + 1, largerCorner.height() + 1));
+ context->setStrokeColor(Color(217, 217, 217));
+ context->setStrokeThickness(1.0f);
+ context->setFillColor(Color::transparent);
+ context->drawRect(largerCorner);
+ }
+}
+
+void ScrollableAreaPainter::drawPlatformResizerImage(GraphicsContext* context, IntRect resizerCornerRect)
+{
+ float deviceScaleFactor = blink::deviceScaleFactor(m_renderLayerScrollableArea.box().frame());
+
+ RefPtr<Image> resizeCornerImage;
+ IntSize cornerResizerSize;
+ if (deviceScaleFactor >= 2) {
+ DEFINE_STATIC_REF(Image, resizeCornerImageHiRes, (Image::loadPlatformResource("textAreaResizeCorner@2x")));
+ resizeCornerImage = resizeCornerImageHiRes;
+ cornerResizerSize = resizeCornerImage->size();
+ cornerResizerSize.scale(0.5f);
+ } else {
+ DEFINE_STATIC_REF(Image, resizeCornerImageLoRes, (Image::loadPlatformResource("textAreaResizeCorner")));
+ resizeCornerImage = resizeCornerImageLoRes;
+ cornerResizerSize = resizeCornerImage->size();
+ }
+
+ if (m_renderLayerScrollableArea.box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
+ context->save();
+ context->translate(resizerCornerRect.x() + cornerResizerSize.width(), resizerCornerRect.y() + resizerCornerRect.height() - cornerResizerSize.height());
+ context->scale(-1.0, 1.0);
+ context->drawImage(resizeCornerImage.get(), IntRect(IntPoint(), cornerResizerSize));
+ context->restore();
+ return;
+ }
+ IntRect imageRect(resizerCornerRect.maxXMaxYCorner() - cornerResizerSize, cornerResizerSize);
+ context->drawImage(resizeCornerImage.get(), imageRect);
+}
+
+void ScrollableAreaPainter::paintOverflowControls(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect, bool paintingOverlayControls)
+{
+ // Don't do anything if we have no overflow.
+ if (!m_renderLayerScrollableArea.box().hasOverflowClip())
+ return;
+
+ IntPoint adjustedPaintOffset = paintOffset;
+ if (paintingOverlayControls)
+ adjustedPaintOffset = m_renderLayerScrollableArea.cachedOverlayScrollbarOffset();
+
+ // Move the scrollbar widgets if necessary. We normally move and resize widgets during layout,
+ // but sometimes widgets can move without layout occurring (most notably when you scroll a
+ // document that contains fixed positioned elements).
+
+ // FIXME: this code should not be necessary.
+ m_renderLayerScrollableArea.positionOverflowControls(toIntSize(adjustedPaintOffset));
+
+ // Overlay scrollbars paint in a second pass through the layer tree so that they will paint
+ // on top of everything else. If this is the normal painting pass, paintingOverlayControls
+ // will be false, and we should just tell the root layer that there are overlay scrollbars
+ // that need to be painted. That will cause the second pass through the layer tree to run,
+ // and we'll paint the scrollbars then. In the meantime, cache tx and ty so that the
+ // second pass doesn't need to re-enter the RenderTree to get it right.
+ if (m_renderLayerScrollableArea.hasOverlayScrollbars() && !paintingOverlayControls) {
+ m_renderLayerScrollableArea.setCachedOverlayScrollbarOffset(paintOffset);
+ // It's not necessary to do the second pass if the scrollbars paint into layers.
+ if ((m_renderLayerScrollableArea.horizontalScrollbar() && m_renderLayerScrollableArea.layerForHorizontalScrollbar()) || (m_renderLayerScrollableArea.verticalScrollbar() && m_renderLayerScrollableArea.layerForVerticalScrollbar()))
+ return;
+ IntRect localDamgeRect = damageRect;
+ localDamgeRect.moveBy(-paintOffset);
+ if (!overflowControlsIntersectRect(localDamgeRect))
+ return;
+
+ RenderView* renderView = m_renderLayerScrollableArea.box().view();
+
+ RenderLayer* paintingRoot = m_renderLayerScrollableArea.layer()->enclosingLayerWithCompositedLayerMapping(IncludeSelf);
+ if (!paintingRoot)
+ paintingRoot = renderView->layer();
+
+ paintingRoot->setContainsDirtyOverlayScrollbars(true);
+ return;
+ }
+
+ // This check is required to avoid painting custom CSS scrollbars twice.
+ if (paintingOverlayControls && !m_renderLayerScrollableArea.hasOverlayScrollbars())
+ return;
+
+ // Now that we're sure the scrollbars are in the right place, paint them.
+ if (m_renderLayerScrollableArea.horizontalScrollbar() && !m_renderLayerScrollableArea.layerForHorizontalScrollbar())
+ m_renderLayerScrollableArea.horizontalScrollbar()->paint(context, damageRect);
+ if (m_renderLayerScrollableArea.verticalScrollbar() && !m_renderLayerScrollableArea.layerForVerticalScrollbar())
+ m_renderLayerScrollableArea.verticalScrollbar()->paint(context, damageRect);
+
+ if (m_renderLayerScrollableArea.layerForScrollCorner())
+ return;
+
+ // We fill our scroll corner with white if we have a scrollbar that doesn't run all the way up to the
+ // edge of the box.
+ paintScrollCorner(context, adjustedPaintOffset, damageRect);
+
+ // Paint our resizer last, since it sits on top of the scroll corner.
+ paintResizer(context, adjustedPaintOffset, damageRect);
+}
+
+bool ScrollableAreaPainter::overflowControlsIntersectRect(const IntRect& localRect) const
+{
+ const IntRect borderBox = m_renderLayerScrollableArea.box().pixelSnappedBorderBoxRect();
+
+ if (m_renderLayerScrollableArea.rectForHorizontalScrollbar(borderBox).intersects(localRect))
+ return true;
+
+ if (m_renderLayerScrollableArea.rectForVerticalScrollbar(borderBox).intersects(localRect))
+ return true;
+
+ if (m_renderLayerScrollableArea.scrollCornerRect().intersects(localRect))
+ return true;
+
+ if (m_renderLayerScrollableArea.resizerCornerRect(borderBox, ResizerForPointer).intersects(localRect))
+ return true;
+
+ return false;
+}
+
+
+void ScrollableAreaPainter::paintScrollCorner(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect)
+{
+ IntRect absRect = m_renderLayerScrollableArea.scrollCornerRect();
+ absRect.moveBy(paintOffset);
+ if (!absRect.intersects(damageRect))
+ return;
+
+ if (m_renderLayerScrollableArea.scrollCorner()) {
+ ScrollbarPainter::paintIntoRect(m_renderLayerScrollableArea.scrollCorner(), context, paintOffset, absRect);
+ return;
+ }
+
+ // We don't want to paint white if we have overlay scrollbars, since we need
+ // to see what is behind it.
+ if (!m_renderLayerScrollableArea.hasOverlayScrollbars())
+ context->fillRect(absRect, Color::white);
+}
+
+} // namespace blink
« no previous file with comments | « Source/core/paint/ScrollableAreaPainter.h ('k') | Source/core/rendering/RenderLayer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698