When writing WeChat games, one of the problems that I often encountered was using various custom fontsthat are not pre-installed by most user devices. Since Wechat game platform have not give us the privilidgeto import those custom font files directly, we have no choice but using Bitmap font. I had done lots ofsearching but there is hardly a concrete implements of the bitmap font in JavaScript on the Internet thatcould be used by simply import a bitmap font class. So here is how I implement it in JavaScript. Feel freeto post any possible corrections or improvements.
A bitmap font is one that stores each glyph as an array of pixels (that is, a bitmap). It is less commonly known as a raster font. Bitmap fonts are simply collections of raster images of glyphs. For each variant of the font, there is a complete set of glyph images, with each set containing an image for each character. For example, if a font has three sizes, and any combination of bold and italic, then there must be 12 complete sets of images.
Here’s a short description of each attribute in the .fnt file:
Unscii is a set of bitmapped Unicode fonts based on classic system fonts. Unscii attempts to support character cell art well while also being suitable for terminal and programming use. The two main variants are unscii-8 (8×8 pixels per glyph) and unscii-16 (8×16). Bitmap Font Generator This program will allow you to generate bitmap fonts from TrueType fonts. The application generates both image files and character descriptions that can be read by a game for easy rendering of fonts. The program is freeware and open source, but a donation is greatly appreciated.
lineHeight | how much to move the cursor when going to the next line. |
base | this is the offset from the top of line, to where the base of each character is. |
scaleW and scaleH | This is the size of the texture. |
pages | gives how many textures that are used for the font. |
id | is the character number in the ASCII table. |
x, y, width, and height | give the position and size of the character image in the texture. |
xoffset and yoffset | hold the offset with which to offset the cursor position when drawing the character image. Note, these shouldn’t actually change the cursor position. |
xadvance | is how much the cursor position should be moved after each character. |
page | gives the texture where the character image is found. |
Here’s some pseudo code for rendering a character:
In the following illustration, I will use the black impact font as an example.Just note that the codes may not work by just copying and pasting. It’s just foryour reference and you may need some necessary modifications for it to work.
To generate bitmap font, you can use the Bitmap Font Generatorwhich will produce a .fnt
file and an image containing your choosing characters.
You can find a tutorial on how to use the Bitmap Font Generator here.
Image: The key of the image containing the font. Offset: If the font set doesn't start at the top left of the given image, specify the X/Y coordinate offset here. Characters: width: The width of each character in the font set. Height: The height of each character in the font set. Chars: The characters used in the font. Codehead’s Bitmap Font Generator Posted: 17 Mar 2015 at 00:08 by Codehead One of the big problems OpenGL runs into after you’ve got your first few polygons flying around the screen is the lack of a standard method for generating text within the API. Contribute to 1vanK/Urho3DBitmapFontGenerator development by creating an account on GitHub. Urho3D Bitmap Font Generator. License: Public Domain. SDF generator uses true brute force on GPU for maximum quality.
Since we are processing the bitmap font with JS, you need to convert the format of the .fnt
file to JSON
. You can achieve the by first generating the .fnt
file in XML
formatand then convert it to JSON
.
There is an awesome tool for you to convert XML
to JSON
online. You can find ithere
After getting the JSON
data, you can place it in a .js
file and store it as aconstant, which will be easier for us to use. Of course, you can place it in a .json
file as it should be and import it when needed. I put it in .js
file because I had tosince WeChat platform does not support read file API of JS.
The bitmap font file and corresponding image
Here is my impact_black.js
:
Here is my bitmap image:
I generated the JSON
data in one line and export it as a constant for later import.One thing to note that make sure you put the bitmap image in the same directory asthe font file.
Processing the font file
Create Bitmap Fonts
Create a class called BitmapFont
, which will parse the JSON
data for string toJS
object and store information including the positions of the characters on thebitmap image and the image itself. Note after the font image loaded, the passingfunction onloaded
will be executed.
Create a class called BitmapText
, which will take use of information stored inBitmapFont
and draw the characters on the canvas.
Bitmap Font Generator Github Generator
Then these two classes can be used by:
How to interpret the values in the font descriptor file
The image to the right illustrates some of the values found in the font descriptor file. The two dotted lines shows the lineHeight, i.e. how far the cursor should be moved vertically when moving to the next line.
The base value is how far from the top of the cell height thebase of the characters in the font should be placed. Characters can of courseextend above or below this base line, which is entirely up to the font design.
The filled red dot marks the current cursor position, and the hollow red dotmarks the position of the cursor after drawing the character. You get to this position by moving the cursor horizontally with the xadvance value. If kerning pairs are used the cursor should also be moved accordingly.
The yoffset gives the distance from the top of the cell height tothe top of the character. A negative value here would mean that the characterextends above the cell height. The xoffset gives the horizontal offsetthat should be added to the cursor position to find the left position where the character should be drawn. A negative value here would mean that the characterslightly overlaps the previous character. Observe that these values shouldn't be used to move the cursor position.
The green rectangle illustrates the quad that should be copied from the textureto the screen when rendering the character. The width and height gives the size of this rectangle, and x and y gives the position of the rectangle in the texture.
Rendering colored text with outline
Bitmap Font Maker
When the bitmap font has been generated with a baked outline, i.e. the outline is pre-generated in the font texture, the text is best rendered in two passes to avoid the outline for a character to overlap the previous character.
In the first pass the application should use only the alpha channel of the font texture as the transparency value when rendering the border.
In the second pass the application should use only the color channels of the font texture as the transparency value to render the characters over the border.
With a two-pass rendering like this it is also very easy to apply different colorsto the border and the internal characters dynamically without the need to pre-colorthe font in the texture. The application simply needs to multiply the transparency valuethe desired color before blending it to the screen.