Skip to content

Commit 3fafdb3

Browse files
Merge pull request #392 from CE-Programming/update-convfont
Update convfont
2 parents 0a083a2 + 4726d40 commit 3fafdb3

File tree

2 files changed

+140
-34
lines changed

2 files changed

+140
-34
lines changed

docs/libraries/fontlibc.rst

Lines changed: 139 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,104 @@ fontlibc.h
77
88
#include <fontlibc.h>
99
10-
The :code:`fontlibc` library provides routines for displaying custom fonts and glyphs, and can be used to extend the limited font capabilities of :ref:`graphx <graphx_h>`.
10+
The :code:`fontlibc` library provides routines for displaying custom fonts and glyphs,
11+
and can be used to extend the limited font capabilities of :ref:`graphx <graphx_h>`.
1112

1213
The :code:`fontlibc` library was designed under a "mechanism not policy" sort of philosophy.
13-
Rather than attempting to provide as many fancy features as a programmer could want, fontlibc tries to provide fast, basic routines that can be used to build the additional functionality you want.
14+
Rather than attempting to provide as many fancy features as a programmer could want,
15+
fontlibc tries to provide fast, basic routines that can be used to build the additional functionality you want.
1416
For example, word-wrap is not directly provided, but can be implemented using :code:`fontlib_SetAlternateStopCode` and :code:`fontlib_GetStringWidth`.
15-
fontlibc hopes to provide enough performance to be usable in games, while providing powerful enough basic features for fancy GUIs and document editors.
17+
fontlibc hopes to provide enough performance to be usable in games,
18+
while providing powerful enough basic features for fancy GUIs and document editors.
1619

1720
.. contents:: :local:
1821
:depth: 3
1922

2023
Creating Fonts
2124
--------------
2225

23-
Fonts for use with fontlibc can be made with any program that can produce Windows 3.x .FNT resource files.
24-
25-
Editor Software
26-
~~~~~~~~~~~~~~~
27-
28-
`Fony <http://hukka.ncn.fi/?fony>`_ is probably the most-used FNT editor available. It can open both .FNT and .FON files.
29-
30-
`mkwinfont <https://github.com/juanitogan/mkwinfont>`_ provides some Python code for converting a text-based format to and .FON files; it should be trivial for someone with basic Python skills to change to code to skip the .FON packaging stage and directly produce a .FNT resource file. Useful if for some reason you think graphics are best done without the aid of any kind of graphics editor.
26+
Fonts for use with :code:`fontlibc` can be made with any program that can produce Windows 3.x .FNT resource files.
27+
Alternatively, the :code:`convfont` utility also supports creating fonts using a simple ASCII art format.
28+
29+
GUI Editor Software
30+
~~~~~~~~~~~~~~~~~~~
31+
32+
`Fony <http://hukka.ncn.fi/?fony>`_ is probably the most-used FNT editor available.
33+
It can open both .FNT and .FON files.
34+
35+
`mkwinfont <https://github.com/juanitogan/mkwinfont>`_ provides some Python code for converting a text-based format to and .FON files;
36+
it should be trivial for someone with basic Python skills to change to code to skip the .FON packaging stage and directly produce a .FNT resource file.
37+
Useful if for some reason you think graphics are best done without the aid of any kind of graphics editor.
38+
39+
`VSoft's FontEdit <http://www.vsoft.nl/software/utils/win/fontedit/>`_ is mostly just the original FontEdit included
40+
with the Windows SDK for Windows 3.x, but compiled for 32-bit Windows.
41+
A notable addition, however, is the ability to import TrueType fonts, though I haven't tested it.
42+
It cannot, however, open .FON files; the FNT resource(s) embedded in a .FON file must be extracted before FontEdit can open the font(s).
43+
44+
`MFE <https://github.com/drdnar/MFE>`_ is DrDnar's own bitmap font editor.
45+
It can export .FNT files.
46+
It has the useful feature of allowing fully custom mapping from Unicode to your font's 8-bit code page,
47+
which makes creating mock-ups with the preview function easier.
48+
49+
Manually Creating a Font
50+
~~~~~~~~~~~~~~~~~~~~~~~~
51+
52+
You can also create a font manually with your favorite text editor.
53+
Characters in most monospaced fonts are about twice as tall as they are wide, so a :code:`double width` mode is supported.
54+
If set to :code:`true`, two characters from the input file are read for each pixel, halving the width.
55+
56+
The first line of text in the file must be :code:`convfont`.
57+
After that, specify metadata about the font by separating a tag from its value with a colon.
58+
A :code:`height` tag is required at a minimum here.
59+
For monospaced fonts, use the :code:`fixed width` tag to set the width.
60+
The metadata block is terminated with a :code:`Font data` tag.
61+
62+
.. code-block::
63+
convfont
64+
Double width: true
65+
Height: 8
66+
Fixed width: 6
67+
x-height: 2
68+
Baseline: 7
69+
: You can make a comment by starting a line with a colon.
70+
Font data:
71+
72+
After the metadata comes the information for each glyph.
73+
For variable width fonts, you should specify a :code:`width` for each glyph.
74+
Making the image is simple: anything that isn't a space is a set pixel.
75+
76+
.. code-block::
77+
Code point: 'A'
78+
: Instead of using a character literal, you could put a number like 65 or 0x41; or use an escape sequence like '\101'.
79+
: There is no need to specify a width because this is a fixed-width font.
80+
Data:
81+
******
82+
** **
83+
** **
84+
**********
85+
** **
86+
** **
87+
** **
88+
89+
: Since B comes after A, there is no need to specify that this is B.
90+
Data:
91+
########
92+
## ##
93+
## ##
94+
########
95+
## ##
96+
## ##
97+
########
3198
32-
`VSoft's FontEdit <http://www.vsoft.nl/software/utils/win/fontedit/>`_ is mostly just the original FontEdit included with the Windows SDK for Windows 3.x, but compiled for 32-bit Windows. A notable addition, however, is the ability to import TrueType fonts, though I haven't tested it. It cannot, however, open .FON files; the FNT resource(s) embedded in a .FON file must be extracted before FontEdit can open the font(s).
99+
: Note that comments are not accepted inside bitmaps; they would just be treated as bitmap data.
33100
34-
`MFE <https://github.com/drdnar/MFE>`_ is DrDnar's own bitmap font editor. It can export .FNT files. It has the useful feature of allowing fully custom mapping from Unicode to your font's 8-bit code page, which makes creating mock-ups with the preview function easier.
101+
For more details, consult the :code:`convfont` readme.
35102

