IconicDroid icon indicating copy to clipboard operation
IconicDroid copied to clipboard

Easy addition of other fonts

Open Natanael1234 opened this issue 11 years ago • 0 comments

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

Now there are two classes, TypefaceManager and IconicFontDrawable

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<Integer, Typeface> typefaces = new Hashtable<Integer, Typeface>();

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 jut put the .ttf file(s) inside res/raw and, in Eclipse, choose Project->Clean... option.

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.

Natanael1234 avatar Nov 01 '14 18:11 Natanael1234