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

Unified Diff: pdf/out_of_process_instance.cc

Issue 2400743002: Improved Pinch-Zoom for PDF. (Closed)
Patch Set: Small changes. Created 4 years, 1 month 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 | « pdf/out_of_process_instance.h ('k') | pdf/paint_manager.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pdf/out_of_process_instance.cc
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc
index 92511185c9715dd610adc6353cae440616666284..3f59d818a76b857aebb198e08f955aad185e3364 100644
--- a/pdf/out_of_process_instance.cc
+++ b/pdf/out_of_process_instance.cc
@@ -56,6 +56,13 @@ const char kJSViewportType[] = "viewport";
const char kJSXOffset[] = "xOffset";
const char kJSYOffset[] = "yOffset";
const char kJSZoom[] = "zoom";
+const char kJSPinchPhase[] = "pinchPhase";
+// kJSPinchX and kJSPinchY represent the center of the pinch gesture.
+const char kJSPinchX[] = "pinchX";
+const char kJSPinchY[] = "pinchY";
+// kJSPinchVector represents the amount of panning caused by the pinch gesture.
+const char kJSPinchVectorX[] = "pinchVectorX";
+const char kJSPinchVectorY[] = "pinchVectorY";
// Stop scrolling message (Page -> Plugin)
const char kJSStopScrollingType[] = "stopScrolling";
// Document dimension arguments (Plugin -> Page).
@@ -274,6 +281,9 @@ OutOfProcessInstance::OutOfProcessInstance(PP_Instance instance)
pp::Printing_Dev(this),
cursor_(PP_CURSORTYPE_POINTER),
zoom_(1.0),
+ needs_reraster_(true),
+ last_bitmap_smaller_(false),
+ last_zoom_when_smaller_(1.0),
device_scale_(1.0),
full_(false),
paint_manager_(this, this, true),
@@ -395,13 +405,91 @@ void OutOfProcessInstance::HandleMessage(const pp::Var& message) {
if (type == kJSViewportType &&
dict.Get(pp::Var(kJSXOffset)).is_number() &&
dict.Get(pp::Var(kJSYOffset)).is_number() &&
- dict.Get(pp::Var(kJSZoom)).is_number()) {
+ dict.Get(pp::Var(kJSZoom)).is_number() &&
+ dict.Get(pp::Var(kJSPinchPhase)).is_number()) {
received_viewport_message_ = true;
stop_scrolling_ = false;
+ PinchPhase pinch_phase =
+ static_cast<PinchPhase>(dict.Get(pp::Var(kJSPinchPhase)).AsInt());
double zoom = dict.Get(pp::Var(kJSZoom)).AsDouble();
+ double zoom_ratio = zoom / zoom_;
+
pp::FloatPoint scroll_offset(dict.Get(pp::Var(kJSXOffset)).AsDouble(),
dict.Get(pp::Var(kJSYOffset)).AsDouble());
+ if (pinch_phase == PINCH_START) {
+ starting_scroll_offset_ = scroll_offset;
+ initial_zoom_ratio_ = zoom_ratio;
+ last_bitmap_smaller_ = false;
+ needs_reraster_ = false;
+ return;
+ }
+
+ if (pinch_phase == PINCH_UPDATE_ZOOM_IN) {
+ if (!(dict.Get(pp::Var(kJSPinchX)).is_number() &&
+ dict.Get(pp::Var(kJSPinchY)).is_number() &&
+ dict.Get(pp::Var(kJSPinchVectorX)).is_number() &&
+ dict.Get(pp::Var(kJSPinchVectorY)).is_number())) {
+ NOTREACHED();
+ return;
+ }
+
+ pp::Point pinch_center(dict.Get(pp::Var(kJSPinchX)).AsDouble(),
+ dict.Get(pp::Var(kJSPinchY)).AsDouble());
+ // Pinch vector is the panning caused due to change in pinch
+ // center between start and end of the gesture.
+ pp::Point pinch_vector =
+ pp::Point(dict.Get(kJSPinchVectorX).AsDouble() * zoom_ratio,
+ dict.Get(kJSPinchVectorY).AsDouble() * zoom_ratio);
+ pp::Point scroll_delta;
+ // If the rendered document doesn't fill the display area we will
+ // use |paint_offset| to anchor the paint vertically into the same place.
+ // We use the scroll bars instead of the pinch vector to get the actual
+ // position on screen of the paint.
+ pp::Point paint_offset;
+
+ if (plugin_size_.width() > GetDocumentPixelWidth() * zoom_ratio) {
+ // We want to keep the paint in the middle but it must stay in the same
+ // position relative to the scroll bars.
+ paint_offset = pp::Point(0, (1 - zoom_ratio) * pinch_center.y());
+ scroll_delta = pp::Point(0,
+ (scroll_offset.y() -
+ starting_scroll_offset_.y() * zoom_ratio / initial_zoom_ratio_));
+
+ pinch_vector = pp::Point();
+ last_zoom_when_smaller_ = zoom;
+ last_bitmap_smaller_ = true;
+ } else if (last_bitmap_smaller_) {
+ pinch_center = pp::Point((plugin_size_.width() / device_scale_) / 2,
+ (plugin_size_.height() / device_scale_) / 2);
+ paint_offset = pp::Point(
+ (1 - zoom / last_zoom_when_smaller_) * pinch_center.x(),
+ (1 - zoom_ratio) * pinch_center.y());
+ pinch_vector = pp::Point();
+ scroll_delta = pp::Point(
+ (scroll_offset.x() -
+ starting_scroll_offset_.x() * zoom_ratio / initial_zoom_ratio_),
+ (scroll_offset.y() -
+ starting_scroll_offset_.y() * zoom_ratio / initial_zoom_ratio_));
+ }
+
+ paint_manager_.SetTransform(zoom_ratio, pinch_center,
+ pinch_vector + paint_offset + scroll_delta,
+ true);
+ needs_reraster_ = false;
+ return;
+ }
+
+ if (pinch_phase == PINCH_UPDATE_ZOOM_OUT || pinch_phase == PINCH_END) {
+ // We reraster on pinch zoom out in order to solve the invalid regions
+ // that appear after zooming out.
+ // On pinch end the scale is again 1.f and we request a reraster
+ // in the new position.
+ paint_manager_.ClearTransform();
+ last_bitmap_smaller_ = false;
+ needs_reraster_ = true;
+ }
+
// Bound the input parameters.
zoom = std::max(kMinZoom, zoom);
SetZoom(zoom);
@@ -788,7 +876,7 @@ void OutOfProcessInstance::OnPaint(
ready->push_back(PaintManager::ReadyRect(rect, image_data_, true));
}
- if (!received_viewport_message_)
+ if (!received_viewport_message_ || !needs_reraster_)
return;
engine_->PrePaint();
« no previous file with comments | « pdf/out_of_process_instance.h ('k') | pdf/paint_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698