Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Easy addition of other fonts #18

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Easy addition of other fonts #18

wants to merge 2 commits into from

Conversation

Natanael1234
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants