/*
* 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.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.TextUtils;
import com.android.gallery3d.R;
import com.android.gallery3d.data.DataSourceType;
import com.android.photos.data.GalleryBitmapPool;
import com.android.gallery3d.util.ThreadPool;
import com.android.gallery3d.util.ThreadPool.JobContext;
public class AlbumLabelMaker {
private static final int BORDER_SIZE = 0;
private final AlbumSetSlotRenderer.LabelSpec mSpec;
private final TextPaint mTitlePaint;
private final TextPaint mCountPaint;
private final Context mContext;
private int mLabelWidth;
private int mBitmapWidth;
private int mBitmapHeight;
private final LazyLoadedBitmap mLocalSetIcon;
private final LazyLoadedBitmap mPicasaIcon;
private final LazyLoadedBitmap mCameraIcon;
public AlbumLabelMaker(Context context, AlbumSetSlotRenderer.LabelSpec spec) {
mContext = context;
mSpec = spec;
mTitlePaint = getTextPaint(spec.titleFontSize, spec.titleColor, false);
mCountPaint = getTextPaint(spec.countFontSize, spec.countColor, false);
mLocalSetIcon = new LazyLoadedBitmap(R.drawable.frame_overlay_gallery_folder);
mPicasaIcon = new LazyLoadedBitmap(R.drawable.frame_overlay_gallery_picasa);
mCameraIcon = new LazyLoadedBitmap(R.drawable.frame_overlay_gallery_camera);
}
public static int getBorderSize() {
return BORDER_SIZE;
}
private Bitmap getOverlayAlbumIcon(int sourceType) {
switch (sourceType) {
case DataSourceType.TYPE_CAMERA:
return mCameraIcon.get();
case DataSourceType.TYPE_LOCAL:
return mLocalSetIcon.get();
case DataSourceType.TYPE_PICASA:
return mPicasaIcon.get();
}
return null;
}
private static TextPaint getTextPaint(int textSize, int color, boolean isBold) {
TextPaint paint = new TextPaint();
paint.setTextSize(textSize);
paint.setAntiAlias(true);
paint.setColor(color);
//paint.setShadowLayer(2f, 0f, 0f, Color.LTGRAY);
if (isBold) {
paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
}
return paint;
}
private class LazyLoadedBitmap {
private Bitmap mBitmap;
private int mResId;
public LazyLoadedBitmap(int resId) {
mResId = resId;
}
public synchronized Bitmap get() {
if (mBitmap == null) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
mBitmap = BitmapFactory.decodeResource(
mContext.getResources(), mResId, options);
}
return mBitmap;
}
}
public synchronized void setLabelWidth(int width) {
if (mLabelWidth == width) return;
mLabelWidth = width;
int borders = 2 * BORDER_SIZE;
mBitmapWidth = width + borders;
mBitmapHeight = mSpec.labelBackgroundHeight + borders;
}
public ThreadPool.Job<Bitmap> requestLabel(
String title, String count, int sourceType) {
return new AlbumLabelJob(title, count, sourceType);
}
static void drawText(Canvas canvas,
int x, int y, String text, int lengthLimit, TextPaint p) {
// The TextPaint cannot be used concurrently
synchronized (p) {
text = TextUtils.ellipsize(
text, p, lengthLimit, TextUtils.TruncateAt.END).toString();
canvas.drawText(text, x, y - p.getFontMetricsInt().ascent, p);
}
}
private class AlbumLabelJob implements ThreadPool.Job<Bitmap> {
private final String mTitle;
private final String mCount;
private final int mSourceType;
public AlbumLabelJob(String title, String count, int sourceType) {
mTitle = title;
mCount = count;
mSourceType = sourceType;
}
@Override
public Bitmap run(JobContext jc) {
AlbumSetSlotRenderer.LabelSpec s = mSpec;
String title = mTitle;
String count = mCount;
Bitmap icon = getOverlayAlbumIcon(mSourceType);
Bitmap bitmap;
int labelWidth;
synchronized (this) {
labelWidth = mLabelWidth;
bitmap = GalleryBitmapPool.getInstance().get(mBitmapWidth, mBitmapHeight);
}
if (bitmap == null) {
int borders = 2 * BORDER_SIZE;
bitmap = Bitmap.createBitmap(labelWidth + borders,
s.labelBackgroundHeight + borders, Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
canvas.clipRect(BORDER_SIZE, BORDER_SIZE,
bitmap.getWidth() - BORDER_SIZE,
bitmap.getHeight() - BORDER_SIZE);
canvas.drawColor(mSpec.backgroundColor, PorterDuff.Mode.SRC);
canvas.translate(BORDER_SIZE, BORDER_SIZE);
// draw title
if (jc.isCancelled()) return null;
int x = s.leftMargin + s.iconSize;
// TODO: is the offset relevant in new reskin?
// int y = s.titleOffset;
int y = (s.labelBackgroundHeight - s.titleFontSize) / 2;
drawText(canvas, x, y, title, labelWidth - s.leftMargin - x -
s.titleRightMargin, mTitlePaint);
// draw count
if (jc.isCancelled()) return null;
x = labelWidth - s.titleRightMargin;
y = (s.labelBackgroundHeight - s.countFontSize) / 2;
drawText(canvas, x, y, count,
labelWidth - x , mCountPaint);
// draw the icon
if (icon != null) {
if (jc.isCancelled()) return null;
float scale = (float) s.iconSize / icon.getWidth();
canvas.translate(s.leftMargin, (s.labelBackgroundHeight -
Math.round(scale * icon.getHeight()))/2f);
canvas.scale(scale, scale);
canvas.drawBitmap(icon, 0, 0, null);
}
return bitmap;
}
}
public void recycleLabel(Bitmap label) {
GalleryBitmapPool.getInstance().put(label);
}
}