FontType HowTo: Displaying fonts

This file will help you display fonts in your own programs.
The template file included will get you started.


'TEMPLATE.BAS
'A program that will serve as your template for font-displaying
'Started 5/30/96 by Chris Sequeira

'all integers
DEFINT A-Z

'sub to show the font
DECLARE SUB PrintFont (text$, font(), rowNy, columnNx, col, mode)

'NEEDED global variables
COMMON SHARED fontYsize     'font height
COMMON SHARED startascii, endascii  'ASCII range

COMMON SHARED textY 'standard text height
'****************************************************************
textY = 16  'replace 16 with the character height for your screen mode.
		'16 is the height for SCREEN 12 and 8 is the height for
		'SCREEN 13.

'code to LOAD. Replace file$ with the name of your font (in quotes,
'plus the .FNT extension). Repeat this code for as many fonts as you
'need, or create a SUB and pass it the font array after creating it like
'this: REDIM font(0,0,0)
OPEN file$ FOR BINARY ACCESS READ AS #1
	  GET #1, , id
	  GET #1, , fontYsize
	  GET #1, , startascii
	  GET #1, , endascii

	  REDIM font(startascii TO endascii, 8, fontYsize)
	  FOR i = startascii TO endascii
			FOR y = 1 TO fontYsize
				  GET #1, , fontval
				  mask = &H80
				  FOR x = 8 TO 1 STEP -1
						IF fontval AND mask THEN font(i, x, y) = 1
						mask = mask / 2
				  NEXT x
			NEXT y
	  NEXT i
CLOSE


'begin displaying. Change SCREEN 12 to any other screen mode except text
'mode.
SCREEN 12

'here's where you print the font! Replace text$ with some text.
'Replace rowNy with a text row or a pixel Y location.
'Replace columnNx with a text column or a pixel X location.
'Replace col with the desired color. Mode is the printing mode.
'0 to print by rows and columns, any other value to print by pixels.

PrintFont text$, font(), rowNy, columnNx, col, mode
END

SUB PrintFont (text$, font(), rowNy, columnNx, col, mode)
'this sub does the work!
	  IF mode = 0 THEN
			x = (columnNx - 1) * 8 - 1: y = (rowNy - 1) * textY - 1
	  ELSE
			x = columnNx: y = rowNy
	  END IF

	  FOR printem = 1 TO LEN(text$)
			daOne = ASC(MID$(text$, printem, 1))
			IF daOne >= startascii AND daOne <= endascii THEN
				  FOR i = 1 TO 8
						FOR j = 1 TO fontYsize
							  IF font(daOne, i, j) THEN
									PSET (x + i, y + j), col
							  END IF
						NEXT j
				  NEXT i
			END IF
		x = x + 8
	  NEXT printem
END SUB


As you see in the code, PrintFont is the main displaying sub. But first,
let's go over the code step by step, starting with global variables.


'NEEDED global variables
COMMON SHARED fontYsize     'font height
COMMON SHARED startascii, endascii  'ASCII range

COMMON SHARED textY 'standard text height


The variable fontYsize is the height of the loaded font. startascii and
endascii contain the range for the font. textY is the height of the
STANDARD character set for that screen mode. All you need to do is set
the variable textY; other globals are set when loading a font.

Next is OPENING a font. All files are opened for BINARY READING.


'code to LOAD. Replace file$ with the name of your font (in quotes,
'plus the .FNT extension). Repeat this code for as many fonts as you
'need, or create a SUB and pass it the font array after creating it like
'this: REDIM font(0,0,0)
OPEN file$ FOR BINARY ACCESS READ AS #1
	  GET #1, , id
	  GET #1, , fontYsize
	  GET #1, , startascii
	  GET #1, , endascii

	  REDIM font(startascii TO endascii, 8, fontYsize)
	  FOR i = startascii TO endascii
			FOR y = 1 TO fontYsize
				  GET #1, , fontval
				  mask = &H80
				  FOR x = 8 TO 1 STEP -1
						IF fontval AND mask THEN font(i, x, y) = 1
						mask = mask / 2
				  NEXT x
			NEXT y
	  NEXT i
