canvas

Using bitmap fonts

With this example we are going to demonstrate how to use bitmap fonts in an Android Application. Android is running on a wide variety of devices with lots of different screen sizes and resolutions.

So bitmap fonts can help you address the problem of using a consistent font face across different devices. For this tutorial we are going to use a monospaced font alphabet which means that all the characters have the same width and height.
 
 
 
 

In short, to create and use bitmap fonts you should:

  • create an image containing all the characters of the alphabet you want, with transparent background and copy it to a drawable Android resource foulders
  • measure the height and the width of a sample character on your image, in pixels
  • create a bitmap containing the character map
  • assosiate all the characters and numbers of the alphabet with a substet bitmap, derived from the main bitmap
  • use Glyphs an canvans to draw the sting you want on the screen

as shown in the code snippets below:

package net.obviam.fonts;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class DrawingPanel extends SurfaceView implements SurfaceHolder.Callback {

	private static final String TAG = DrawingPanel.class.getSimpleName();

	private Canvas canvas;		// the canvas to draw on
	private Glyphs glyphs;		// the glyphs

	public DrawingPanel(Context context) {
		super(context);
		// adding the panel to handle events
		getHolder().addCallback(this);

		// initialise resources
		loadResources();

		// making the Panel focusable so it can handle events
		setFocusable(true);
	}

	/**
	 * Loads the images
	 */
 	private void loadResources() {
		this.glyphs = new Glyphs(BitmapFactory.decodeResource(getResources(), R.drawable.glyphs_green));
		Log.d(TAG, "Green glyphs loaded");
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// draw text at touch
		try {
			canvas = getHolder().lockCanvas();
			synchronized (getHolder()) {
				if (event.getAction() == MotionEvent.ACTION_DOWN 
						|| event.getAction() == MotionEvent.ACTION_MOVE) {
					// clear the screen
					canvas.drawColor(Color.BLACK);
					// draw glyphs
					glyphs.drawString(canvas, "Drawing string at "
							+ (int) event.getX() + " " + (int) event.getY(),
							(int) event.getX(), (int) event.getY());
				}
				if (event.getAction() == MotionEvent.ACTION_UP) {
					canvas.drawColor(Color.BLACK);
					glyphs.drawString(canvas, "Drawn string at "
							+ (int) event.getX() + " " + (int) event.getY(),
							(int) event.getX(), (int) event.getY());
				}
			}
		} finally {
			if (canvas != null) {
				getHolder().unlockCanvasAndPost(canvas);
			}
		}
		// event was handled
		return true;
	}

	@Override
	protected void onDraw(Canvas canvas) {
	}

}
package net.obviam.fonts;

import java.util.HashMap;
import java.util.Map;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.util.Log;

public class Glyphs {

	private static final String TAG = Glyphs.class.getSimpleName();
	private Bitmap bitmap;	// bitmap containing the character map/sheet

	// Map to associate a bitmap to each character
	private Map<Character, Bitmap> glyphs = new HashMap<Character, Bitmap>(62);

	private int width;	// width in pixels of one character
	private int height;	// height in pixels of one character

	// the characters in the English alphabet
	private char[] charactersL = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g',
			'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
			'u', 'v', 'w', 'x', 'y', 'z' };
	private char[] charactersU = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G',
			'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
			'U', 'V', 'W', 'X', 'Y', 'Z' };
	private char[] numbers = new char[] { '1', '2', '3', '4', '5', '6', '7',
			'8', '9', '0' };

	public Glyphs(Bitmap bitmap) {
		super();
		this.bitmap = bitmap;
		this.width = 8;
		this.height = 12;
		// Cutting up the glyphs
		// Starting with the first row - lower cases
		for (int i = 0; i < 26; i++) {
			glyphs.put(charactersL[i], Bitmap.createBitmap(bitmap,
					0 + (i * width), 0, width, height));
		}
		Log.d(TAG, "Lowercases initialised");

		// Continuing with the second row - upper cases 
		// Note that the row starts at 15px - hardcoded
		for (int i = 0; i < 26; i++) {
			glyphs.put(charactersU[i], Bitmap.createBitmap(bitmap,
					0 + (i * width), 15, width, height));
		}
		// row 3 for numbers
		Log.d(TAG, "Uppercases initialised");
		for (int i = 0; i < 10; i++) {
			glyphs.put(numbers[i], Bitmap.createBitmap(bitmap,
					0 + (i * width), 30, width, height));
		}
		Log.d(TAG, "Numbers initialised");

		// TODO - 4th row for punctuation
	}

	public Bitmap getBitmap() {
		return bitmap;
	}

	/**
	 * Draws the string onto the canvas at <code>x</code> and <code>y</code>
	 * @param text
	 */
	public void drawString(Canvas canvas, String text, int x, int y) {
		if (canvas == null) {
			Log.d(TAG, "Canvas is null");
		}
		for (int i = 0; i < text.length(); i++) {
			Character ch = text.charAt(i);
			if (glyphs.get(ch) != null) {
				canvas.drawBitmap(glyphs.get(ch), x + (i * width), y, null);
			}
		}
	}
}
package net.obviam.fonts;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class PrintingActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

  // turn off title

  requestWindowFeature(Window.FEATURE_NO_TITLE);

  setContentView(new DrawingPanel(this));
    }
}

 
This was an example of how to Use Bitmap Fonts in Android.

Related Article:

Reference: Using Bitmap Fonts in Android from our JCG partner Tamas Jano at the “Against The Grain” blog.

Ilias Tsagklis

Ilias is a software developer turned online entrepreneur. He is co-founder and Executive Editor at Java Code Geeks.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button