/** * Implementation of PanZoomTarget Converts a point from layer view coordinates to layer * coordinates. In other words, given a point measured in pixels from the top left corner of the * layer view, returns the point in pixels measured from the last scroll position we sent to * Gecko, in CSS pixels. Assuming the events being sent to Gecko are processed in FIFO order, this * calculation should always be correct. */ public PointF convertViewPointToLayerPoint(PointF viewPoint) { if (!mGeckoIsReady) { return null; } ImmutableViewportMetrics viewportMetrics = mViewportMetrics; PointF origin = viewportMetrics.getOrigin(); float zoom = viewportMetrics.zoomFactor; ImmutableViewportMetrics geckoViewport = mGeckoViewport; PointF geckoOrigin = geckoViewport.getOrigin(); float geckoZoom = geckoViewport.zoomFactor; // viewPoint + origin gives the coordinate in device pixels from the top-left corner of the // page. // Divided by zoom, this gives us the coordinate in CSS pixels from the top-left corner of the // page. // geckoOrigin / geckoZoom is where Gecko thinks it is (scrollTo position) in CSS pixels from // the top-left corner of the page. Subtracting the two gives us the offset of the viewPoint // from // the current Gecko coordinate in CSS pixels. PointF layerPoint = new PointF( ((viewPoint.x + origin.x) / zoom) - (geckoOrigin.x / geckoZoom), ((viewPoint.y + origin.y) / zoom) - (geckoOrigin.y / geckoZoom)); return layerPoint; }
private void adjustViewport(DisplayPortMetrics displayPort) { ImmutableViewportMetrics metrics = getViewportMetrics(); ImmutableViewportMetrics clampedMetrics = metrics.clamp(); if (displayPort == null) { displayPort = DisplayPortCalculator.calculate(metrics, mPanZoomController.getVelocityVector()); } mDisplayPort = displayPort; mGeckoViewport = clampedMetrics; if (mRecordDrawTimes) { mDrawTimingQueue.add(displayPort); } GeckoAppShell.sendEventToGecko(GeckoEvent.createViewportEvent(clampedMetrics, displayPort)); }
/** Sets the current page rect. You must hold the monitor while calling this. */ private void setPageRect(RectF rect, RectF cssRect) { // Since the "rect" is always just a multiple of "cssRect" we don't need to // check both; this function assumes that both "rect" and "cssRect" are relative // the zoom factor in mViewportMetrics. if (mViewportMetrics.getCssPageRect().equals(cssRect)) return; mViewportMetrics = mViewportMetrics.setPageRect(rect, cssRect); // Page size is owned by the layer client, so no need to notify it of // this change. post( new Runnable() { public void run() { mPanZoomController.pageRectUpdated(); mView.requestRender(); } }); }
/** * The view calls this function to indicate that the viewport changed size. It must hold the * monitor while calling it. * * <p>TODO: Refactor this to use an interface. Expose that interface only to the view and not to * the layer client. That way, the layer client won't be tempted to call this, which might result * in an infinite loop. */ void setViewportSize(int width, int height) { mViewportMetrics = mViewportMetrics.setViewportSize(width, height); if (mGeckoIsReady) { // here we send gecko a resize message. The code in browser.js is responsible for // picking up on that resize event, modifying the viewport as necessary, and informing // us of the new viewport. sendResizeEventIfNecessary(true); // the following call also sends gecko a message, which will be processed after the resize // message above has updated the viewport. this message ensures that if we have just put // focus in a text field, we scroll the content so that the text field is in view. GeckoAppShell.viewSizeChanged(); } }
/** Viewport message handler. */ private DisplayPortMetrics handleViewportMessage( ImmutableViewportMetrics messageMetrics, ViewportMessageType type) { synchronized (this) { ImmutableViewportMetrics metrics; ImmutableViewportMetrics oldMetrics = getViewportMetrics(); switch (type) { default: case UPDATE: // Keep the old viewport size metrics = messageMetrics.setViewportSize(oldMetrics.getWidth(), oldMetrics.getHeight()); abortPanZoomAnimation(); break; case PAGE_SIZE: // adjust the page dimensions to account for differences in zoom // between the rendered content (which is what Gecko tells us) // and our zoom level (which may have diverged). float scaleFactor = oldMetrics.zoomFactor / messageMetrics.zoomFactor; metrics = oldMetrics.setPageRect( RectUtils.scale(messageMetrics.getPageRect(), scaleFactor), messageMetrics.getCssPageRect()); break; } final ImmutableViewportMetrics newMetrics = metrics; post( new Runnable() { public void run() { mGeckoViewport = newMetrics; } }); setViewportMetrics(newMetrics, type == ViewportMessageType.UPDATE); mDisplayPort = DisplayPortCalculator.calculate(getViewportMetrics(), null); } return mDisplayPort; }
public FloatSize getViewportSize() { return mViewportMetrics.getSize(); }