I don’t have anymore time for Blue Bit Entertainment and I considered my Font 2 PNG program as its current state obsolote.
I recommend for Cerberus X projects FONTDU Bitmap Font Editor instead!
Here’s link to it: https://richpantson.itch.io/fontdu
Anyway, if you still use my old program below is some info:
In the dat file there are two 4 byte integers for each character. The first one is starting position (x-coordinate) of a character in the bitmap font, the second is the width of the character in the bitmap font in pixels.
Notice! In all the example programs below the ASCII range is 32 – 126; if range 0 – 255 is used the subtraction of 32 is not needed. When using the range of 0 – 255, remember also change the size of the arrays.
Example code to use font.png and font.dat files in Monkey X.
' Version 0.72 Import mojo Import brl.stream Import brl.filestream Function Main() New MyApp End Class MyApp Extends App Const FONT_HEIGHT:Int = 32 Global fontDat:Int[][] Global gfxFont:Image, gfxBG:Image Global width:Float,height:Float Method OnCreate() gfxFont = LoadImage("font.png") Local File:=FileStream.Open("monkey://data/font.dat","r") fontDat = allocateArray(94,2) For Local i:Int = 0 To 94 - 1 fontDat[i][0] = File.ReadInt() fontDat[i][1] = File.ReadInt() Next File.Close() width = DeviceWidth() height = DeviceHeight() End Method OnUpdate() End Method OnRender() SetColor 0,200,0 DrawRect 0,0,width,height SetBlend AdditiveBlend SetColor 255,255,0 drawString("123ABC",0,0) End Function drawString(text:String, x, y) Local len:Int = text.Length() Local chrs:Int[] chrs = text.ToChars() For Local i:Int = 0 To len - 1 DrawImageRect gfxFont, x, y, fontDat[chrs[i]-32][0], 0, fontDat[chrs[i]-32][1], FONT_HEIGHT x = x + fontDat[chrs[i]-32][1] Next End ' NEW! Added 07/19/2015 ' Returns string's width in pixels Function stringWidth:Int(text:String) Local len:Int = text.Length() Local chrs:Int[] Local length:Int chrs = text.ToChars() For Local i:Int = 0 To len - 1 length = length + fontDat[chrs[i]-32][1] Next Return length End Function allocateArray:Int[][](i:Int, j:Int) Local arr:Int[][] = New Int[i][] For Local index = 0 Until i arr[index] = New Int[j] Next Return arr End End Class
Constant FONT_HEIGHT must be inserted manually and is the height of the tallest character. In practice the height of the png-file.
Example code to use with mojo2 in Monkey X (with mojo2 fixed width bitmap fonts can be used):
Import mojo2 Function Main() New MyApp End Class MyApp Extends App Field canvas:Canvas Field font:Font Method OnCreate() canvas=New Canvas font = Font.Load("font.png",32,94,true) End Method OnRender() canvas.Clear .7,0,.7 canvas.SetFont font canvas.SetBlendMode 2 canvas.SetColor 1,1,0,1 canvas.DrawText "Sample text",DeviceWidth/2,DeviceHeight/2,.5,.5 canvas.Flush End End
Notice that if you’re for example working with Monkey X and try to save to “Game.data” folder new version of the font, the old contents can’t be overwritten. The font data must be saved elsewhere and then copied to “Game.data” folder.
Below is an example of use in a Java program with fixed width font:
The Java code:
import java.awt.*; import java.awt.image.BufferedImage; import javax.swing.*; import java.awt.event.WindowEvent; import java.awt.event.WindowAdapter; import java.io.File; import javax.imageio.ImageIO; import java.io.IOException; public class Example { private JFrame frame; private ExamplePanel panel; public Example() { frame = new JFrame("Bitmap Font Example"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); initialize(); frame.pack(); frame.setVisible(true); } private void initialize() { panel = new ExamplePanel(); frame.getContentPane().add(panel); } public static void main(String args[]) { new Example(); } } class ExamplePanel extends JPanel { public BufferedImage gfxFont; public ExamplePanel() { try { gfxFont = ImageIO.read(new File("./font.png")); } catch (IOException e) {System.exit(0);} setBackground(Color.lightGray); setPreferredSize(new Dimension(500,200)); } public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D)g; drawString(g,"Sample Text",60,60); } public void drawString(Graphics g, String text, int x, int y) { for (int i = 0; i < text.length(); i++) { // width of character is 34 pixels, height 56 pixels g.drawImage(gfxFont, x + i * 34, y , x + 34 * i + 34, y + 56, (text.charAt(i)-32) * 34, 0, (text.charAt(i)-32) * 34 + 34,56,null); } } }
And then example of non-fixed width usage:
The code:
import java.awt.*; import java.awt.image.BufferedImage; import javax.swing.*; import java.awt.event.WindowEvent; import java.awt.event.WindowAdapter; import java.io.File; import javax.imageio.ImageIO; import java.io.IOException; import java.io.FileInputStream; import java.io.DataInputStream; import java.io.BufferedInputStream; import java.io.FileNotFoundException; import java.nio.ByteBuffer; import java.nio.ByteOrder; public class Example { private JFrame frame; private ExamplePanel panel; public Example() { frame = new JFrame("Bitmap Font Example"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); initialize(); frame.pack(); frame.setVisible(true); } private void initialize() { panel = new ExamplePanel(); frame.getContentPane().add(panel); } public static void main(String args[]) { new Example(); } } class ExamplePanel extends JPanel { public BufferedImage gfxFont; public int[][] fontData = new int[94][2]; public ExamplePanel() { try { gfxFont = ImageIO.read(new File("./font.png")); } catch (IOException e) {System.exit(0);} DataInputStream inp = null; try { inp = new DataInputStream(new BufferedInputStream(new FileInputStream("./font.dat"), 752)); } catch (IOException e) {System.exit(0);} byte[] buffer = new byte[4]; ByteBuffer byteBuffer = ByteBuffer.allocate(4); try { for (int j=0; j < 94; j++) { for (int i=0; i < 2; i++) { inp.read(buffer); byteBuffer = ByteBuffer.wrap(buffer); fontData[j][i] = byteBuffer.order(ByteOrder.LITTLE_ENDIAN).getInt(); } } } catch (IOException e) {System.exit(0);} finally { try { if (inp != null) inp.close(); } catch (IOException ex) { ex.printStackTrace(); } } setBackground(Color.lightGray); setPreferredSize(new Dimension(500,200)); } public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D)g; drawString(g,"Sample Text",60,60); } public void drawString(Graphics g, String text, int x, int y) { int dx = 0; for (int i = 0; i < text.length(); i++) { // height is 74 pixels; dx = fontData[text.charAt(i)-32][1]; g.drawImage(gfxFont, x, y,x + dx, y + 74, fontData[(text.charAt(i)-32)][0], 0, fontData[(text.charAt(i)-32)][0] + fontData[text.charAt(i)-32][1],74,null); x = x + dx; } } }
Update!
The Monkey X code below works on Android systems:
Import mojo Import brl.databuffer Function Main() New MyApp End Class MyApp Extends App Const FONT_HEIGHT:Int = 37 Global fontDat:DataBuffer Global gfxFont:Image Method OnCreate() gfxFont = LoadImage("font.png") fontDat = New DataBuffer(95*4*2) ' 95 characters, for each character two 4 byte integers fontDat = DataBuffer.Load("monkey://data/font.dat") End Method OnUpdate() End Method OnRender() PushMatrix() Scale(DeviceWidth()/800.0,DeviceHeight()/600.0) Cls SetBlend AdditiveBlend SetColor 255,255,0 drawString("123ABC",(800 - stringWidth("123ABC")) / 2, (600 - 37) / 2) PopMatrix() End Function drawString(text:String, x, y) Local len = text.Length() Local chrs:Int[] chrs = text.ToChars() For Local i = 0 To len - 1 DrawImageRect gfxFont, x, y, fontDat.PeekInt((chrs[i]-32)*4*2), 0, fontDat.PeekInt((chrs[i]-32)*4*2 + 4), FONT_HEIGHT x = x + fontDat.PeekInt((chrs[i]-32)*4*2 + 4) Next End Function stringWidth:Int(text:String) Local len:Int = text.Length() Local chrs:Int[] Local length:Int = 0 chrs = text.ToChars() For Local i:Int = 0 To len - 1 length = length + fontDat.PeekInt((chrs[i]-32)*4*2+4) Next Return length End End Class
Feel free to use these codes.
I have a blog post regarding simple text scrollers in Monkey X (and Monkey2). The Monkey X version uses data files of Font 2 PNG, that can be downloaded. Good example in full how to use the files of Font 2 PNG.
See this and this blog post for code to scale a font made with Font 2 PNG in Monkey X. At the end of the posts is a video demonstration of the codes.
I’ve implemented also two examples of own font class to use with Font 2 PNG in Monkey X:
Here’s also a font class for Cerberus X:
I’ve used Font 2 PNG’s fonts in my Old School demonstrations like in the following: