/* * 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 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 { 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); } }