atermenji/IconicDroid — pull request #18 by Natanael1234 (2014-11-01 18:06:19+00:00)
Title: Easy addition of other fonts

I modified the library to be easier to add new TrueTrype files:

Now there is two classes, TypefaceManager and

package com.atermenji.android.iconicdroid;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Hashtable;

import android.content.Context;
import android.content.res.Resources.NotFoundException;
import android.graphics.Typeface;
import android.util.Log;

class TypefaceManager {

private static Hashtable typefaces = new Hashtable();

private static final String TAG = "TypefaceManager";

public TypefaceManager() {
}

public Typeface removeTypeFace(int typefaceResourceId){
return typefaces.remove(typefaceResourceId);
}

public Typeface getTypeFace(Context context, int typefaceResourceId){
Typeface typeface = typefaces.get(typefaceResourceId);
if(typeface == null){
typeface = createTypefaceFromResource(context, typefaceResourceId);
typefaces.put(typefaceResourceId, typeface);
}
return typeface;
}

private static Typeface createTypefaceFromResource(Context context, final int resource) {
Typeface typeface = null;
InputStream inputStream = null;
OutputStream outputStream = null;

try {
inputStream = context.getResources().openRawResource(resource);
} catch (NotFoundException ex) {
Log.e(TAG, "Could not find typeface in resources.", ex);
}

String outPath = context.getCacheDir() + "/tmp.raw";

try {
byte[] buffer = new byte[inputStream.available()];
outputStream = new BufferedOutputStream(new FileOutputStream(outPath));

int l = 0;
while ((l = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, l);
}

typeface = Typeface.createFromFile(outPath);

new File(outPath).delete();
} catch (IOException ex) {
Log.e(TAG, "Error reading typeface from resource.", ex);
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException ex) {
Log.e(TAG, "Error closing typeface streams.", ex);
}
}

return typeface;
}
}
package com.atermenji.android.iconicdroid;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Hashtable;

import android.content.Context;
import android.content.res.Resources.NotFoundException;
import android.graphics.Typeface;
import android.util.Log;

class TypefaceManager {

private static Hashtable typefaces = new Hashtable();

private static final String TAG = "TypefaceManager";

public TypefaceManager() {
}

public Typeface removeTypeFace(int typefaceResourceId){
return typefaces.remove(typefaceResourceId);
}

public Typeface getTypeFace(Context context, int typefaceResourceId){
Typeface typeface = typefaces.get(typefaceResourceId);
if(typeface == null){
typeface = createTypefaceFromResource(context, typefaceResourceId);
typefaces.put(typefaceResourceId, typeface);
}
return typeface;
}

private static Typeface createTypefaceFromResource(Context context, final int resource) {
Typeface typeface = null;
InputStream inputStream = null;
OutputStream outputStream = null;

try {
inputStream = context.getResources().openRawResource(resource);
} catch (NotFoundException ex) {
Log.e(TAG, "Could not find typeface in resources.", ex);
}

String outPath = context.getCacheDir() + "/tmp.raw";

try {
byte[] buffer = new byte[inputStream.available()];
outputStream = new BufferedOutputStream(new FileOutputStream(outPath));

int l = 0;
while ((l = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, l);
}

typeface = Typeface.createFromFile(outPath);

new File(outPath).delete();
} catch (IOException ex) {
Log.e(TAG, "Error reading typeface from resource.", ex);
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException ex) {
Log.e(TAG, "Error closing typeface streams.", ex);
}
}

return typeface;
}
}