CLOSE


As it says, replace file$ with the filename of the font, including the
.FNT extension. What does this code do?

	GET #1, , id
	GET #1, , fontYsize
	GET #1, , startascii
	GET #1, , endascii

This code gets the fontYsize, and ranges. What's the id variable for?
This tells the program if the file is a FontType font file or not. A 
FontType file ALWAYS has an id of 22. Be sure to test for that in the real
program; the template file and the program FONTTEST.BAS do not test for
that.

	  REDIM font(startascii TO endascii, 8, fontYsize)
	  FOR i = startascii TO endascii
			FOR y = 1 TO fontYsize
				  GET #1, , fontval
				  mask = &H80
				  FOR x = 8 TO 1 STEP -1
						IF fontval AND mask THEN font(i, x, y) = 1
						mask = mask / 2
				  NEXT x
			NEXT y
	  NEXT i

This code creates the font array (REDIM font) using the values loaded.
Then there's the magic: The file actually contains NUMBERS, not 1's and
0's as you might have thought. When you save, FontType treats the
ON and OFF pixels as BITS and puts them together to make a decimal number.  
The code above BREAKS the number down and puts the resulting BITS into 
the font array. That's why an 8x8 chracter is only 8 bytes, not 64. 
Nifty, eh?


After loading comes displaying!!! The sub PrintFont does this.
Here's the syntax:

PrintFont (text$, font%(), rowNy%, columnNx%, col%, mode%)

text$ is the text YOU give PrintFont to serve as the basis for font 
displaying. font%() is an integer array which contains the font data
you want to use. rowNy% is an integer which holds the row or pixel
Y location to print at. columnNx% is an integer which holds the COLUMN
or pixel X location to print at. The 2 location variables can be pixels
or rows and columns, but they must be the same type. One can't hold
pixels while the other holds rows or columns. col% is an integer which
holds the desired color value. mode% is an integer which tells what location
type is given to it. This is VERY important. A value of 0 tells PrintFont to
display using rows and columns; any other value makes PrintFont print using 
pixels.


SUB PrintFont (text$, font(), rowNy, columnNx, col, mode)
'this sub does the work!
	  IF mode = 0 THEN
			x = (columnNx - 1) * 8 - 1: y = (rowNy - 1) * textY - 1
	  ELSE
			x = columnNx: y = rowNy
	  END IF

	  FOR printem = 1 TO LEN(text$)
			daOne = ASC(MID$(text$, printem, 1))
			IF daOne >= startascii AND daOne <= endascii THEN
				  FOR i = 1 TO 8
						FOR j = 1 TO fontYsize
							  IF font(daOne, i, j) THEN
									PSET (x + i, y + j), col
							  END IF
						NEXT j
				  NEXT i
			END IF
	  NEXT printem
END SUB

First, PrintFont converts the location to the desired values: rows and
columns, or pixels. Then it goes through a printing loop. This line

daOne = ASC(MID$(text$, printem, 1))

gets the next character in the value text$. It scans through the font array
for that value and plots the pixels down. One thing, though: If the character
is not found, your program will crash with a "Subscript out of range" error.
Be sure to only print characters the font array has, remember the 
ASCII limits.

That's all there is to it!! Only one more thing: since PrintFont plots 
pixels, fonts will not overwrite what's behind them with a blank space.
This is good, AND bad. If you want to write OVER other text, you either
have to clear the ROW and COLUMN with this line:

COLOR 0
LOCATE ROW, COLUMN: PRINT SPACE$(spacenum%)
COLOR 15

or clear the PIXEL location with this LINE:

LINE (leftX%, topY%) - (rightX%, bottomY%), 0, BF.

Replace 0 with the color you want.

HAVE FUN, and email us at nav2@flash.net for any other questions.
