summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d')
-rw-r--r--src/com/android/gallery3d/app/PhotoDataAdapter.java41
-rw-r--r--src/com/android/gallery3d/ui/BasicTexture.java4
-rw-r--r--src/com/android/gallery3d/ui/BitmapScreenNail.java49
-rw-r--r--src/com/android/gallery3d/ui/GLCanvas.java7
-rw-r--r--src/com/android/gallery3d/ui/GLCanvasImpl.java82
-rw-r--r--src/com/android/gallery3d/ui/TileImageView.java3
-rw-r--r--src/com/android/gallery3d/ui/TiledTexture.java298
7 files changed, 56 insertions, 428 deletions
diff --git a/src/com/android/gallery3d/app/PhotoDataAdapter.java b/src/com/android/gallery3d/app/PhotoDataAdapter.java
index 5ab022ac6..66f2874f7 100644
--- a/src/com/android/gallery3d/app/PhotoDataAdapter.java
+++ b/src/com/android/gallery3d/app/PhotoDataAdapter.java
@@ -35,7 +35,6 @@ import com.android.gallery3d.ui.PhotoView;
import com.android.gallery3d.ui.ScreenNail;
import com.android.gallery3d.ui.SynchronizedHandler;
import com.android.gallery3d.ui.TileImageViewAdapter;
-import com.android.gallery3d.ui.TiledTexture;
import com.android.gallery3d.util.Future;
import com.android.gallery3d.util.FutureListener;
import com.android.gallery3d.util.MediaSetUtils;
@@ -60,8 +59,8 @@ public class PhotoDataAdapter implements PhotoPage.Model {
private static final int MSG_RUN_OBJECT = 3;
private static final int MSG_UPDATE_IMAGE_REQUESTS = 4;
- private static final int MIN_LOAD_COUNT = 16;
- private static final int DATA_CACHE_SIZE = 256;
+ private static final int MIN_LOAD_COUNT = 8;
+ private static final int DATA_CACHE_SIZE = 32;
private static final int SCREEN_NAIL_MAX = PhotoView.SCREEN_NAIL_MAX;
private static final int IMAGE_CACHE_SIZE = 2 * SCREEN_NAIL_MAX + 1;
@@ -163,7 +162,6 @@ public class PhotoDataAdapter implements PhotoPage.Model {
private DataListener mDataListener;
private final SourceListener mSourceListener = new SourceListener();
- private final TiledTexture.Uploader mUploader;
// The path of the current viewing item will be stored in mItemPath.
// If mItemPath is not null, mCurrentIndex is only a hint for where we
@@ -185,8 +183,6 @@ public class PhotoDataAdapter implements PhotoPage.Model {
Arrays.fill(mChanges, MediaObject.INVALID_DATA_VERSION);
- mUploader = new TiledTexture.Uploader(activity.getGLRoot());
-
mMainHandler = new SynchronizedHandler(activity.getGLRoot()) {
@SuppressWarnings("unchecked")
@Override
@@ -325,7 +321,6 @@ public class PhotoDataAdapter implements PhotoPage.Model {
}
}
updateImageRequests();
- updateScreenNailUploadQueue();
}
private void updateFullImage(Path path, Future<BitmapRegionDecoder> future) {
@@ -350,8 +345,6 @@ public class PhotoDataAdapter implements PhotoPage.Model {
@Override
public void resume() {
mIsActive = true;
- TiledTexture.prepareResources();
-
mSource.addContentListener(mSourceListener);
updateImageCache();
updateImageRequests();
@@ -378,9 +371,6 @@ public class PhotoDataAdapter implements PhotoPage.Model {
}
mImageCache.clear();
mTileProvider.clear();
-
- mUploader.clear();
- TiledTexture.freeResources();
}
private MediaItem getItem(int index) {
@@ -404,7 +394,6 @@ public class PhotoDataAdapter implements PhotoPage.Model {
updateImageCache();
updateImageRequests();
updateTileProvider();
- updateScreenNailUploadQueue();
if (mDataListener != null) {
mDataListener.onPhotoChanged(index, mItemPath);
@@ -413,32 +402,6 @@ public class PhotoDataAdapter implements PhotoPage.Model {
fireDataChange();
}
- private void uploadScreenNail(int offset) {
- int index = mCurrentIndex + offset;
- if (index < mActiveStart || index >= mActiveEnd) return;
-
- MediaItem item = getItem(index);
- if (item == null) return;
-
- ImageEntry e = mImageCache.get(item.getPath());
- if (e == null) return;
-
- ScreenNail s = e.screenNail;
- if (s instanceof BitmapScreenNail) {
- TiledTexture t = ((BitmapScreenNail) s).getTexture();
- if (t != null && !t.isReady()) mUploader.addTexture(t);
- }
- }
-
- private void updateScreenNailUploadQueue() {
- mUploader.clear();
- uploadScreenNail(0);
- for (int i = 1; i < IMAGE_CACHE_SIZE; ++i) {
- uploadScreenNail(i);
- uploadScreenNail(-i);
- }
- }
-
@Override
public void moveTo(int index) {
updateCurrentIndex(index);
diff --git a/src/com/android/gallery3d/ui/BasicTexture.java b/src/com/android/gallery3d/ui/BasicTexture.java
index 99cf0571c..7b8e30de4 100644
--- a/src/com/android/gallery3d/ui/BasicTexture.java
+++ b/src/com/android/gallery3d/ui/BasicTexture.java
@@ -42,8 +42,8 @@ abstract class BasicTexture implements Texture {
protected int mWidth = UNSPECIFIED;
protected int mHeight = UNSPECIFIED;
- protected int mTextureWidth;
- protected int mTextureHeight;
+ private int mTextureWidth;
+ private int mTextureHeight;
private boolean mHasBorder;
diff --git a/src/com/android/gallery3d/ui/BitmapScreenNail.java b/src/com/android/gallery3d/ui/BitmapScreenNail.java
index 9b629160c..bf31bcbdf 100644
--- a/src/com/android/gallery3d/ui/BitmapScreenNail.java
+++ b/src/com/android/gallery3d/ui/BitmapScreenNail.java
@@ -46,16 +46,16 @@ public class BitmapScreenNail implements ScreenNail {
private int mWidth;
private int mHeight;
- private long mAnimationStartTime = ANIMATION_NOT_NEEDED;
-
private Bitmap mBitmap;
- private TiledTexture mTexture;
+ private BitmapTexture mTexture;
+ private long mAnimationStartTime = ANIMATION_NOT_NEEDED;
public BitmapScreenNail(Bitmap bitmap) {
mWidth = bitmap.getWidth();
mHeight = bitmap.getHeight();
mBitmap = bitmap;
- mTexture = new TiledTexture(bitmap);
+ // We create mTexture lazily, so we don't incur the cost if we don't
+ // actually need it.
}
public BitmapScreenNail(int width, int height) {
@@ -103,14 +103,17 @@ public class BitmapScreenNail implements ScreenNail {
BitmapScreenNail newer = (BitmapScreenNail) other;
mWidth = newer.mWidth;
mHeight = newer.mHeight;
- if (newer.mTexture != null) {
+ if (newer.mBitmap != null) {
recycleBitmap(MediaItem.getThumbPool(), mBitmap);
- if (mTexture != null) mTexture.recycle();
mBitmap = newer.mBitmap;
- mTexture = newer.mTexture;
newer.mBitmap = null;
- newer.mTexture = null;
+
+ if (mTexture != null) {
+ mTexture.recycle();
+ mTexture = null;
+ }
}
+
newer.recycle();
return this;
}
@@ -155,7 +158,7 @@ public class BitmapScreenNail implements ScreenNail {
@Override
public void draw(GLCanvas canvas, int x, int y, int width, int height) {
- if (mTexture == null || !mTexture.isReady()) {
+ if (mBitmap == null) {
if (mAnimationStartTime == ANIMATION_NOT_NEEDED) {
mAnimationStartTime = ANIMATION_NEEDED;
}
@@ -165,12 +168,16 @@ public class BitmapScreenNail implements ScreenNail {
return;
}
+ if (mTexture == null) {
+ mTexture = new BitmapTexture(mBitmap);
+ }
+
if (mAnimationStartTime == ANIMATION_NEEDED) {
- mAnimationStartTime = AnimationTime.get();
+ mAnimationStartTime = now();
}
if (isAnimating()) {
- mTexture.drawMixed(canvas, mPlaceholderColor, getRatio(), x, y,
+ canvas.drawMixed(mTexture, mPlaceholderColor, getRatio(), x, y,
width, height);
} else {
mTexture.draw(canvas, x, y, width, height);
@@ -179,26 +186,34 @@ public class BitmapScreenNail implements ScreenNail {
@Override
public void draw(GLCanvas canvas, RectF source, RectF dest) {
- if (mTexture == null || !mTexture.isReady()) {
+ if (mBitmap == null) {
canvas.fillRect(dest.left, dest.top, dest.width(), dest.height(),
mPlaceholderColor);
return;
}
- mTexture.draw(canvas, source, dest);
+ if (mTexture == null) {
+ mTexture = new BitmapTexture(mBitmap);
+ }
+
+ canvas.drawTexture(mTexture, source, dest);
}
public boolean isAnimating() {
if (mAnimationStartTime < 0) return false;
- if (AnimationTime.get() - mAnimationStartTime >= DURATION) {
+ if (now() - mAnimationStartTime >= DURATION) {
mAnimationStartTime = ANIMATION_DONE;
return false;
}
return true;
}
+ private static long now() {
+ return AnimationTime.get();
+ }
+
private float getRatio() {
- float r = (float) (AnimationTime.get() - mAnimationStartTime) / DURATION;
+ float r = (float)(now() - mAnimationStartTime) / DURATION;
return Utils.clamp(1.0f - r, 0.0f, 1.0f);
}
@@ -206,10 +221,6 @@ public class BitmapScreenNail implements ScreenNail {
return (mBitmap == null) || isAnimating();
}
- public TiledTexture getTexture() {
- return mTexture;
- }
-
public static void setMaxSide(int size) {
sMaxSide = size;
}
diff --git a/src/com/android/gallery3d/ui/GLCanvas.java b/src/com/android/gallery3d/ui/GLCanvas.java
index 6f8baef7e..e3a32ef08 100644
--- a/src/com/android/gallery3d/ui/GLCanvas.java
+++ b/src/com/android/gallery3d/ui/GLCanvas.java
@@ -99,13 +99,6 @@ public interface GLCanvas {
public void drawMixed(BasicTexture from, int toColor,
float ratio, int x, int y, int w, int h);
- // Draw a region of a texture and a specified color to the specified
- // rectangle. The actual color used is from * (1 - ratio) + to * ratio.
- // The region of the texture is defined by parameter "src". The target
- // rectangle is specified by parameter "target".
- public void drawMixed(BasicTexture from, int toColor,
- float ratio, RectF src, RectF target);
-
// Gets the underlying GL instance. This is used only when direct access to
// GL is needed.
public GL11 getGLInstance();
diff --git a/src/com/android/gallery3d/ui/GLCanvasImpl.java b/src/com/android/gallery3d/ui/GLCanvasImpl.java
index 45903b3cd..d83daf3e4 100644
--- a/src/com/android/gallery3d/ui/GLCanvasImpl.java
+++ b/src/com/android/gallery3d/ui/GLCanvasImpl.java
@@ -415,7 +415,7 @@ public class GLCanvasImpl implements GLCanvas {
// This function changes the source coordinate to the texture coordinates.
// It also clips the source and target coordinates if it is beyond the
// bound of the texture.
- private static void convertCoordinate(RectF source, RectF target,
+ private void convertCoordinate(RectF source, RectF target,
BasicTexture texture) {
int width = texture.getWidth();
@@ -465,7 +465,23 @@ public class GLCanvasImpl implements GLCanvas {
color[3] = alpha;
}
- private void setMixedColor(int toColor, float ratio, float alpha) {
+ private void drawMixed(BasicTexture from, int toColor,
+ float ratio, int x, int y, int width, int height, float alpha) {
+ // change from 0 to 0.01f to prevent getting divided by zero below
+ if (ratio <= 0.01f) {
+ drawTexture(from, x, y, width, height, alpha);
+ return;
+ } else if (ratio >= 1) {
+ fillRect(x, y, width, height, toColor);
+ return;
+ }
+
+ mGLState.setBlendEnabled(mBlendEnabled && (!from.isOpaque()
+ || !Utils.isOpaque(toColor) || alpha < OPAQUE_ALPHA));
+
+ final GL11 gl = mGL;
+ if (!bindTexture(from)) return;
+
//
// The formula we want:
// alpha * ((1 - ratio) * from + ratio * to)
@@ -479,6 +495,9 @@ public class GLCanvasImpl implements GLCanvas {
float combo = alpha * (1 - ratio);
float scale = alpha * ratio / (1 - combo);
+ // Interpolate the RGB and alpha values between both textures.
+ mGLState.setTexEnvMode(GL11.GL_COMBINE);
+
// Specify the interpolation factor via the alpha component of
// GL_TEXTURE_ENV_COLORs.
// RGB component are get from toColor and will used as SRC1
@@ -486,7 +505,6 @@ public class GLCanvasImpl implements GLCanvas {
setTextureColor(((toColor >>> 16) & 0xff) * colorScale,
((toColor >>> 8) & 0xff) * colorScale,
(toColor & 0xff) * colorScale, combo);
- GL11 gl = mGL;
gl.glTexEnvfv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_COLOR, mTextureColor, 0);
gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_RGB, GL11.GL_INTERPOLATE);
@@ -504,64 +522,6 @@ public class GLCanvasImpl implements GLCanvas {
gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_ALPHA, GL11.GL_CONSTANT);
gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_ALPHA, GL11.GL_SRC_ALPHA);
- }
-
- @Override
- public void drawMixed(BasicTexture from, int toColor, float ratio,
- RectF source, RectF target) {
- if (target.width() <= 0 || target.height() <= 0) return;
-
- if (ratio <= 0.01f) {
- drawTexture(from, source, target);
- return;
- } else if (ratio >= 1) {
- fillRect(target.left, target.top, target.width(), target.height(), toColor);
- return;
- }
-
- float alpha = mAlpha;
-
- // Copy the input to avoid changing it.
- mDrawTextureSourceRect.set(source);
- mDrawTextureTargetRect.set(target);
- source = mDrawTextureSourceRect;
- target = mDrawTextureTargetRect;
-
- mGLState.setBlendEnabled(mBlendEnabled && (!from.isOpaque()
- || !Utils.isOpaque(toColor) || alpha < OPAQUE_ALPHA));
-
- if (!bindTexture(from)) return;
-
- // Interpolate the RGB and alpha values between both textures.
- mGLState.setTexEnvMode(GL11.GL_COMBINE);
- setMixedColor(toColor, ratio, alpha);
- convertCoordinate(source, target, from);
- setTextureCoords(source);
- textureRect(target.left, target.top, target.width(), target.height());
- mGLState.setTexEnvMode(GL11.GL_REPLACE);
- }
-
- private void drawMixed(BasicTexture from, int toColor,
- float ratio, int x, int y, int width, int height, float alpha) {
- // change from 0 to 0.01f to prevent getting divided by zero below
- if (ratio <= 0.01f) {
- drawTexture(from, x, y, width, height, alpha);
- return;
- } else if (ratio >= 1) {
- fillRect(x, y, width, height, toColor);
- return;
- }
-
- mGLState.setBlendEnabled(mBlendEnabled && (!from.isOpaque()
- || !Utils.isOpaque(toColor) || alpha < OPAQUE_ALPHA));
-
- final GL11 gl = mGL;
- if (!bindTexture(from)) return;
-
- // Interpolate the RGB and alpha values between both textures.
- mGLState.setTexEnvMode(GL11.GL_COMBINE);
- setMixedColor(toColor, ratio, alpha);
-
drawBoundTexture(from, x, y, width, height);
mGLState.setTexEnvMode(GL11.GL_REPLACE);
}
diff --git a/src/com/android/gallery3d/ui/TileImageView.java b/src/com/android/gallery3d/ui/TileImageView.java
index 18a7af849..5ce06bec4 100644
--- a/src/com/android/gallery3d/ui/TileImageView.java
+++ b/src/com/android/gallery3d/ui/TileImageView.java
@@ -575,10 +575,8 @@ public class TileImageView extends GLView {
}
if (tile == null) break;
if (!tile.isContentValid()) {
- boolean hasBeenLoaded = tile.isLoaded();
Utils.assertTrue(tile.mTileState == STATE_DECODED);
tile.updateContent(canvas);
- if (!hasBeenLoaded) tile.draw(canvas, 0, 0);
--quota;
}
}
@@ -623,6 +621,7 @@ public class TileImageView extends GLView {
}
}
+ // TODO: avoid drawing the unused part of the textures.
static boolean drawTile(
Tile tile, GLCanvas canvas, RectF source, RectF target) {
while (true) {
diff --git a/src/com/android/gallery3d/ui/TiledTexture.java b/src/com/android/gallery3d/ui/TiledTexture.java
deleted file mode 100644
index 6e9ad9ea8..000000000
--- a/src/com/android/gallery3d/ui/TiledTexture.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.gallery3d.ui;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.RectF;
-
-import com.android.gallery3d.ui.GLRoot.OnGLIdleListener;
-
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-
-// This class is similar to BitmapTexture, except the bitmap is
-// split into tiles. By doing so, we may increase the time required to
-// upload the whole bitmap but we reduce the time of uploading each tile
-// so it make the animation more smooth and prevents jank.
-public class TiledTexture {
- private static final int CONTENT_SIZE = 254;
- private static final int BORDER_SIZE = 1;
- private static final int TILE_SIZE = CONTENT_SIZE + 2 * BORDER_SIZE;
- private static final int INIT_CAPACITY = 8;
-
- private static Tile sFreeTileHead = null;
- private static final Object sFreeTileLock = new Object();
-
- private static Bitmap sUploadBitmap;
- private static Canvas sCanvas;
- private static Paint sPaint;
-
- private int mUploadIndex = 0;
-
- private final Tile[] mTiles;
- private final int mWidth;
- private final int mHeight;
- private final RectF mSrcRect = new RectF();
- private final RectF mDestRect = new RectF();
-
- public static class Uploader implements OnGLIdleListener {
- private final ArrayDeque<TiledTexture> mTextures =
- new ArrayDeque<TiledTexture>(INIT_CAPACITY);
-
- private final GLRoot mGlRoot;
- private boolean mIsQueued = false;
-
- public Uploader(GLRoot glRoot) {
- mGlRoot = glRoot;
- }
-
- public synchronized void clear() {
- mTextures.clear();
- }
-
- public synchronized void addTexture(TiledTexture t) {
- if (t.isReady()) return;
- mTextures.addLast(t);
-
- if (mIsQueued) return;
- mIsQueued = true;
- mGlRoot.addOnGLIdleListener(this);
- }
-
-
- @Override
- public boolean onGLIdle(GLCanvas canvas, boolean renderRequested) {
- ArrayDeque<TiledTexture> deque = mTextures;
- synchronized (this) {
- if (!deque.isEmpty()) {
- TiledTexture t = deque.peekFirst();
- if (t.uploadNextTile(canvas)) {
- deque.removeFirst();
- mGlRoot.requestRender();
- }
- }
- mIsQueued = !mTextures.isEmpty();
-
- // return true to keep this listener in the queue
- return mIsQueued;
- }
- }
- }
-
- private static class Tile extends UploadedTexture {
- public int offsetX;
- public int offsetY;
- public Bitmap bitmap;
- public Tile nextFreeTile;
- public int contentWidth;
- public int contentHeight;
-
- @Override
- public void setSize(int width, int height) {
- contentWidth = width;
- contentHeight = height;
- mWidth = width + 2 * BORDER_SIZE;
- mHeight = height + 2 * BORDER_SIZE;
- mTextureWidth = TILE_SIZE;
- mTextureHeight = TILE_SIZE;
- }
-
- @Override
- protected Bitmap onGetBitmap() {
- int x = BORDER_SIZE - offsetX;
- int y = BORDER_SIZE - offsetY;
- int r = bitmap.getWidth() - x;
- int b = bitmap.getHeight() - y ;
- sCanvas.drawBitmap(bitmap, x, y, null);
- bitmap = null;
-
- // draw borders if need
- if (x > 0) sCanvas.drawLine(x - 1, 0, x - 1, TILE_SIZE, sPaint);
- if (y > 0) sCanvas.drawLine(0, y - 1, TILE_SIZE, y - 1, sPaint);
- if (r < CONTENT_SIZE) sCanvas.drawLine(r, 0, r, TILE_SIZE, sPaint);
- if (b < CONTENT_SIZE) sCanvas.drawLine(0, b, TILE_SIZE, b, sPaint);
-
- return sUploadBitmap;
- }
-
- @Override
- protected void onFreeBitmap(Bitmap bitmap) {
- // do nothing
- }
- }
-
- private static void freeTile(Tile tile) {
- tile.invalidateContent();
- tile.bitmap = null;
- synchronized (sFreeTileLock) {
- tile.nextFreeTile = sFreeTileHead;
- sFreeTileHead = tile;
- }
- }
-
- private static Tile obtainTile() {
- synchronized (sFreeTileLock) {
- Tile result = sFreeTileHead;
- if (result == null) return new Tile();
- sFreeTileHead = result.nextFreeTile;
- result.nextFreeTile = null;
- return result;
- }
- }
-
- private boolean uploadNextTile(GLCanvas canvas) {
- if (mUploadIndex == mTiles.length) return true;
- Tile next = mTiles[mUploadIndex++];
- boolean hasBeenLoad = next.isLoaded();
- next.updateContent(canvas);
-
- // It will take some time for a texture to be drawn for the first
- // time. When scrolling, we need to draw several tiles on the screen
- // at the same time. It may cause a UI jank even these textures has
- // been uploaded.
- if (!hasBeenLoad) next.draw(canvas, 0, 0);
- return mUploadIndex == mTiles.length;
- }
-
- public TiledTexture(Bitmap bitmap) {
- mWidth = bitmap.getWidth();
- mHeight = bitmap.getHeight();
- ArrayList<Tile> list = new ArrayList<Tile>();
-
- for (int x = 0, w = mWidth; x < w; x += CONTENT_SIZE) {
- for (int y = 0, h = mHeight; y < h; y += CONTENT_SIZE) {
- Tile tile = obtainTile();
- tile.offsetX = x;
- tile.offsetY = y;
- tile.bitmap = bitmap;
- tile.setSize(
- Math.min(CONTENT_SIZE, mWidth - x),
- Math.min(CONTENT_SIZE, mHeight - y));
- list.add(tile);
- }
- }
- mTiles = list.toArray(new Tile[list.size()]);
- }
-
- public boolean isReady() {
- return mUploadIndex == mTiles.length;
- }
-
- public void recycle() {
- for (int i = 0, n = mTiles.length; i < n; ++i) {
- freeTile(mTiles[i]);
- }
- }
-
- public static void freeResources() {
- sUploadBitmap = null;
- sCanvas = null;
- sPaint = null;
- }
-
- public static void prepareResources() {
- sUploadBitmap = Bitmap.createBitmap(TILE_SIZE, TILE_SIZE, Config.ARGB_8888);
- sCanvas = new Canvas(sUploadBitmap);
- sPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
- sPaint.setColor(Color.TRANSPARENT);
- sPaint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
- }
-
- // We want to draw the "source" on the "target".
- // This method is to find the "output" rectangle which is
- // the corresponding area of the "src".
- // (x,y) target
- // (x0,y0) source +---------------+
- // +----------+ | |
- // | src | | output |
- // | +--+ | linear map | +----+ |
- // | +--+ | ----------> | | | |
- // | | by (scaleX, scaleY) | +----+ |
- // +----------+ | |
- // Texture +---------------+
- // Canvas
- private static void mapRect(RectF output,
- RectF src, float x0, float y0, float x, float y, float scaleX,
- float scaleY) {
- output.set(x + (src.left - x0) * scaleX,
- y + (src.top - y0) * scaleY,
- x + (src.right - x0) * scaleX,
- y + (src.bottom - y0) * scaleY);
- }
-
- // Draws a mixed color of this texture and a specified color onto the
- // a rectangle. The used color is: from * (1 - ratio) + to * ratio.
- public void drawMixed(GLCanvas canvas, int color, float ratio,
- int x, int y, int width, int height) {
- RectF src = mSrcRect;
- RectF dest = mDestRect;
- float scaleX = (float) width / mWidth ;
- float scaleY = (float) height / mHeight;
- for (int i = 0, n = mTiles.length; i < n; ++i) {
- Tile t = mTiles[i];
- src.set(0, 0, t.contentWidth, t.contentHeight);
- src.offset(t.offsetX, t.offsetY);
- mapRect(dest, src, 0, 0, x, y, scaleX, scaleY);
- src.offset(BORDER_SIZE - t.offsetX, BORDER_SIZE - t.offsetY);
- canvas.drawMixed(t, color, ratio, mSrcRect, mDestRect);
- }
- }
-
- // Draws the texture on to the specified rectangle.
- public void draw(GLCanvas canvas, int x, int y, int width, int height) {
- RectF src = mSrcRect;
- RectF dest = mDestRect;
- float scaleX = (float) width / mWidth ;
- float scaleY = (float) height / mHeight;
- for (int i = 0, n = mTiles.length; i < n; ++i) {
- Tile t = mTiles[i];
- src.set(0, 0, t.contentWidth, t.contentHeight);
- src.offset(t.offsetX, t.offsetY);
- mapRect(dest, src, 0, 0, x, y, scaleX, scaleY);
- src.offset(BORDER_SIZE - t.offsetX, BORDER_SIZE - t.offsetY);
- canvas.drawTexture(t, mSrcRect, mDestRect);
- }
- }
-
- // Draws a sub region of this texture on to the specified rectangle.
- public void draw(GLCanvas canvas, RectF source, RectF target) {
- RectF src = mSrcRect;
- RectF dest = mDestRect;
- float x0 = source.left;
- float y0 = source.top;
- float x = target.left;
- float y = target.top;
- float scaleX = target.width() / source.width();
- float scaleY = target.height() / source.height();
-
- for (int i = 0, n = mTiles.length; i < n; ++i) {
- Tile t = mTiles[i];
- src.set(0, 0, t.contentWidth, t.contentHeight);
- src.offset(t.offsetX, t.offsetY);
- if (!src.intersect(source)) continue;
- mapRect(dest, src, x0, y0, x, y, scaleX, scaleY);
- src.offset(BORDER_SIZE - t.offsetX, BORDER_SIZE - t.offsetY);
- canvas.drawTexture(t, src, dest);
- }
- }
-}