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)); }
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); }