예제 #1
0
  private void computeCoverAndKeepRect(final Rect visibleRect, Rect coverRect, Rect keepRect) {
    visibleRect.copyTo(coverRect);
    visibleRect.copyTo(keepRect);

    // If we cover more that the actual viewport we can be smart about which tiles we choose to
    // render.
    if (mCoverAreaMultiplier > 1) {
      // The initial cover area covers equally in each direction, according to the
      // coverAreaMultiplier.
      coverRect.inflate(
          (int) (visibleRect.getWidth() * (mCoverAreaMultiplier - 1) / 2),
          (int) (visibleRect.getHeight() * (mCoverAreaMultiplier - 1) / 2));
      coverRect.copyTo(keepRect);

      if (mPendingTrajectoryVector.getX() != 0 || mPendingTrajectoryVector.getY() != 0) {
        // A null trajectory vector (no motion) means that tiles for the coverArea will be created.
        // A non-null trajectory vector will shrink the covered rect to visibleRect plus its
        // expansion from its
        // center toward the cover area edges in the direction of the given vector.

        // E.g. if visibleRect == (10,10)5x5 and coverAreaMultiplier == 3.0:
        // a (0,0) trajectory vector will create tiles intersecting (5,5)15x15,
        // a (1,0) trajectory vector will create tiles intersecting (10,10)10x5,
        // and a (1,1) trajectory vector will create tiles intersecting (10,10)10x10.

        // Multiply the vector by the distance to the edge of the cover area.
        float trajectoryVectorMultiplier = (mCoverAreaMultiplier - 1) / 2;

        // Unite the visible rect with a "ghost" of the visible rect moved in the direction of the
        // trajectory vector.
        visibleRect.copyTo(coverRect);
        coverRect.offset(
            (int) (coverRect.getWidth() * mTrajectoryVector.getX() * trajectoryVectorMultiplier),
            (int) (coverRect.getHeight() * mTrajectoryVector.getY() * trajectoryVectorMultiplier));

        coverRect.composite(visibleRect);
      }

      assert (keepRect.contains(coverRect));
    }

    adjustForContentsRect(coverRect);

    // The keep rect is an inflated version of the cover rect, inflated in tile dimensions.
    keepRect.composite(coverRect);
    keepRect.inflate(mTileSize.getWidth() / 2, mTileSize.getHeight() / 2);
    keepRect.intersect(mRect);

    assert (coverRect.isEmpty() || keepRect.contains(coverRect));
  }
예제 #2
0
  private void adjustForContentsRect(Rect rect) {
    Rect bounds = mRect;
    Size candidateSize = new Size(rect.getWidth(), rect.getHeight());

    rect.intersect(bounds);

    if (rect.getWidth() == candidateSize.getWidth()
        && rect.getHeight() == candidateSize.getHeight()) return;

    /*
     * In the following case, there is no intersection of the contents rect and the cover rect.
     * Thus the latter should not be inflated.
     *
     *  +---------------+
     *  |   m_rect      |
     *  +---------------+
     *
     *          +-------------------------------+
     *          |          cover rect           |
     *          |         +---------+           |
     *          |         | visible |           |
     *          |         |  rect   |           |
     *          |         +---------+           |
     *          +-------------------------------+
     */
    if (rect.isEmpty()) return;

    // Try to create a cover rect of the same size as the candidate, but within content bounds.
    int pixelsCovered = candidateSize.getWidth() * candidateSize.getHeight();

    if (rect.getWidth() < candidateSize.getWidth())
      rect.inflate(0, ((pixelsCovered / rect.getWidth()) - rect.getHeight()) / 2);
    if (rect.getHeight() < candidateSize.getHeight())
      rect.inflate(((pixelsCovered / rect.getHeight()) - rect.getWidth()) / 2, 0);

    rect.intersect(bounds);
  }