36103
Using Fonts in Your Project
37104
~~~~~~~~~~~~~~~~~~~~~~~~~~~
38105

39-
Once your .FNT file has been created, use the convfont utility included with the SDK to convert the .FNT resource file into a format usable in your project.
106+
Once your .FNT file has been created,
107+
use the convfont utility included with the SDK to convert the .FNT resource file into a format usable in your project.
40108

41109
There are two main ways of including a font in your project:
42110

@@ -46,7 +114,9 @@ There are two main ways of including a font in your project:
46114
Embedding a Font Directly in Your Program
47115
.........................................
48116

49-
Embedding a font directly in your program ensures the font will always be available, but it prevents it from being used by any other program, and bloats your program. However, it is also the easiest way to access a custom font.
117+
Embedding a font directly in your program ensures the font will always be available,
118+
but it prevents it from being used by any other program, and bloats your program.
119+
However, it is also the easiest way to access a custom font.
50120

51121
Place your .FNT font files in your source code directory. Then, create a :code:`myfonts.h` source code file:
52122

@@ -75,7 +145,8 @@ Then create a :code:`myfonts.c` file:
75145
};
76146
const fontlib_font_t *my_font_2 = (fontlib_font_t *)my_font_2_data;
77147
78-
Now you should be wondering where the :code:`myfont1.inc` file comes from. This file will get generated by your makefile, which will need to be modified to append the following:
148+
Now you should be wondering where the :code:`myfont1.inc` file comes from.
149+
This file will get generated by your makefile, which will need to be modified to append the following:
79150

80151
.. code-block:: make
81152
@@ -103,11 +174,18 @@ Finally, somewhere else in your program, you can use :code:`fontlib_SetFont`:
103174
Packaging a Font Pack
104175
.....................
105176

106-
Font packs are an alternative to directly embedding a font in your program binary. They allow multiple related fonts to be packaged together, and FontLibC can select a font from the font pack given a requested size and style. The fonts in a font pack can be used by other programs, reducing the size of your program and saving valuable space on-calculator. They can also be archived, freeing up limited RAM.
177+
Font packs are an alternative to directly embedding a font in your program binary.
178+
They allow multiple related fonts to be packaged together,
179+
and FontLibC can select a font from the font pack given a requested size and style.
180+
The fonts in a font pack can be used by other programs, reducing the size of your program and saving valuable space on-calculator.
181+
They can also be archived, freeing up limited RAM.
107182

108-
A font pack should contain related fonts, namely different sizes and styles of a typeface. It is legal for a font pack to contain only one font. Metadata fields in a font pack, such as the description, should be *short.*
183+
A font pack should contain related fonts, namely different sizes and styles of a typeface.
184+
It is legal for a font pack to contain only one font.
185+
Metadata fields in a font pack, such as the description, should be *short.*
109186

