How do you create and work with image fonts?



1. Introduction



Would you like to make your own fonts, but don't really know how that well? Do you want some strategies and tips on how to make them? Well, you've come to the right place. This tutorial will explain most everything I can think of that I know about making fonts. In the various images I have around, clicking on them brings a full-size version (1600x1200 pixels). To prevent unwanted stretching, I've shrunk them down to half the size via the HTML image width and height attributes. They are all PNG format which keeps true color in tact and PNG does better than JPG in compression with these screenshots.

2. Creating the image



2.1 Planning your font



First, plan how big you want your characters to be. Don't forget to have spare space on the bottom for the letters that go below the normal mean, such as g, j, p, q, and y. A hint would be to know the height of your capital letters then add about 30% to that height. The smallest a font can be and still be legible is 3 by 5 pixels for the letters and most of the punctuation. At least 5 by 7 is recommended. A font I've long worked with is called "Digital Octagon". I named it so because there are only 8 possible directions the lines can go in. The capital letters are 5 wide by 7 wide. I would like to allow 2 pixels below for underlining and the "dunker letters", 1 pixel of white space on the left, 2 pixels of white space on the right, and one pixel of white space at the bottom. This means that the font letters need to be 8 wide by 10 high.

2.2 Determining image dimensions



With the decision made on a font being 8 wide by 10 high, we now need to create the image. Let's stick with a 128-character font (characters 00 through 7F). The letters need to be arranged in a grid 32 wide by 4 high. Then, open up whatever graphics editor you like. I prefer MSPaint because I'm acquainted very well with it. Because the characters are 8 pixels wide by 10 pixels high and that the characters are arranged on a 32 by 4 grid, you'll need an image size of 256 by 40. To calculate the image size, use this formula:

IW = CW*32
IH = CH*4 // OR // IH = CH*8

vars:
IW = image width;
CW = character width; // 8 in this example
IH = image height;
CH = character height; // 10 in this example

In the example, IW = 256 and IH = 40. From now on, CW represents character width (8 in the example) and CH represents character height (10 in the example).

2.3 Boxes help you position your characters



Now that you know the height, it's time to draw the characters. To help with positioning, draw a box of pixels that is CW by CH. It is highly recommended that you use a different color from black or white, typically a mid-level gray (or 96, 96, 96) or lighter, but I don't recommend going brighter than 224, 224, 224 otherwise it gets too hard to see. Highly recommended is that you use an odd color such as 53, 170, 158. Now, select the box you made and copy it to the clip board then paste it. Move the pasted item so that the top part of it matches with the bottom part of the original. You should get a line that's two pixels wide. Now paste the object again and move it toward the bottom again and paste it once more. If done correctly, there should be no white lines of pixels at the bottom left and there should be 4 full rectangles. If not, either your image size is not correct or you copied and pasted wrong. Up to this point, you should get something like this:



Now, select all four of those rectangles and copy them to the clipboard. Paste the objects and move them just to the left so that the left sides of the pasted objects matches the right side of the original without overlap. Select the rectangles again and copy them then paste them. Move the rectangles to the right so they join up with the original set. Paste it again and once more positioning them. You should now have 8 rectangles by 4. Finally, select all of the rectangles again, copy them and paste and position them joining them together until the entire area is covered in rectangles. If done correctly, you should see no white along the edges. It should look like this:



2.4 Drawing your characters



The next stage is to draw your letters in ASCII order*. However, leave the entire top row of rectangles empty. Start your design on the second row. Leave the first area blank and go to the one on the right, character 21, the exclamation point. At this stage, don't bother with color. Just use black for now. As the first character is done, do the next, 22 (the double-quotation marks) to the right of the previous. When you reach the end of a row, go down to the next row on the left, just as if you were reading a book. Your characters don't have to be letters or numbers, they could be pictures too, a flag on a pole, a box in 3D, anything. You may allow one pixel to get into the boxes and the opposite side must be empty. Any more than one pixel and you may notice strange things with otherwise adjacent characters. What I mean by opposite side is, if the pixels were on the top of the block, the bottom part for that character must be empty. If it's not, the font may be a little hard to read. When using picture fonts that occupy many blocks, however, this is acceptable. When you get done, you should have something like this at this point:



Notice that I've got one pixel of overlap into the boxes mainly along the top and how the bottom area is left blank? This allows for adequate spacing to make it more legible.

2.5 Finalizing and cleanup



From here, you can provide the decorations you want as you please. In my example, I'm using a mixed spectrum of 8 colors. You can color and design your letters however you want. If your design spreads out onto the rectangles, you may use the bucket fill tool and fill all the rectangles with the background color. This is why I mentioned to use a different color than white or black. When you're done designing your characters as you want them, it's time for cleanup. If you haven't done it already, using the bucket fill tool, fill the rectangles with the background color to get rid of the rectangles. A finished font would resemble something like this:



3 Using your new font



To make your font of use, you'll need to open your script editor, SED. In it, define a font object, preferrably near the top. Add a line like this:

font name_of_your_font = "filenameoffont.bmp", CW, CH;


name_of_your_font - the name you want to give your font as described in text objects.
filenameoffont.bmp - the file name of your font. You can use something other than BMP as the file type.
CW - your character width (as from in section 2.1 and 2.2; use a number here)
CH - your character height (as from in section 2.1 and 2.2; use a number here)

