/** Implementation of PanZoomTarget */
 public void setAnimationTarget(ImmutableViewportMetrics metrics) {
   if (mGeckoIsReady) {
     // We know what the final viewport of the animation is going to be, so
     // immediately request a draw of that area by setting the display port
     // accordingly. This way we should have the content pre-rendered by the
     // time the animation is done.
     DisplayPortMetrics displayPort = DisplayPortCalculator.calculate(metrics, null);
     adjustViewport(displayPort);
   }
 }
  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));
  }
 public DisplayPortMetrics getDisplayPort(
     boolean pageSizeUpdate,
     boolean isBrowserContentDisplayed,
     int tabId,
     ImmutableViewportMetrics metrics) {
   Tabs tabs = Tabs.getInstance();
   if (tabs.isSelectedTab(tabs.getTab(tabId)) && isBrowserContentDisplayed) {
     // for foreground tabs, send the viewport update unless the document
     // displayed is different from the content document. In that case, just
     // calculate the display port.
     return handleViewportMessage(
         metrics, pageSizeUpdate ? ViewportMessageType.PAGE_SIZE : ViewportMessageType.UPDATE);
   } else {
     // for background tabs, request a new display port calculation, so that
     // when we do switch to that tab, we have the correct display port and
     // don't need to draw twice (once to allow the first-paint viewport to
     // get to java, and again once java figures out the display port).
     return DisplayPortCalculator.calculate(metrics, null);
   }
 }
  /** 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;
  }