110-
Font packs are easiest to make as a separate project. Create a new folder, place your :code:`.fnt` files in it, and then create a :code:`makefile` with the following contents:
187+
Font packs are easiest to make as a separate project.
188+
Create a new folder, place your :code:`.fnt` files in it, and then create a :code:`makefile` with the following contents:
111189

112190
.. code-block:: make
113191
@@ -131,9 +209,14 @@ Font packs are easiest to make as a separate project. Create a new folder, place
131209
Using Font Packs
132210
----------------
133211

134-
While using an embedded font is easy—just call :code:`fontlib_SetFont` directly on the pointer to the font data—, using a font pack is a bit more involved.
212+
While using an embedded font is easy—just call :code:`fontlib_SetFont` directly on the pointer to the font data—,
213+
using a font pack is a bit more involved.
135214

136-
**WARNING: FontLibC caches a pointer to the font's data when you use** :code:`SetFont`. **If you do something that causes the font's data to move, that pointer becomes invalid and FontLibC will start displaying garbage!** For example, if a font appvar is in RAM, any operation that creates or resizes a file may invalidate the cached pointer. Simply calling :code:`SetFont` again will not suffice to fix this; you must also lookup the font's location again. This also applies if a font pack is archived, and you do something that causes a garbage collection cycle.
215+
**WARNING: FontLibC caches a pointer to the font's data when you use** :code:`SetFont`.
216+
**If you do something that causes the font's data to move, that pointer becomes invalid and FontLibC will start displaying garbage!**
217+
For example, if a font appvar is in RAM, any operation that creates or resizes a file may invalidate the cached pointer.
218+
Simply calling :code:`SetFont` again will not suffice to fix this; you must also lookup the font's location again.
219+
This also applies if a font pack is archived, and you do something that causes a garbage collection cycle.
137220

138221
(The above warning does not apply to fonts embedded into your program, as data embedded in your program cannot get moved.)
139222

@@ -165,7 +248,9 @@ If you require a specific font pack with a specific appvar name, then opening a
165248
Caching a Font Pack's Address
166249
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
167250

168-
However, accessing fonts this way triggers a slow VAT lookup for the appvar every time you call a :code:`GetFont` routine. You can avoid this overhead—provided you keep in mind the above warning about moving data around—by using the FileIOC library to get a direct pointer to the appvar's data.
251+
However, accessing fonts this way triggers a slow VAT lookup for the appvar every time you call a :code:`GetFont` routine.
252+
You can avoid this overhead—provided you keep in mind the above warning about moving data around—by
253+
using the FileIOC library to get a direct pointer to the appvar's data.
169254

170255
.. code-block:: c
171256
@@ -193,7 +278,9 @@ However, accessing fonts this way triggers a slow VAT lookup for the appvar ever
193278
Finding a Font Pack by Typeface Name
194279
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
195280

196-
In addition to opening a font pack by appvar name, FontLibC also provides the special routine :code:`fontlib_GetFontPackName` to make it easier to search for a font pack by typeface name:
281+
In addition to opening a font pack by appvar name,
282+
FontLibC also provides the special routine :code:`fontlib_GetFontPackName` to make it easier to search
283+
for a font pack by typeface name:
197284

198285
.. code-block:: c
199286
@@ -218,7 +305,8 @@ In addition to opening a font pack by appvar name, FontLibC also provides the sp
218305
Looking at Other Font Metadata
219306
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
220307

221-
There are no other routines for processing the other metadata fields in a font pack. However, it is not hard to process the metadata fields yourself:
308+
There are no other routines for processing the other metadata fields in a font pack.
309+
However, it is not hard to process the metadata fields yourself:
222310

223311
.. code-block:: c
224312
@@ -264,41 +352,59 @@ API Usage Notes
264352
Text Windowing
265353
~~~~~~~~~~~~~~
266354

267-
To assist in text layout, fontlibc provides for a text window, which automatically confines text to appear in a specific rectangular area of the screen. This feature may be useful for dialogs and scrolling large blocks of text. Use :code:`fontlib_SetWindow` to set the current window bounds. Use :code:`fontlib_SetNewlineOptions` to control how :code:`fontlib_DrawString` behaves when it reaches the right edge of the text window.
355+
To assist in text layout, fontlibc provides for a text window,
356+
which automatically confines text to appear in a specific rectangular area of the screen.
357+
This feature may be useful for dialogs and scrolling large blocks of text.
358+
Use :code:`fontlib_SetWindow` to set the current window bounds.
359+
Use :code:`fontlib_SetNewlineOptions` to control how :code:`fontlib_DrawString` behaves when it reaches
360+
the right edge of he text window.
268361

269362
Aligning Text
270363
~~~~~~~~~~~~~
271364