/*
* Copyright (C) 2013 Artur Termenji
*
* 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.atermenji.android.iconicdroid;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;

//import com.atermenji.android.iconicdroid.icon.Icon;

/**
* A custom {@link Drawable} which can display icons from icon fonts.
*/
public class IconicFontDrawable extends Drawable {

// private Context mContext;

private Paint mIconPaint;
private Paint mContourPaint;

private Rect mPaddingBounds;
private RectF mPathBounds;

private Path mPath;

private int mIconPadding;
private int mContourWidth;

private int mIntrinsicWidth;
private int mIntrinsicHeight;

private boolean mDrawContour;

// private Font mIcon;
private char[] mIconUtfChars;

private IconicFontDrawable() {
// mContext = getContext().getApplicationContext();

mIconPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

mContourPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mContourPaint.setStyle(Paint.Style.STROKE);

mPath = new Path();

mPathBounds = new RectF();
mPaddingBounds = new Rect();
}

IconicFontDrawable(Typeface typeface, int utfValue) {
this();
updateIcon(typeface, utfValue);
}

/**
* Loads and draws given {@link Font}.
*
* @param icon
*/
public void setIcon(Typeface typeface, int utfValue) {
updateIcon(typeface, utfValue);
invalidateSelf();
}

/**
* Set a color for the {@link Font}.
*
* @param color
*/
public void setIconColor(int color) {
mIconPaint.setColor(color);
invalidateSelf();
}

/**
* Set a padding for the {@link Font}.
*
* @param iconPadding
*/
public void setIconPadding(int iconPadding) {
mIconPadding = iconPadding;
if (mDrawContour) {
mIconPadding += mContourWidth;
}

invalidateSelf();
}

/**
* Set contour params for the {@link Font}.
* You should call {@link #drawContour(boolean)} method to enable contour.
*
* @param contourColor
* @param contourWidth
*/
public void setContour(int contourColor, int contourWidth) {
setContourColor(contourColor);
setContourWidth(contourWidth);
invalidateSelf();
}

/**
* Set contour color for the {@link Font}.
* You should call {@link #drawContour(boolean)} method to enable contour.
*
* @param contourColor
*/
public void setContourColor(int contourColor) {
mContourPaint.setColor(contourColor);
invalidateSelf();
}

/**
* Set contour width for the {@link Font}.
* You should call {@link #drawContour(boolean)} method to enable contour.
*
* @param contourWidth
*/
public void setContourWidth(int contourWidth) {
mContourWidth = contourWidth;
mContourPaint.setStrokeWidth(mContourWidth);
invalidateSelf();
}

/**
* Enable/disable contour drawing.
*
* @param drawContour
*/
public void drawContour(boolean drawContour) {
mDrawContour = drawContour;

if (mDrawContour) {
mIconPadding += mContourWidth;
} else {
mIconPadding -= mContourWidth;
}

invalidateSelf();
}

/**
* Set intrinsic width, which is used by several controls.
*
* @param intrinsicWidth
*/
public void setIntrinsicWidth(int intrinsicWidth) {
mIntrinsicWidth = intrinsicWidth;
}

/**
* Set intrinsic height, which is used by several controls.
*
* @param intrinsicHeight
*/
public void setIntrinsicHeight(int intrinsicHeight) {
mIntrinsicHeight = intrinsicHeight;
}

@Override
public void draw(Canvas canvas) {
// if (mIcon != null) {
final Rect viewBounds = getBounds();

updatePaddingBounds(viewBounds);
updateTextSize(viewBounds);
offsetIcon(viewBounds);

mPath.close();

if (mDrawContour) {
canvas.drawPath(mPath, mContourPaint);
}

canvas.drawPath(mPath, mIconPaint);
// }
}

@Override
public int getIntrinsicWidth() {
return mIntrinsicWidth;
}

@Override
public int getIntrinsicHeight() {
return mIntrinsicHeight;
}

@Override
public int getOpacity() {
return PixelFormat.OPAQUE;
}

@Override
public void setAlpha(int alpha) {
mIconPaint.setAlpha(alpha);
}

@Override
public void setColorFilter(ColorFilter cf) {
mIconPaint.setColorFilter(cf);
}

private void updateIcon(Typeface typeface, int utfValue) {
mIconUtfChars = Character.toChars(utfValue);
mIconPaint.setTypeface(typeface);
}

private void updatePaddingBounds(Rect viewBounds) {
if (mIconPadding >= 0
&& !(mIconPadding * 2 > viewBounds.width())
&& !(mIconPadding * 2 > viewBounds.height())) {
mPaddingBounds.set(
viewBounds.left + mIconPadding,
viewBounds.top + mIconPadding,
viewBounds.right - mIconPadding,
viewBounds.bottom - mIconPadding);
}
}

private void updateTextSize(Rect viewBounds) {
float textSize = (float) viewBounds.height() * 2;
mIconPaint.setTextSize(textSize);

mIconPaint.getTextPath(mIconUtfChars, 0, mIconUtfChars.length,
0, viewBounds.height(), mPath);
mPath.computeBounds(mPathBounds, true);

float deltaWidth = ((float) mPaddingBounds.width() / mPathBounds.width());
float deltaHeight = ((float) mPaddingBounds.height() / mPathBounds.height());
float delta = (deltaWidth < deltaHeight) ? deltaWidth : deltaHeight;
textSize *= delta;

mIconPaint.setTextSize(textSize);

mIconPaint.getTextPath(mIconUtfChars, 0, mIconUtfChars.length,
0, viewBounds.height(), mPath);
mPath.computeBounds(mPathBounds, true);
}

private void offsetIcon(Rect viewBounds) {
float startX = viewBounds.centerX() - (mPathBounds.width() / 2);
float offsetX = startX - mPathBounds.left;

float startY = viewBounds.centerY() - (mPathBounds.height() / 2);
float offsetY = startY - (mPathBounds.top);

mPath.offset(offsetX, offsetY);
}

public static IconicFontDrawable getDrawable(Context context, int typefaceResourceId, int utfValue){
Typeface typeface = new TypefaceManager().getTypeFace(context, typefaceResourceId);
IconicFontDrawable drawable = new IconicFontDrawable(typeface, utfValue);
return drawable;
}
}

To use in your project just add the .ttf files on res/raw directory and choose to Project->Clean... on Eclipse.

IconicFontDrawable drawable = IconicFontDrawable.getDrawable(mContext, R.raw.roboto_bold, '$');
// you also can use the hex value of the character instead of a char as the second argument.