If you want to see your font in the game engine, use a text object like this:
text name_of_text_object
{
	pos_x = 0;
	pos_y = 0;
	layer = 10;
	font = name_of_your_font; // use your font name as you named in the font object above.
	string = my_string;
	flags = visible; // makes the text object visible by default
}


definitions of code:
name_of_text_object = name your text object; // When you want to change various things later, such as hiding and unhiding it, knowing the name of your text object will help.
pos_x = the position the object will be at on the screen; // The actual position for the first character is the top left corner of the box for the first character in the string (such as s or +)
pos_y = the position the object will be at on the screen; // see note above for details
layer = the object's layer; // the higher the number, the more objects it'll appear above. For example, if you have a transparent dark gray panel (alpha at 64 of 255) at layer 8 and you have the text object at layer 10, the text will appear fully. If the text object was on layer 7 or below, the text would be made a different color due to the transparency effects of the panel.
font = what font you want to use; // this is the same as the font you defined earlier using the font object. string = what string to use; // the string can be either one from a string defined earlier or a new one. If using a new one, just add a pair of double quotes and insert text inside the quotes. to use a double quotation mark, insert /". For a hard return, use /n.
flags = flags to be set; // the most common flags are visible and refresh. Consult the manual for others.

Then, just run the engine (no builds are required) and you should be able to see it. If not, see section 4 for troubleshooting.

4 Troubleshooting



Font not working? Characters coming out not as expected? This section will help you solve some of the typical problems.

Problem 1: When I run the engine, I get range over/underrun errors.
Solution 1: This is caused from having invalid values in your font object. The most common case is getting the CW and CH values flipped around. The other case is that something in your original image doesn't add up evenly. For example, if you're CH was 10 pixels but your image is 36 pixels high, change your CH to CH4 (for 128 character maps) or CH8 (for 256 character maps).

Problem 2: My characters are disaligned!
Solution 2: Character disalignment is caused by unequal spacing in your image. The reason for making the rectangles is to help prevent this and make it easier to space the characters properly. To fix it, adjust the characters the best you can and insert the rectangle grid over them. With the rectangle grid now in place, realign your chracters from here. When you're done, just bucket fill the rectangles away.

Problem 3: My font seems too small!
Solution 3: If your font seems too small, it could either be because you're using too small of an image or too high of a resolution. In any case, you can simply create another file identical to your main one but stretch it to 200% of the size to make it bigger, though you might want to do some touchups otherwise it might look too pixellated. I suggest that you design one font targetted for resolutions of up to 1024x768 then one double the size for resolutions above this.

Problem 4: How do I design shadows?
Solution 4: To design shadows, you might need the alpha channel. Half transparent black is typical and can be varied. This would be that same font above with shadows:


I used the GIMP to process this and the shadows go toward the bottom right. A shadow is basically a copy of the characters, but made transparent of a black color and shifted some number of pixels, usually one, in any direction.

Problem 5: How do I make a quick bold and italicized version of my font?
Solution 5: A quick bold takes about 10 seconds. In MSPaint, once you've gotten rid of your boxes, use the eyedropper tool and choose the background color by right-clicking on it. Then, press control+A then, while holding control, press C then V to paste a duplicate. Choose the "draw opaque" option to make the background contents transparent and move your selection one pixel to the left or right, however you want it. For a quick italicized version, it'll take longer, but it's still rather fast. First, find the center of your character along the vertical axis. Select the bottom 1/3 of your character using the select tool and shift it one pixel to the left. Select the entire top third and shift it one pixel to the right. For a steeper italicization, select in terms of 1/4, 1/5, etc. instead of 1/3. I recommend that for every three pixels from the bottom, the upper areas get shifted by one pixel, though you can change this however you want. Here's an example of what I mean by this using the 1/3 method (with bold and underline effects included):



For both bold and italic, first, do the italic version (open up your italic version of your font) and apply the quick bold tactic and save your file. When naming your fonts using different styles, I suggest using b, i, or bi for bold.

For a quick underline, needing about ten seconds, from near the bottom of where the boxes normally would've been (remember to allow at least one pixel of clearance), just draw a straight horizontal line from end to end. The underline doesn't have to obey the 1-pixel clearance concept so only one long straight line is all that's needed per row of characters. When naming your fonts using styles, just use the u to indicate underline such as "font digital_octagon_bu = "digital octagon bu.bmp";" for bold and underline all in one.

Footnotes:
* The order of ASCII has some parts of it in a recognizable order, while others, typical of punctuation, are not in any specific order. Here's a list of the entire ASCII table from 00 to FF: For some unknown reason, character AD doesn't show up....

This row contains special characters such as tabs and returns
  ! " # $ % & ' ( ) * + , - . /
0 1 2 3 4 5 6 7 8 9 : ; < = > ?

@ 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 [ \ ] ^ _

` 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 { | } ~ 

               
               

               
               

               
               

               
               


Beyond the fourth row are characters not available by normal means. To use them, take out character map and go from there. When making your font, each group of two represents a row. The top line of each group is on the left and the bottom line of each group is on the right. If you're making a 128-character font, just use the first three groups of the bigger letters. If you're making a 256-character font, use all groups.