272-
Implementing centered text, right-aligned text, and word wrap requires being able to compute the width of a word or string of text. The routine :code:`fontlib_GetStringWidth` provides this functionality.
365+
Implementing centered text, right-aligned text, and word wrap requires being able to compute the width of a word or string of text.
366+
The routine :code:`fontlib_GetStringWidth` provides this functionality.
273367

274-
If you call :code:`fontlib_SetAlternateStopCode(' ')`, :code:`fontlib_GetStringWidth` and :code:`fontlib_DrawString` will stop drawing on spaces, giving you a chance to check if the next word will fit on screen. You can use :code:`fontlib_GetLastCharacterRead()` to find out where :code:`fontlib_GetStringWidth` or :code:`fontlib_DrawString` stopped, and, after handling the space, then pass that address (plus one) again to :code:`fontlib_GetStringWidth` or :code:`fontlib_DrawString` to resume processing at where it left off before.
368+
If you call :code:`fontlib_SetAlternateStopCode(' ')`, :code:`fontlib_GetStringWidth` and :code:`fontlib_DrawString`
369+
will stop drawing on spaces, giving you a chance to check if the next word will fit on screen.
370+
You can use :code:`fontlib_GetLastCharacterRead()` to find out where :code:`fontlib_GetStringWidth` or
371+
:code:`fontlib_DrawString` stopped, and, after handling the space,
372+
then pass that address (plus one) again to :code:`fontlib_GetStringWidth` or :code:`fontlib_DrawString`
373+
to resume processing at where it left off before.
275374

276375
Text Control Codes
277376
~~~~~~~~~~~~~~~~~~
278377

279378
Embedded control codes are a popular way of managing style and formatting information in string.
280-
fontlibc only natively recognizes two types of control codes: NULL (0) as a stop code and a user-specified alternate stop code, and a user-specified newline code (defaults to 0x0A---ASCII LF and standard Linux style).
379+
fontlibc only natively recognizes two types of control codes: NULL (0) as a stop code and a user-specified alternate stop code,
380+
and a user-specified newline code (defaults to 0x0A---ASCII LF and standard Linux style).
281381
However, you can add your own control codes with :code:`fontlib_SetFirstPrintableCodePoint`.
282-
When any code point less than the first printable code point is encountered, fontlibc stops string processing and returns to allow you to handle the control code yourself using :code:`fontlib_GetLastCharacterRead`.
382+
When any code point less than the first printable code point is encountered,
383+
fontlibc stops string processing and returns to allow you to handle the control code yourself using
384+
:code:`fontlib_GetLastCharacterRead`.
283385

284386
Transparent Text
285387
~~~~~~~~~~~~~~~~
286388

287389
Part of providing high-performance is not painting a single pixel more than once.
288390
To assist with this goal, fontlibc provides for both transparent and opaque text backgrounds.
289391
Use :code:`fontlib_SetTransparency(true)` if you need to paint text over a background other than a solid color.
290-
If you turn transparency off, however, fontlibc will paint both background and foreground pixels for you, eliminating the time needed to erase those pixels before painting over that area.
392+
If you turn transparency off, however, fontlibc will paint both background and foreground pixels for you,
393+
eliminating the time needed to erase those pixels before painting over that area.
291394

292395
Line Spacing
293396
~~~~~~~~~~~~
294397

295-
Since a block of text may not always be the same size, fontlibc provides :code:`fontlib_ClearEOL` for erasing the remainder of a line of text without needing to pad it with spaces.
296-
This action can also be performed automatically after embedded newlines in text and on normal wrapping with :code:`fontlib_SetNewlineOptions`.
398+
Since a block of text may not always be the same size,
399+
fontlibc provides :code:`fontlib_ClearEOL` for erasing the remainder of a line of text without needing to pad it with spaces.
400+
This action can also be performed automatically after embedded newlines in text and
401+
on normal wrapping with :code:`fontlib_SetNewlineOptions`.
297402

298403
Additional blank vertical space around text can improve readability in large blocks of text.
299404
:code:`fontlib_SetLineSpacing` allows you to set this behavior.
300405
Fonts may specify default additional spacing that is automatically applied when calling :code:`fontlib_SetFont`.
301-
In GUIs and games where the benefits of legibility are outweighed by more aggressive use of vertical space, you can force the default spacing to zero after using :code:`fontlib_SetFont` with :code:`fontlib_SetLineSpacing`.
406+
In GUIs and games where the benefits of legibility are outweighed by more aggressive use of vertical space,
407+
you can force the default spacing to zero after using :code:`fontlib_SetFont` with :code:`fontlib_SetLineSpacing`.
302408

303409
API Documentation
304410
-----------------

0 commit comments

Comments
 (0)