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.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) {
		// adding the panel to handle events

		// initialise resources

		// making the Panel focusable so it can handle events

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

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

	public void surfaceCreated(SurfaceHolder holder) {

	public void surfaceDestroyed(SurfaceHolder holder) {

	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
					// 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) {
					glyphs.drawString(canvas, "Drawn string at "
							+ (int) event.getX() + " " + (int) event.getY(),
							(int) event.getX(), (int) event.getY());
		} finally {
			if (canvas != null) {
		// event was handled
		return true;

	protected void onDraw(Canvas canvas) {

package net.obviam.fonts;

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

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) {
		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.os.Bundle;
import android.view.Window;

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


  // turn off 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.

Want to know how to develop your skillset to become a Java Rockstar?

Join our newsletter to start rocking!

To get you started we give you our best selling eBooks for FREE!


1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design


and many more ....


Receive Java & Developer job alerts in your Area

I have read and agree to the terms & conditions


Ilias Tsagklis

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

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

Inline Feedbacks
View all comments
Back to top button