| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
reserved. |
| 3 * | 3 * |
| 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. | 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. |
| 5 * | 5 * |
| 6 * Other contributors: | 6 * Other contributors: |
| 7 * Robert O'Callahan <roc+@cs.cmu.edu> | 7 * Robert O'Callahan <roc+@cs.cmu.edu> |
| 8 * David Baron <dbaron@fas.harvard.edu> | 8 * David Baron <dbaron@fas.harvard.edu> |
| 9 * Christian Biesinger <cbiesinger@web.de> | 9 * Christian Biesinger <cbiesinger@web.de> |
| 10 * Randall Jesup <rjesup@wgate.com> | 10 * Randall Jesup <rjesup@wgate.com> |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 #include "core/editing/FrameSelection.h" | 51 #include "core/editing/FrameSelection.h" |
| 52 #include "core/frame/FrameView.h" | 52 #include "core/frame/FrameView.h" |
| 53 #include "core/frame/LocalFrame.h" | 53 #include "core/frame/LocalFrame.h" |
| 54 #include "core/html/HTMLFrameOwnerElement.h" | 54 #include "core/html/HTMLFrameOwnerElement.h" |
| 55 #include "core/inspector/InspectorInstrumentation.h" | 55 #include "core/inspector/InspectorInstrumentation.h" |
| 56 #include "core/page/Chrome.h" | 56 #include "core/page/Chrome.h" |
| 57 #include "core/page/EventHandler.h" | 57 #include "core/page/EventHandler.h" |
| 58 #include "core/page/FocusController.h" | 58 #include "core/page/FocusController.h" |
| 59 #include "core/page/Page.h" | 59 #include "core/page/Page.h" |
| 60 #include "core/page/scrolling/ScrollingCoordinator.h" | 60 #include "core/page/scrolling/ScrollingCoordinator.h" |
| 61 #include "core/paint/ScrollbarPainter.h" | |
| 62 #include "core/rendering/RenderGeometryMap.h" | 61 #include "core/rendering/RenderGeometryMap.h" |
| 63 #include "core/rendering/RenderScrollbar.h" | 62 #include "core/rendering/RenderScrollbar.h" |
| 64 #include "core/rendering/RenderScrollbarPart.h" | 63 #include "core/rendering/RenderScrollbarPart.h" |
| 65 #include "core/rendering/RenderTheme.h" | 64 #include "core/rendering/RenderTheme.h" |
| 66 #include "core/rendering/RenderView.h" | 65 #include "core/rendering/RenderView.h" |
| 67 #include "core/rendering/compositing/CompositedLayerMapping.h" | 66 #include "core/rendering/compositing/CompositedLayerMapping.h" |
| 68 #include "core/rendering/compositing/RenderLayerCompositor.h" | 67 #include "core/rendering/compositing/RenderLayerCompositor.h" |
| 69 #include "platform/PlatformGestureEvent.h" | 68 #include "platform/PlatformGestureEvent.h" |
| 70 #include "platform/PlatformMouseEvent.h" | 69 #include "platform/PlatformMouseEvent.h" |
| 71 #include "platform/graphics/GraphicsContextStateSaver.h" | 70 #include "platform/graphics/GraphicsContextStateSaver.h" |
| (...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 m_scrollCorner = RenderScrollbarPart::createAnonymous(&box().documen
t()); | 1014 m_scrollCorner = RenderScrollbarPart::createAnonymous(&box().documen
t()); |
| 1016 m_scrollCorner->setParent(&box()); | 1015 m_scrollCorner->setParent(&box()); |
| 1017 } | 1016 } |
| 1018 m_scrollCorner->setStyle(corner.release()); | 1017 m_scrollCorner->setStyle(corner.release()); |
| 1019 } else if (m_scrollCorner) { | 1018 } else if (m_scrollCorner) { |
| 1020 m_scrollCorner->destroy(); | 1019 m_scrollCorner->destroy(); |
| 1021 m_scrollCorner = nullptr; | 1020 m_scrollCorner = nullptr; |
| 1022 } | 1021 } |
| 1023 } | 1022 } |
| 1024 | 1023 |
| 1025 void RenderLayerScrollableArea::paintOverflowControls(GraphicsContext* context,
const IntPoint& paintOffset, const IntRect& damageRect, bool paintingOverlayCont
rols) | |
| 1026 { | |
| 1027 // Don't do anything if we have no overflow. | |
| 1028 if (!box().hasOverflowClip()) | |
| 1029 return; | |
| 1030 | |
| 1031 IntPoint adjustedPaintOffset = paintOffset; | |
| 1032 if (paintingOverlayControls) | |
| 1033 adjustedPaintOffset = m_cachedOverlayScrollbarOffset; | |
| 1034 | |
| 1035 // Move the scrollbar widgets if necessary. We normally move and resize widg
ets during layout, | |
| 1036 // but sometimes widgets can move without layout occurring (most notably whe
n you scroll a | |
| 1037 // document that contains fixed positioned elements). | |
| 1038 positionOverflowControls(toIntSize(adjustedPaintOffset)); | |
| 1039 | |
| 1040 // Overlay scrollbars paint in a second pass through the layer tree so that
they will paint | |
| 1041 // on top of everything else. If this is the normal painting pass, paintingO
verlayControls | |
| 1042 // will be false, and we should just tell the root layer that there are over
lay scrollbars | |
| 1043 // that need to be painted. That will cause the second pass through the laye
r tree to run, | |
| 1044 // and we'll paint the scrollbars then. In the meantime, cache tx and ty so
that the | |
| 1045 // second pass doesn't need to re-enter the RenderTree to get it right. | |
| 1046 if (hasOverlayScrollbars() && !paintingOverlayControls) { | |
| 1047 m_cachedOverlayScrollbarOffset = paintOffset; | |
| 1048 // It's not necessary to do the second pass if the scrollbars paint into
layers. | |
| 1049 if ((m_hBar && layerForHorizontalScrollbar()) || (m_vBar && layerForVert
icalScrollbar())) | |
| 1050 return; | |
| 1051 IntRect localDamgeRect = damageRect; | |
| 1052 localDamgeRect.moveBy(-paintOffset); | |
| 1053 if (!overflowControlsIntersectRect(localDamgeRect)) | |
| 1054 return; | |
| 1055 | |
| 1056 RenderView* renderView = box().view(); | |
| 1057 | |
| 1058 RenderLayer* paintingRoot = layer()->enclosingLayerWithCompositedLayerMa
pping(IncludeSelf); | |
| 1059 if (!paintingRoot) | |
| 1060 paintingRoot = renderView->layer(); | |
| 1061 | |
| 1062 paintingRoot->setContainsDirtyOverlayScrollbars(true); | |
| 1063 return; | |
| 1064 } | |
| 1065 | |
| 1066 // This check is required to avoid painting custom CSS scrollbars twice. | |
| 1067 if (paintingOverlayControls && !hasOverlayScrollbars()) | |
| 1068 return; | |
| 1069 | |
| 1070 // Now that we're sure the scrollbars are in the right place, paint them. | |
| 1071 if (m_hBar && !layerForHorizontalScrollbar()) | |
| 1072 m_hBar->paint(context, damageRect); | |
| 1073 if (m_vBar && !layerForVerticalScrollbar()) | |
| 1074 m_vBar->paint(context, damageRect); | |
| 1075 | |
| 1076 if (layerForScrollCorner()) | |
| 1077 return; | |
| 1078 | |
| 1079 // We fill our scroll corner with white if we have a scrollbar that doesn't
run all the way up to the | |
| 1080 // edge of the box. | |
| 1081 paintScrollCorner(context, adjustedPaintOffset, damageRect); | |
| 1082 | |
| 1083 // Paint our resizer last, since it sits on top of the scroll corner. | |
| 1084 paintResizer(context, adjustedPaintOffset, damageRect); | |
| 1085 } | |
| 1086 | |
| 1087 void RenderLayerScrollableArea::paintScrollCorner(GraphicsContext* context, cons
t IntPoint& paintOffset, const IntRect& damageRect) | |
| 1088 { | |
| 1089 IntRect absRect = scrollCornerRect(); | |
| 1090 absRect.moveBy(paintOffset); | |
| 1091 if (!absRect.intersects(damageRect)) | |
| 1092 return; | |
| 1093 | |
| 1094 if (m_scrollCorner) { | |
| 1095 ScrollbarPainter::paintIntoRect(m_scrollCorner, context, paintOffset, ab
sRect); | |
| 1096 return; | |
| 1097 } | |
| 1098 | |
| 1099 // We don't want to paint white if we have overlay scrollbars, since we need | |
| 1100 // to see what is behind it. | |
| 1101 if (!hasOverlayScrollbars()) | |
| 1102 context->fillRect(absRect, Color::white); | |
| 1103 } | |
| 1104 | |
| 1105 bool RenderLayerScrollableArea::hitTestOverflowControls(HitTestResult& result, c
onst IntPoint& localPoint) | 1024 bool RenderLayerScrollableArea::hitTestOverflowControls(HitTestResult& result, c
onst IntPoint& localPoint) |
| 1106 { | 1025 { |
| 1107 if (!hasScrollbar() && !box().canResize()) | 1026 if (!hasScrollbar() && !box().canResize()) |
| 1108 return false; | 1027 return false; |
| 1109 | 1028 |
| 1110 IntRect resizeControlRect; | 1029 IntRect resizeControlRect; |
| 1111 if (box().style()->resize() != RESIZE_NONE) { | 1030 if (box().style()->resize() != RESIZE_NONE) { |
| 1112 resizeControlRect = resizerCornerRect(box().pixelSnappedBorderBoxRect(),
ResizerForPointer); | 1031 resizeControlRect = resizerCornerRect(box().pixelSnappedBorderBoxRect(),
ResizerForPointer); |
| 1113 if (resizeControlRect.contains(localPoint)) | 1032 if (resizeControlRect.contains(localPoint)) |
| 1114 return true; | 1033 return true; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1163 } | 1082 } |
| 1164 | 1083 |
| 1165 IntRect RenderLayerScrollableArea::scrollCornerAndResizerRect() const | 1084 IntRect RenderLayerScrollableArea::scrollCornerAndResizerRect() const |
| 1166 { | 1085 { |
| 1167 IntRect scrollCornerAndResizer = scrollCornerRect(); | 1086 IntRect scrollCornerAndResizer = scrollCornerRect(); |
| 1168 if (scrollCornerAndResizer.isEmpty()) | 1087 if (scrollCornerAndResizer.isEmpty()) |
| 1169 scrollCornerAndResizer = resizerCornerRect(box().pixelSnappedBorderBoxRe
ct(), ResizerForPointer); | 1088 scrollCornerAndResizer = resizerCornerRect(box().pixelSnappedBorderBoxRe
ct(), ResizerForPointer); |
| 1170 return scrollCornerAndResizer; | 1089 return scrollCornerAndResizer; |
| 1171 } | 1090 } |
| 1172 | 1091 |
| 1173 bool RenderLayerScrollableArea::overflowControlsIntersectRect(const IntRect& loc
alRect) const | |
| 1174 { | |
| 1175 const IntRect borderBox = box().pixelSnappedBorderBoxRect(); | |
| 1176 | |
| 1177 if (rectForHorizontalScrollbar(borderBox).intersects(localRect)) | |
| 1178 return true; | |
| 1179 | |
| 1180 if (rectForVerticalScrollbar(borderBox).intersects(localRect)) | |
| 1181 return true; | |
| 1182 | |
| 1183 if (scrollCornerRect().intersects(localRect)) | |
| 1184 return true; | |
| 1185 | |
| 1186 if (resizerCornerRect(borderBox, ResizerForPointer).intersects(localRect)) | |
| 1187 return true; | |
| 1188 | |
| 1189 return false; | |
| 1190 } | |
| 1191 | |
| 1192 void RenderLayerScrollableArea::paintResizer(GraphicsContext* context, const Int
Point& paintOffset, const IntRect& damageRect) | |
| 1193 { | |
| 1194 if (box().style()->resize() == RESIZE_NONE) | |
| 1195 return; | |
| 1196 | |
| 1197 IntRect absRect = resizerCornerRect(box().pixelSnappedBorderBoxRect(), Resiz
erForPointer); | |
| 1198 absRect.moveBy(paintOffset); | |
| 1199 if (!absRect.intersects(damageRect)) | |
| 1200 return; | |
| 1201 | |
| 1202 if (m_resizer) { | |
| 1203 ScrollbarPainter::paintIntoRect(m_resizer, context, paintOffset, absRect
); | |
| 1204 return; | |
| 1205 } | |
| 1206 | |
| 1207 drawPlatformResizerImage(context, absRect); | |
| 1208 | |
| 1209 // Draw a frame around the resizer (1px grey line) if there are any scrollba
rs present. | |
| 1210 // Clipping will exclude the right and bottom edges of this frame. | |
| 1211 if (!hasOverlayScrollbars() && hasScrollbar()) { | |
| 1212 GraphicsContextStateSaver stateSaver(*context); | |
| 1213 context->clip(absRect); | |
| 1214 IntRect largerCorner = absRect; | |
| 1215 largerCorner.setSize(IntSize(largerCorner.width() + 1, largerCorner.heig
ht() + 1)); | |
| 1216 context->setStrokeColor(Color(217, 217, 217)); | |
| 1217 context->setStrokeThickness(1.0f); | |
| 1218 context->setFillColor(Color::transparent); | |
| 1219 context->drawRect(largerCorner); | |
| 1220 } | |
| 1221 } | |
| 1222 | |
| 1223 bool RenderLayerScrollableArea::isPointInResizeControl(const IntPoint& absoluteP
oint, ResizerHitTestType resizerHitTestType) const | 1092 bool RenderLayerScrollableArea::isPointInResizeControl(const IntPoint& absoluteP
oint, ResizerHitTestType resizerHitTestType) const |
| 1224 { | 1093 { |
| 1225 if (!box().canResize()) | 1094 if (!box().canResize()) |
| 1226 return false; | 1095 return false; |
| 1227 | 1096 |
| 1228 IntPoint localPoint = roundedIntPoint(box().absoluteToLocal(absolutePoint, U
seTransforms)); | 1097 IntPoint localPoint = roundedIntPoint(box().absoluteToLocal(absolutePoint, U
seTransforms)); |
| 1229 IntRect localBounds(0, 0, box().pixelSnappedWidth(), box().pixelSnappedHeigh
t()); | 1098 IntRect localBounds(0, 0, box().pixelSnappedWidth(), box().pixelSnappedHeigh
t()); |
| 1230 return resizerCornerRect(localBounds, resizerHitTestType).contains(localPoin
t); | 1099 return resizerCornerRect(localBounds, resizerHitTestType).contains(localPoin
t); |
| 1231 } | 1100 } |
| 1232 | 1101 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1273 m_resizer = RenderScrollbarPart::createAnonymous(&box().document()); | 1142 m_resizer = RenderScrollbarPart::createAnonymous(&box().document()); |
| 1274 m_resizer->setParent(&box()); | 1143 m_resizer->setParent(&box()); |
| 1275 } | 1144 } |
| 1276 m_resizer->setStyle(resizer.release()); | 1145 m_resizer->setStyle(resizer.release()); |
| 1277 } else if (m_resizer) { | 1146 } else if (m_resizer) { |
| 1278 m_resizer->destroy(); | 1147 m_resizer->destroy(); |
| 1279 m_resizer = nullptr; | 1148 m_resizer = nullptr; |
| 1280 } | 1149 } |
| 1281 } | 1150 } |
| 1282 | 1151 |
| 1283 void RenderLayerScrollableArea::drawPlatformResizerImage(GraphicsContext* contex
t, IntRect resizerCornerRect) | |
| 1284 { | |
| 1285 float deviceScaleFactor = blink::deviceScaleFactor(box().frame()); | |
| 1286 | |
| 1287 RefPtr<Image> resizeCornerImage; | |
| 1288 IntSize cornerResizerSize; | |
| 1289 if (deviceScaleFactor >= 2) { | |
| 1290 DEFINE_STATIC_REF(Image, resizeCornerImageHiRes, (Image::loadPlatformRes
ource("textAreaResizeCorner@2x"))); | |
| 1291 resizeCornerImage = resizeCornerImageHiRes; | |
| 1292 cornerResizerSize = resizeCornerImage->size(); | |
| 1293 cornerResizerSize.scale(0.5f); | |
| 1294 } else { | |
| 1295 DEFINE_STATIC_REF(Image, resizeCornerImageLoRes, (Image::loadPlatformRes
ource("textAreaResizeCorner"))); | |
| 1296 resizeCornerImage = resizeCornerImageLoRes; | |
| 1297 cornerResizerSize = resizeCornerImage->size(); | |
| 1298 } | |
| 1299 | |
| 1300 if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) { | |
| 1301 context->save(); | |
| 1302 context->translate(resizerCornerRect.x() + cornerResizerSize.width(), re
sizerCornerRect.y() + resizerCornerRect.height() - cornerResizerSize.height()); | |
| 1303 context->scale(-1.0, 1.0); | |
| 1304 context->drawImage(resizeCornerImage.get(), IntRect(IntPoint(), cornerRe
sizerSize)); | |
| 1305 context->restore(); | |
| 1306 return; | |
| 1307 } | |
| 1308 IntRect imageRect(resizerCornerRect.maxXMaxYCorner() - cornerResizerSize, co
rnerResizerSize); | |
| 1309 context->drawImage(resizeCornerImage.get(), imageRect); | |
| 1310 } | |
| 1311 | |
| 1312 IntSize RenderLayerScrollableArea::offsetFromResizeCorner(const IntPoint& absolu
tePoint) const | 1152 IntSize RenderLayerScrollableArea::offsetFromResizeCorner(const IntPoint& absolu
tePoint) const |
| 1313 { | 1153 { |
| 1314 // Currently the resize corner is either the bottom right corner or the bott
om left corner. | 1154 // Currently the resize corner is either the bottom right corner or the bott
om left corner. |
| 1315 // FIXME: This assumes the location is 0, 0. Is this guaranteed to always be
the case? | 1155 // FIXME: This assumes the location is 0, 0. Is this guaranteed to always be
the case? |
| 1316 IntSize elementSize = layer()->size(); | 1156 IntSize elementSize = layer()->size(); |
| 1317 if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) | 1157 if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) |
| 1318 elementSize.setWidth(0); | 1158 elementSize.setWidth(0); |
| 1319 IntPoint resizerPoint = IntPoint(elementSize); | 1159 IntPoint resizerPoint = IntPoint(elementSize); |
| 1320 IntPoint localPoint = roundedIntPoint(box().absoluteToLocal(absolutePoint, U
seTransforms)); | 1160 IntPoint localPoint = roundedIntPoint(box().absoluteToLocal(absolutePoint, U
seTransforms)); |
| 1321 return localPoint - resizerPoint; | 1161 return localPoint - resizerPoint; |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1492 void RenderLayerScrollableArea::setTopmostScrollChild(RenderLayer* scrollChild) | 1332 void RenderLayerScrollableArea::setTopmostScrollChild(RenderLayer* scrollChild) |
| 1493 { | 1333 { |
| 1494 // We only want to track the topmost scroll child for scrollable areas with | 1334 // We only want to track the topmost scroll child for scrollable areas with |
| 1495 // overlay scrollbars. | 1335 // overlay scrollbars. |
| 1496 if (!hasOverlayScrollbars()) | 1336 if (!hasOverlayScrollbars()) |
| 1497 return; | 1337 return; |
| 1498 m_nextTopmostScrollChild = scrollChild; | 1338 m_nextTopmostScrollChild = scrollChild; |
| 1499 } | 1339 } |
| 1500 | 1340 |
| 1501 } // namespace blink | 1341 } // namespace blink |
| OLD | NEW |