Home » Android » games » canvas » Using bitmap fonts

About Ilias Tsagklis

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

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.

0 0 vote
Article Rating

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

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

 

Subscribe
Notify of
guest
The comment form collects your name, email and content to allow us keep track of the comments placed on the website. Please read and accept our website Terms and Privacy Policy to post a comment.

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

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x