/*
* Copyright 2011 - AndroidQuery.com (tinyeeliu@gmail.com)
*
* 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.external.androidquery.util;
import java.lang.ref.WeakReference;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import com.external.androidquery.AQuery;
/**
* AQuery internal use only.
*
*/
public class RatioDrawable extends BitmapDrawable{
private float ratio;
private WeakReference<ImageView> ref;
private boolean adjusted;
private Matrix m;
private int w;
private float anchor;
public RatioDrawable(Resources res, Bitmap bm, ImageView iv, float ratio, float anchor){
super(res, bm);
this.ref = new WeakReference<ImageView>(iv);
this.ratio = ratio;
this.anchor = anchor;
iv.setScaleType(ScaleType.MATRIX);
Matrix m = new Matrix();
iv.setImageMatrix(m);
adjust(iv, bm, false);
}
private int getWidth(ImageView iv){
int width = 0;
LayoutParams lp = iv.getLayoutParams();
if(lp != null) width = lp.width;
if(width <= 0){
width = iv.getWidth();
}
if(width > 0){
width = width - iv.getPaddingLeft() - iv.getPaddingRight();
}
return width;
}
public void draw(Canvas canvas){
ImageView iv = null;
if(ref != null){
iv = ref.get();
}
if(ratio == 0 || iv == null){
super.draw(canvas);
}else{
Bitmap bm = getBitmap();
draw(canvas, iv, bm);
}
}
private void draw(Canvas canvas, ImageView iv, Bitmap bm){
Matrix m = getMatrix(iv, bm);
if(m != null){
int vpad = iv.getPaddingTop() + iv.getPaddingBottom();
int hpad = iv.getPaddingLeft() + iv.getPaddingRight();
if(vpad > 0 || hpad > 0){
canvas.clipRect(0, 0, iv.getWidth() - hpad, iv.getHeight() - vpad);
}
canvas.drawBitmap(bm, m, getPaint());
}
if(!adjusted){
adjust(iv, bm, true);
}
}
private void adjust(ImageView iv, Bitmap bm, boolean done){
int vw = getWidth(iv);
if(vw <= 0) return;
int dw = bm.getWidth();
int dh = bm.getHeight();
int th = targetHeight(dw, dh, vw) + iv.getPaddingTop() + iv.getPaddingBottom();
LayoutParams lp = iv.getLayoutParams();
if(lp == null) return;
int vh = lp.height;
if(th != vh){
lp.height = th;
iv.setLayoutParams(lp);
}
if(done) adjusted = true;
}
private int targetHeight(int dw, int dh, int vw){
float r = ratio;
if(ratio == AQuery.RATIO_PRESERVE){
r = (float) dh / (float) dw;
}
return (int) (vw * r);
}
private Matrix getMatrix(ImageView iv, Bitmap bm){
int dw = bm.getWidth();
if(m != null && dw == w){
return m;
}
int dh = bm.getHeight();
int vw = getWidth(iv);
int vh = targetHeight(dw, dh, vw);
if(dw <= 0 || dh <= 0 || vw <= 0 || vh <= 0) return null;
if(m == null || dw != w){
float scale;
float dx = 0, dy = 0;
m = new Matrix();
if(dw * vh >= vw * dh){
//if image is super wider
scale = (float) vh / (float) dh;
dx = (vw - dw * scale) * 0.5f;
}else{
//if image is taller
scale = (float) vw / (float) dw;
float sy = getYOffset(dw, dh);
dy = (vh - dh * scale) * sy;
}
m.setScale(scale, scale);
m.postTranslate(dx, dy);
w = dw;
}
return m;
}
private float getYOffset(int vwidth, int vheight){
if(anchor != AQuery.ANCHOR_DYNAMIC){
return (1 - anchor) / 2;
}
float ratio = (float) vheight / (float) vwidth;
ratio = Math.min(1.5f, ratio);
ratio = Math.max(1, ratio);
return 0.25f + ((1.5f - ratio) / 2.0f);
}
}