Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/render_view_impl.h" | 5 #include "content/renderer/render_view_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 348 | 348 |
| 349 static const size_t kExtraCharsBeforeAndAfterSelection = 100; | 349 static const size_t kExtraCharsBeforeAndAfterSelection = 100; |
| 350 | 350 |
| 351 // The maximum number of popups that can be spawned from one page. | 351 // The maximum number of popups that can be spawned from one page. |
| 352 static const int kMaximumNumberOfUnacknowledgedPopups = 25; | 352 static const int kMaximumNumberOfUnacknowledgedPopups = 25; |
| 353 | 353 |
| 354 static const float kScalingIncrement = 0.1f; | 354 static const float kScalingIncrement = 0.1f; |
| 355 | 355 |
| 356 static const float kScalingIncrementForGesture = 0.01f; | 356 static const float kScalingIncrementForGesture = 0.01f; |
| 357 | 357 |
| 358 // The amount of padding to add to the disambiguation popup to show | |
| 359 // content around the possible elements, adding some context. | |
| 360 static const int kDisambiguationPopupPadding = 8; | |
| 361 | |
| 362 // Constants used for fitting the disambiguation popup inside the bounds of | |
| 363 // the view. Note that there are mirror constants in PopupZoomer.java. | |
| 364 static const int kDisambiguationPopupBoundsMargin = 25; | |
| 365 | |
| 366 // The smallest allowable touch target used for disambiguation popup. | |
| 367 // This value is used to determine the minimum amount we need to scale to | |
| 368 // make all targets touchable. | |
| 369 static const int kDisambiguationPopupMinimumTouchSize = 40; | |
| 370 static const float kDisambiguationPopupMaxScale = 5.0; | |
| 371 static const float kDisambiguationPopupMinScale = 2.0; | |
| 372 | |
| 358 #if defined(OS_ANDROID) | 373 #if defined(OS_ANDROID) |
| 359 // Delay between tapping in content and launching the associated android intent. | 374 // Delay between tapping in content and launching the associated android intent. |
| 360 // Used to allow users see what has been recognized as content. | 375 // Used to allow users see what has been recognized as content. |
| 361 static const size_t kContentIntentDelayMilliseconds = 700; | 376 static const size_t kContentIntentDelayMilliseconds = 700; |
| 362 #endif | 377 #endif |
| 363 | 378 |
| 364 static RenderViewImpl* FromRoutingID(int32 routing_id) { | 379 static RenderViewImpl* FromRoutingID(int32 routing_id) { |
| 365 return static_cast<RenderViewImpl*>( | 380 return static_cast<RenderViewImpl*>( |
| 366 ChildThread::current()->ResolveRoute(routing_id)); | 381 ChildThread::current()->ResolveRoute(routing_id)); |
| 367 } | 382 } |
| (...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1000 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed) | 1015 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed) |
| 1001 // TODO(viettrungluu): Move to a separate message filter. | 1016 // TODO(viettrungluu): Move to a separate message filter. |
| 1002 #if defined(OS_MACOSX) | 1017 #if defined(OS_MACOSX) |
| 1003 IPC_MESSAGE_HANDLER(ViewMsg_SetInLiveResize, OnSetInLiveResize) | 1018 IPC_MESSAGE_HANDLER(ViewMsg_SetInLiveResize, OnSetInLiveResize) |
| 1004 #endif | 1019 #endif |
| 1005 IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune, | 1020 IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune, |
| 1006 OnSetHistoryLengthAndPrune) | 1021 OnSetHistoryLengthAndPrune) |
| 1007 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode) | 1022 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode) |
| 1008 IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit) | 1023 IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit) |
| 1009 IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityMode, OnSetAccessibilityMode) | 1024 IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityMode, OnSetAccessibilityMode) |
| 1025 IPC_MESSAGE_HANDLER(ViewMsg_ReleaseDisambiguationPopupDIB, | |
| 1026 OnReleaseDisambiguationPopupDIB) | |
| 1010 | 1027 |
| 1011 // Have the super handle all other messages. | 1028 // Have the super handle all other messages. |
| 1012 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message)) | 1029 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message)) |
| 1013 IPC_END_MESSAGE_MAP() | 1030 IPC_END_MESSAGE_MAP() |
| 1014 | 1031 |
| 1015 if (!msg_is_ok) { | 1032 if (!msg_is_ok) { |
| 1016 // The message had a handler, but its deserialization failed. | 1033 // The message had a handler, but its deserialization failed. |
| 1017 // Kill the renderer to avoid potential spoofing attacks. | 1034 // Kill the renderer to avoid potential spoofing attacks. |
| 1018 CHECK(false) << "Unable to deserialize message in RenderViewImpl."; | 1035 CHECK(false) << "Unable to deserialize message in RenderViewImpl."; |
| 1019 } | 1036 } |
| (...skipping 4865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5885 bool RenderViewImpl::WebWidgetHandlesCompositorScheduling() const { | 5902 bool RenderViewImpl::WebWidgetHandlesCompositorScheduling() const { |
| 5886 return !!RenderThreadImpl::current()->compositor_thread(); | 5903 return !!RenderThreadImpl::current()->compositor_thread(); |
| 5887 } | 5904 } |
| 5888 | 5905 |
| 5889 void RenderViewImpl::OnJavaBridgeInit() { | 5906 void RenderViewImpl::OnJavaBridgeInit() { |
| 5890 DCHECK(!java_bridge_dispatcher_); | 5907 DCHECK(!java_bridge_dispatcher_); |
| 5891 #if defined(ENABLE_JAVA_BRIDGE) | 5908 #if defined(ENABLE_JAVA_BRIDGE) |
| 5892 java_bridge_dispatcher_ = new JavaBridgeDispatcher(this); | 5909 java_bridge_dispatcher_ = new JavaBridgeDispatcher(this); |
| 5893 #endif | 5910 #endif |
| 5894 } | 5911 } |
| 5912 | |
| 5913 // Compute the scaling factor to ensure the smallest touch candidate reaches | |
|
darin (slow to review)
2012/08/30 17:39:23
render_view_impl.cc is already packed with code fo
trchen
2012/08/30 21:15:22
That sounds like a great idea. I think splitting i
| |
| 5914 // a certain clickable size after zooming | |
| 5915 static float FindOptimalScaleFactor(const WebVector<WebRect>& target_rects) { | |
| 5916 using std::min; | |
| 5917 using std::max; | |
| 5918 if (!target_rects.size()) // shall never reach | |
| 5919 return kDisambiguationPopupMinScale; | |
| 5920 int smallest_target = min(target_rects[0].width, target_rects[0].height); | |
| 5921 for (size_t i = 1; i < target_rects.size(); i++) { | |
| 5922 smallest_target = min(smallest_target, target_rects[i].width); | |
| 5923 smallest_target = min(smallest_target, target_rects[i].height); | |
| 5924 } | |
| 5925 smallest_target = max(smallest_target, 1); | |
| 5926 return min(kDisambiguationPopupMaxScale, max(kDisambiguationPopupMinScale, | |
| 5927 static_cast<float>(kDisambiguationPopupMinimumTouchSize) | |
| 5928 / smallest_target)); | |
| 5929 } | |
| 5930 | |
| 5931 static void TrimEdges(int *e1, int *e2, int max_combined) { | |
| 5932 if (*e1 + *e2 <= max_combined) | |
| 5933 return; | |
| 5934 | |
| 5935 if (std::min(*e1, *e2) * 2 >= max_combined) { | |
| 5936 *e1 = *e2 = max_combined / 2; | |
| 5937 } else if (*e1 > *e2) { | |
| 5938 *e1 = max_combined - *e2; | |
| 5939 } else | |
| 5940 *e2 = max_combined - *e1; | |
| 5941 } | |
| 5942 | |
| 5943 // Ensure the disambiguation popup fits inside the screen, | |
| 5944 // clip the edges farthest to the touch point if needed. | |
| 5945 static gfx::Rect CropZoomArea(const gfx::Rect& zoom_rect, | |
| 5946 const gfx::Size& viewport_size, | |
| 5947 const gfx::Point& touch_point, | |
| 5948 float scale) { | |
| 5949 gfx::Size max_size = viewport_size; | |
| 5950 max_size.Enlarge(-2 * kDisambiguationPopupBoundsMargin, | |
| 5951 -2 * kDisambiguationPopupBoundsMargin); | |
| 5952 max_size = max_size.Scale(1.0 / scale); | |
| 5953 | |
| 5954 int left = touch_point.x() - zoom_rect.x(); | |
| 5955 int right = zoom_rect.right() - touch_point.x(); | |
| 5956 int top = touch_point.y() - zoom_rect.y(); | |
| 5957 int bottom = zoom_rect.bottom() - touch_point.y(); | |
| 5958 TrimEdges(&left, &right, max_size.width()); | |
| 5959 TrimEdges(&top, &bottom, max_size.height()); | |
| 5960 | |
| 5961 return gfx::Rect(touch_point.x() - left, | |
| 5962 touch_point.y() - top, | |
| 5963 left + right, | |
| 5964 top + bottom); | |
| 5965 } | |
| 5966 | |
| 5967 bool RenderViewImpl::handleDisambiguationPopup( | |
|
darin (slow to review)
2012/08/30 17:39:23
why is this function named "handleDisambiguationPo
trchen
2012/08/30 21:15:22
Yea... I agree the naming is confusing here.
Up t
| |
| 5968 const WebKit::WebGestureEvent& event, | |
| 5969 const WebVector<WebRect>& target_rects) { | |
| 5970 gfx::Rect zoom_rect = event.boundingBox; | |
| 5971 for (size_t i = 0; i < target_rects.size(); i++) | |
| 5972 zoom_rect = zoom_rect.Union(gfx::Rect(target_rects[i])); | |
| 5973 zoom_rect.Inset(-kDisambiguationPopupPadding, -kDisambiguationPopupPadding); | |
| 5974 zoom_rect = zoom_rect.Intersect(gfx::Rect(GetSize())); | |
| 5975 | |
| 5976 float scale = FindOptimalScaleFactor(target_rects); | |
| 5977 zoom_rect = CropZoomArea( | |
| 5978 zoom_rect, GetSize(), gfx::Point(event.x, event.y), scale); | |
| 5979 | |
| 5980 gfx::Size canvas_size = zoom_rect.size(); | |
| 5981 canvas_size = canvas_size.Scale(scale); | |
| 5982 | |
| 5983 TransportDIB* transport_dib = NULL; | |
| 5984 { | |
| 5985 scoped_ptr<skia::PlatformCanvas> canvas( | |
| 5986 RenderProcess::current()->GetDrawingCanvas(&transport_dib, | |
| 5987 gfx::Rect(canvas_size))); | |
| 5988 if (!canvas.get()) | |
| 5989 return false; | |
| 5990 | |
| 5991 canvas->scale(scale, scale); | |
| 5992 | |
| 5993 canvas->translate(-zoom_rect.x(), -zoom_rect.y()); | |
| 5994 webwidget_->paint(webkit_glue::ToWebCanvas(canvas.get()), zoom_rect, | |
| 5995 WebWidget::ForceSoftwareRenderingAndIgnoreGPUResidentContent); | |
| 5996 } | |
| 5997 Send(new ViewHostMsg_MultipleTargetsTouched(routing_id_, | |
| 5998 zoom_rect, | |
| 5999 canvas_size, | |
| 6000 transport_dib->id())); | |
| 6001 | |
| 6002 return true; | |
| 6003 } | |
| 6004 | |
| 6005 void RenderViewImpl::OnReleaseDisambiguationPopupDIB( | |
| 6006 TransportDIB::Handle dib_handle) { | |
| 6007 TransportDIB* dib = TransportDIB::CreateWithHandle(dib_handle); | |
| 6008 RenderProcess::current()->ReleaseTransportDIB(dib); | |
| 6009 } | |
| OLD | NEW |