fontlibc.h
#include <fontlibc.h>
The fontlibc
library provides routines for displaying custom fonts and glyphs, and can be used to extend the limited font capabilities of graphx.
The fontlibc
library was designed under a “mechanism not policy” sort of philosophy.
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.
For example, word-wrap is not directly provided, but can be implemented using fontlib_SetAlternateStopCode
and fontlib_GetStringWidth
.
fontlibc hopes to provide enough performance to be usable in games, while providing powerful enough basic features for fancy GUIs and document editors.
Creating Fonts
Fonts for use with fontlibc can be made with any program that can produce Windows 3.x .FNT resource files.
Editor Software
Fony is probably the most-used FNT editor available. It can open both .FNT and .FON files.
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.
VSoft’s 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).
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.
Using Fonts in Your Project
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.
There are two main ways of including a font in your project:
directly in your program binary; or,
in separate font pack appvar.
Embedding a Font Directly in Your Program
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.
Place your .FNT font files in your source code directory. Then, create a myfonts.h
source code file:
/* Declare globally-accessible pointers to the font data. */
extern const fontlib_font_t *my_font_1;
extern const fontlib_font_t *my_font_2;
. . .
Then create a myfonts.c
file:
/* This contains the raw data for the font. */
static const uint8_t my_font_1_data[] = {
#include "myfont1.inc"
};
/* However, C89 does not allow us to typecast a byte array into a
fontlib_font_t pointer directly, so we have to use a second statement to do it,
though helpfully we can at least do it in the global scope. */
const fontlib_font_t *my_font_1 = (fontlib_font_t *)my_font_1_data;
static const uint8_t my_font_2_data[] = {
#include "myfont2.inc"
};
const fontlib_font_t *my_font_2 = (fontlib_font_t *)my_font_2_data;
Now you should be wondering where the myfont1.inc
file comes from. This file will get generated by your makefile, which will need to be modified to append the following:
# This is a roundabout way to tell make that myfonts.c depends on the .inc files.
# It does it by saying the compiled object code depends on the .inc files.
$(OBJDIR)/myfonts.src: $(SRCDIR)/myfont1.inc $(SRCDIR)/myfont2.inc
# Convert a .fnt file into a .inc file
$(SRCDIR)/myfont1.inc: $(SRCDIR)/myfont1.fnt
convfont -o carray -f $(SRCDIR)/myfont1.fnt $(SRCDIR)/myfont1.inc
$(SRCDIR)/myfont2.inc: $(SRCDIR)/myfont2.fnt
convfont -o carray -f $(SRCDIR)/myfont2.fnt $(SRCDIR)/myfont2.inc
Finally, somewhere else in your program, you can use fontlib_SetFont
:
void main() {
. . .
fontlib_SetFont(my_font_1, 0);
. . .
}
Packaging a Font Pack
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.
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.
Font packs are easiest to make as a separate project. Create a new folder, place your .fnt
files in it, and then create a makefile
with the following contents:
# Put each of your .fnt files on this next line.
# Look at the documentation for convfont for more information on font properties
temp.bin: font1.fnt font2.fnt font3.fnt
convfont -o fontpack -N "Font Name" -P "ASCII" -V "Some version or date" -A "Your Name" \
-D "A SHORT description of your font" \
-f font1.fnt -a 1 -b 1 -w bold -s sans-serif -s upright -s proportional \
-f font2.fnt -a 2 -b 2 -w normal -s serif -s italic \
-f font3.fnt -a 0 -b 3 -w light -s monospaced \
temp.bin
# Don't forget to change font_pack_file_name on both these lines.
# Set PACKNAME to the on-calculator appvar name you want
font_pack_file_name.8xv: temp.bin
convhex -a -v -n PACKNAME temp.bin font_pack_file_name.8xv
all: font_pack_file_name.8xv
Using Font Packs
While using an embedded font is easy—just call fontlib_SetFont
directly on the pointer to the font data—, using a font pack is a bit more involved.
WARNING: FontLibC caches a pointer to the font’s data when you use 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 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.
(The above warning does not apply to fonts embedded into your program, as data embedded in your program cannot get moved.)
Opening a Font Pack the Simple Way
If you require a specific font pack with a specific appvar name, then opening a font is straight-forward:
#include <graphx.h>
#include <fontlibc.h>
void main(void) {
fontlib_font_t *my_font;
. . .
/* Get the first font present in the font pack */
my_font = fontlib_GetFontByIndex("MYFONT", 0);
/* This check is important! If fetching the font fails, trying to use the font will go . . . poorly. */
if (!my_font) {
gfx_PrintStringXY("MYFONT appvar not found or invalid", 0, 0);
return;
}
/* Use font for whatever */
fontlib_SetFont(my_font, 0);
. . .
}
Caching a Font Pack’s Address
However, accessing fonts this way triggers a slow VAT lookup for the appvar every time you call a 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.
uint8_t file;
fontlib_font_pack_t *my_font_pack;
fontlib_font_t *my_font;
. . .
/* Open file */
file = ti_open("MYFONT", "r");
/* Throw an error if the file was not found */
if (!my_font_pack) {
gfx_PrintStringXY("MYFONT appvar not found", 0, 0);
return;
}
my_font_pack = ti_GetDataPtr(file);
/* Once we have the pointer, we don't need the file handle any more. */
ti_Close(file);
/* Just because the file exists doesn't mean it's actually a font pack */
my_font = fontlib_GetFontByIndexRaw(my_font_pack, 0);
if (!my_font) {
gfx_PrintStringXY("MYFONT appvar is invalid", 0, 0);
return;
}
Finding a Font Pack by Typeface Name
In addition to opening a font pack by appvar name, FontLibC also provides the special routine fontlib_GetFontPackName
to make it easier to search for a font pack by typeface name:
char *var_name;
char *typeface_name;
fontlib_font_pack_t *my_font_pack;
uint8_t *search_pos = NULL;
while ((var_name = ti_DetectVar(&search_pos, "FONTPACK", TI_APPVAR_TYPE)) != NULL) {
typeface_name = fontlib_GetFontPackName(var_name);
/* Font packs can omit the name metadata property, so check for that. */
if (!typeface_name)
continue;
/* Do something interesting with the typeface_name here.
Note that a direct pointer to the name is returned, which may be archived,
so you cannot write to the string. */
if (!strcmp(typeface_name, "My Font")) {
fontlib_SetFont(fontlib_GetFontByIndex(var_name, 0), 0);
break;
}
}
Looking at Other Font Metadata
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:
uint8_t file;
fontlib_font_pack_t *font_pack;
int metadata_offset;
fontlib_metadata_t *font_pack_metadata;
char *font_pack_author;
. . .
/* Assume that file is the already-opened appvar of the font pack. */
font_pack = ti_GetDataPtr(file);
metadata_offset = font_pack->metadata;
if (!metadata_offset)
return; /* No metadata in the font pack, do something else here */
ti_Seek(metadata_offset, SEEK_SET, file);
font_pack_metadata = ti_GetDataPtr(file);
metadata_offset = font_pack_metadata->font_author;
if (!metadata_offset)
return; /* No author specified */
ti_Seek(metadata_offset, SEEK_SET, file);
font_pack_author = ti_GetDataPtr(file);
/* Now you have the author name string */
Selecting a Font by Style
The GetFontByStyle
routines help you automatically select a font given a set of size and style criteria.
fontlib_font_pack_t *font_pack;
fontlib_font_t *font;
. . .
/* Assume font_pack already points to a valid font pack. */
/* Get a 9 or 10 pixel tall bold, serif font that isn't monospaced and isn't italic. */
font = fontlib_GetFontByStyleRaw(font_pack, 9, 10, FONTLIB_BOLD, FONTLIB_BOLD, FONTLIB_SERIF, FONTLIB_MONOSPACED | FONTLIB_ITALIC);
if (font)
fontlib_SetFont(font, 0);
API Usage Notes
Text Windowing
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 fontlib_SetWindow
to set the current window bounds. Use fontlib_SetNewlineOptions
to control how fontlib_DrawString
behaves when it reaches the right edge of the text window.
Aligning Text
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 fontlib_GetStringWidth
provides this functionality.
If you call fontlib_SetAlternateStopCode(' ')
, fontlib_GetStringWidth
and fontlib_DrawString
will stop drawing on spaces, giving you a chance to check if the next word will fit on screen. You can use fontlib_GetLastCharacterRead()
to find out where fontlib_GetStringWidth
or fontlib_DrawString
stopped, and, after handling the space, then pass that address (plus one) again to fontlib_GetStringWidth
or fontlib_DrawString
to resume processing at where it left off before.
Text Control Codes
Embedded control codes are a popular way of managing style and formatting information in string.
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).
However, you can add your own control codes with fontlib_SetFirstPrintableCodePoint
.
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 fontlib_GetLastCharacterRead
.
Transparent Text
Part of providing high-performance is not painting a single pixel more than once.
To assist with this goal, fontlibc provides for both transparent and opaque text backgrounds.
Use fontlib_SetTransparency(true)
if you need to paint text over a background other than a solid color.
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.
Line Spacing
Since a block of text may not always be the same size, fontlibc provides fontlib_ClearEOL
for erasing the remainder of a line of text without needing to pad it with spaces.
This action can also be performed automatically after embedded newlines in text and on normal wrapping with fontlib_SetNewlineOptions
.
Additional blank vertical space around text can improve readability in large blocks of text.
fontlib_SetLineSpacing
allows you to set this behavior.
Fonts may specify default additional spacing that is automatically applied when calling fontlib_SetFont
.
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 fontlib_SetFont
with fontlib_SetLineSpacing
.
API Documentation
Provides improved font support.
- Author
DrDnar
Enums
-
enum fontlib_newline_options_t
Options for controlling newline behavior.
See also
fontlib_SetNewlineOptions
Values:
-
enumerator FONTLIB_ENABLE_AUTO_WRAP = 0x01
Enables automatic wrapping at the end of the line.
Note
This is per-glyph; word warp is neither implemented nor planned
-
enumerator FONTLIB_AUTO_CLEAR_TO_EOL = 0x02
Upon any newline, clears the remainder of the line of text.
Note
Useful for printing over previously printed text when transparency is turned off, as this means each pixel in a line of text need only be visited once.
-
enumerator FONTLIB_PRECLEAR_NEWLINE = 0x04
Clears the NEXT line of text.
Note
Don’t combine this with AUTO_CLEAR because that just wastes CPU cycles due to erasing/drawing each pixel twice.
-
enumerator FONTLIB_AUTO_SCROLL = 0x08
Enables automatic scrolling when a newline would push the cursor past the bottom of the text window.
The cursor is left at the bottom left.
Note
If PRECLEAR is not set, then the bottom line of text will not be erased.
-
enumerator FONTLIB_ENABLE_AUTO_WRAP = 0x01
-
enum fontlib_load_options_t
Options for controlling how SetFont functions.
See also
fontlib_SetFont
Values:
-
enumerator FONTLIB_IGNORE_LINE_SPACING = 0x01
If set, then the space above/below metrics specified in the font will be ignored and set to zero.
You can still manually set them later.
-
enumerator FONTLIB_IGNORE_LINE_SPACING = 0x01
-
enum fontlib_styles_t
Options for selecting a font by style.
See also
fontlib_GetFontByStyle
Values:
-
enumerator FONTLIB_SERIF = 0x01
Clear = sans-serif font.
-
enumerator FONTLIB_OBLIQUE = 0x02
Oblique is slanted like italic text, but with the cursive-like styling.
-
enumerator FONTLIB_ITALIC = 0x04
If both italic and oblique are set, then assume there’s no difference between oblique and italic styles.
-
enumerator FONTLIB_MONOSPACED = 0x08
Monospaced font.
Note
Chances are you’re not using this library for monospaced fonts. But if you are, you’ll still have to provide a widths table where every byte is the same.
Note
This is not enforced; a variable-width font can claim to be monospaced!
-
enumerator FONTLIB_SERIF = 0x01
-
enum fontlib_weights_t
Options for selecting a font by weight.
See also
fontlib_GetFontByStyle
Values:
-
enumerator FONTLIB_THIN = 0x20
-
enumerator FONTLIB_EXTRA_LIGHT = 0x30
-
enumerator FONTLIB_LIGHT = 0x40
-
enumerator FONTLIB_SEMILIGHT = 0x60
-
enumerator FONTLIB_NORMAL = 0x80
-
enumerator FONTLIB_MEDIUM = 0x90
-
enumerator FONTLIB_SEMIBOLD = 0xA0
-
enumerator FONTLIB_BOLD = 0xC0
-
enumerator FONTLIB_EXTRA_BOLD = 0xE0
-
enumerator FONTLIB_BLACK = 0xF0
-
enumerator FONTLIB_THIN = 0x20
Functions
-
void fontlib_SetWindowFullScreen(void)
Sets the bounds of the window all text will appear in to be the full screen.
This is the default.
-
void fontlib_SetWindow(unsigned int x_min, uint8_t y_min, unsigned int width, uint8_t height)
Sets the bounds of the window all text will appear in.
Note
Clipping of partial glyphs is not supported. If a glyph, either horizontally or vertically, does not fit in the text window, it will not be printed at all.
Note
Behavior is undefined if the text cursor is positioned outside of the current text window.
Warning
Changing this does not automatically move the text cursor into the window.
- Parameters
x_min – [in] X coord base
y_min – [in] Y coord base
width – [in] Width
height – [in] Height
-
unsigned int fontlib_GetWindowXMin(void)
Returns the starting column of the current text window.
- Returns
Window X
-
uint8_t fontlib_GetWindowYMin(void)
Returns the starting row of the current text window.
- Returns
Window Y
-
unsigned int fontlib_GetWindowWidth(void)
Returns the width of the current text window.
- Returns
Window width
-
uint8_t fontlib_GetWindowHeight(void)
Returns the height of the current text window.
- Returns
Window height
-
void fontlib_SetCursorPosition(unsigned int x, uint8_t y)
Sets the cursor position.
Behavior is undefined if the cursor is set outside of the text window.
- Parameters
x – [in] X
y – [in] Y
-
unsigned int fontlib_GetCursorX(void)
Returns the cursor column.
- Returns
Current cursor X
-
uint8_t fontlib_GetCursorY(void)
Returns the cursor row.
- Returns
Current cursor Y
-
void fontlib_ShiftCursorPosition(int x, int y)
Adds the given (x,y) to the cursor position.
Note
Useful for tabbing, for example.
Warning
Behavior is undefined if the resulting cursor position is offscreen.
- Parameters
x – [in] x-shift
y – [in] y-shift
-
void fontlib_HomeUp()
Moves the cursor to the upper left corner of the text window.
-
void fontlib_Home()
Moves the cursor back to the start of the current line.
-
bool fontlib_SetFont(const fontlib_font_t *font_data, fontlib_load_options_t flags)
Sets the current font.
Warning
If false is returned, no valid font is currently loaded and trying to print will print garbage!
- Parameters
font_data – [in] Pointer to font data
flags – [in] Information about how to process the font (unused)
- Returns
Returns false if the font seems invalid for any reason
-
void fontlib_SetForegroundColor(uint8_t color)
Sets the current foreground color FontLibC will use for drawing.
Note
This is NOT the same as GraphX’s current color!
- Parameters
color – New color to use
-
void fontlib_SetBackgroundColor(uint8_t color)
Sets the current background color FontLibC will use for drawing.
Note
This is NOT the same as GraphX’s current color!
- Parameters
color – [in] New color to use
-
void fontlib_SetColors(uint8_t forecolor, uint8_t backcolor)
Sets the current colors FontLibC will use for drawing.
Note
These are NOT the same as GraphX’s current colors!
- Parameters
forecolor – [in] New foreground color to use
backcolor – [in] New background color to use
-
uint8_t fontlib_GetForegroundColor(void)
Returns the current foreground color FontLibC will use for drawing.
Note
This is NOT the same as GraphX’s current color!
- Returns
Current foreground color
-
uint8_t fontlib_GetBackgroundColor(void)
Returns the current background color FontLibC will use for drawing.
Note
This is NOT the same as GraphX’s current color!
- Returns
Current background color
-
void fontlib_SetTransparency(bool transparency)
Controls whether FontLibC will use a transparent background for text drawing instead of the currently configured background color.
Note
This has nothing to do with GraphX’s configured transparent color
- Parameters
transparency – [in] true to make background transparent, false to use background color
-
bool fontlib_GetTransparency(void)
Returns whether FontLibC will use a transparent background for text drawing instead of the currently configured background color.
Note
This has nothing to do with GraphX’s configured transparent color
- Returns
true if background will be transparent, false if background color will be used
-
void fontlib_SetLineSpacing(uint8_t space_above, uint8_t space_below)
Controls hows much black space will be added above and below each line of text.
If transparency is set, then the padding will not be overwritten with the background color, but padding will still be added. Padding space is added at the time each glyph is drawn.
- Parameters
space_above – [in] Blank space padding to add above
space_below – [in] Blank space padding to add below
-
uint8_t fontlib_GetSpaceAbove(void)
Returns current padding space above.
- Returns
Current padding space above
-
uint8_t fontlib_GetSpaceBelow(void)
Returns current padding space below.
- Returns
Current padding space below
-
void fontlib_SetItalicSpacingAdjustment(uint8_t italic_spacing_adjustment)
Sets current spacing adjustment for italic text.
This causes the cursor to be moved back a certain number of pixels after every glyph is drawn.
Note
This is only useful if transparency mode is set.
Note
Italics is currently untested! (I haven’t designed an italic font yet.)
- Parameters
italic_spacing_adjustment – [in] Pixels to move cursor backward after each glyph
-
uint8_t fontlib_GetItalicSpacingAdjustment(void)
Returns current spacing adjustment for italic text.
- Returns
Current spacing adjustment for italic text
-
uint8_t fontlib_GetCurrentFontHeight(void)
Returns the height of the current font, INCLUDING space above/below.
- Returns
Height in pixels
-
bool fontlib_ValidateCodePoint(char code_point)
Tests whether the current font has the given code point.
- Parameters
code_point – [in] Code point to test
- Returns
true if code_point is in current font, false if not
-
size_t fontlib_GetTotalGlyphs(void)
Returns the total number of printable glyphs in the font.
Note
This can return 256; no valid font has 0 printable glyphs.
- Returns
Total number of printable glyphs
-
char fontlib_GetFirstGlyph(void)
Returns the code point of the first printable glyph.
Note
The C SDK makes char SIGNED by default, so you probably want to typecast this to unsigned char before attempting any math with it.
- Returns
First print glyph code point
-
void fontlib_SetNewlineCode(char code_point)
Allows you to set the code point that is recognized as being a new line code.
You can set this to zero to prevent new line code processing.
Note
If FONTLIB_ENABLE_AUTO_WRAP is enabled, then wrapping will still implicitly case a newline.
Note
This defaults to 0x0A (ASCII line feed/UNIX newline)
- Parameters
code_point – [in] New code point to use for newline
-
char fontlib_GetNewlineCode(void)
Returns the code point that is currently recognized as being a newline.
If 0, newlines in strings will not be processed.
- Returns
Current newline
-
void fontlib_SetAlternateStopCode(char code_point)
Sets an alternate code point to recognize as a stop code.
Set this to 0 if you do not want to use the alternate stop code feature. Defaults to 0.
Note
You can set this to space to make DrawString and GetStringWidth stop processing when they reach a space.
Note
NULL (0) will still be recognized as a stop code regardless of value.
- Parameters
code_point – [in] Additional code point to recognize as a stop code.
-
char fontlib_GetAlternateStopCode(void)
Returns the current alternate stop code.
- Returns
Current alternate stop code.
-
void fontlib_SetFirstPrintableCodePoint(char code_point)
Sets the first code point considered printable.
All code points before this will be considered control codes. This defaults 0x10.
Note
Setting this to 0 (NULL) will NOT cause NULL to be ignored.
- Parameters
code_point – [in] First printable code point
-
char fontlib_GetFirstPrintableCodePoint(void)
Returns the first code point considered printable.
- Returns
Current first printable code point
-
void fontlib_SetDrawIntCodePoints(char minus, char zero)
Sets the code points DrawInt and DrawUInt will use for the minus symbol and digits 0-9.
- Parameters
minus – [in] Minus symbol code point, defaults to ‘-‘
zero – [in] Zero code point, defaults to ‘0’; ‘1’-‘9’ are assumed to follow
-
char fontlib_GetDrawIntMinus(void)
Returns the code point DrawInt and DrawUInt will use for a minus symbol Defaults to ‘-‘.
- Returns
‘-‘ or whatever you set it to
-
char fontlib_GetDrawIntZero(void)
Returns the code point DrawInt and DrawUInt will use for ‘0’; it assumes ‘1’-‘9’ follow ‘0’ Defaults to ‘0’.
- Returns
‘0’ or whatever you set it to
-
uint8_t fontlib_GetGlyphWidth(char codepoint)
Returns the width of the given glyph.
- Parameters
codepoint – [in] Codepoint to test
- Returns
Width of glyph, 0 if invalid codepoint
-
unsigned int fontlib_GetStringWidth(const char *str)
Returns the width of a string printed in the current font.
Stops processing when it encounters ANY control code or a codepoint not in the current font.
- Parameters
str – [in] Pointer to string
- Returns
Width of string
-
unsigned int fontlib_GetStringWidthL(const char *str, size_t max_characters)
Returns the width of a string printed in the current font.
Stops processing when it encounters ANY control code or a codepoint not in the current font, or when max_characters have been processed.
- Parameters
str – [in] Pointer to string
max_characters – [in] Maximum number of characters to process
- Returns
Width of string
-
char *fontlib_GetLastCharacterRead(void)
Gets the location of the last character processed by GetStringWidth or DrawString.
- Returns
Pointer to character
-
size_t fontlib_GetCharactersRemaining(void)
Returns 0 if DrawStringL or GetStringWidthL returned because max_characters were processed.
Returns a non-zero number otherwise.
- Returns
Either zero, or a non-zero number depending on the reason DrawStringL or GetStringWidthL returned.
-
uint24_t fontlib_DrawGlyph(uint8_t glyph)
Draws a glyph.
Note
This can even draw code points less than the code point specified with fontlib_SetFirstPrintableCodePoint(). It can even draw code point 0.
Note
Although this does update the cursor X/Y positions, it does NOT process window bounds at all! (Maybe this should be FIXME? On the other hand, users may want this specifically so they can handle all their own layout without the text window settings getting in their way.)
- Parameters
glyph – [in] Codepoint
- Returns
The new X value of the cursor
-
uint24_t fontlib_DrawString(const char *str)
Draws a string.
This will return when it reaches the right edge of the text window if FONTLIB_ENABLE_AUTO_WRAP is turned off.
This stops drawing upon reaching NULL. It will also stop if it encounters the character code specified with fontlib_SetAlternateStopCode().
Note
The check for the alternate stop code always takes place before drawing a glyph, so if you need to also display the stop code character, you must directly call fontlib_DrawGlyph to force display the character and increment past it.
Note
Newline codes will print regardless of whether FONTLIB_ENABLE_AUTO_WRAP is enabled. To disable parsing newline codes, use fontlib_SetNewlineCode(0);
Note
THIS IS NOT REENTRANT (though if you need that, you’re probably not using C)
- Parameters
str – [in] Pointer to string
- Returns
The new X value of the cursor (probably not useful if a newline was processed.)
-
uint24_t fontlib_DrawStringL(const char *str, size_t max_characters)
Draws a string, up to a maximum number of characters.
Note
This is intended to be used if you only want a portion of a string printed. (Or if you hate null-terminated strings and want length-prefixed strings instead. It still won’t print NULLs though.)
Note
THIS IS NOT REENTRANT (though if you need that, you’re probably not using C)
- Parameters
str – Pointer to string
max_characters – [in] Maximum number of characters to attempt to print, may return early if some other condition requires returning
- Returns
The new X value of the cursor (probably not useful if a newline was processed.)
-
void fontlib_DrawInt(int n, uint8_t length)
Prints a signed integer.
Outputs at the current cursor position. Padded with leading zeros if necessary to satisfy the specified minimum length.
Note
This does not obey window bounds like DrawString/L
Note
length
must be between 1 and 8, inclusive- Parameters
n – [in] Integer to print
length – [in] Minimum number of characters to print
-
void fontlib_DrawUInt(unsigned int n, uint8_t length)
Prints an unsigned integer.
Outputs at the current cursor position. Padded with leading zeros if necessary to satisfy the specified minimum length.
Note
This does not obey window bounds like DrawString/L
Note
length
must be between 1 and 8, inclusive- Parameters
n – [in] Unsigned integer to print
length – [in] Minimum number of characters to print
-
void fontlib_ClearEOL(void)
Erases everything from the cursor to the right side of the text window (End-Of-Line).
This ignores the transparent background flag.
-
void fontlib_ClearWindow(void)
Erases the entire current text window.
Note
This ignores the transparent background flag. If background transparency is important, check fontlib_GetTransparency() before calling this routine.
-
void fontlib_Newline(void)
Performs a newline.
Pays attention to newline flags.
- Returns
Returns true if the text window is full. This only happens if scrolling is disabled.
-
void fontlib_SetNewlineOptions(uint8_t options)
Sets options for controlling newline behavior.
See also
fontlib_newline_options_t
- Parameters
options – [in] Flags setting newline behavior
-
uint8_t fontlib_GetNewlineOptions(void)
Gets the current newline behavior options.
- Returns
Current newline behavior options
-
void fontlib_ScrollWindowDown(void)
Scrolls the contents of the text window down one line, i.e.
everything in the window is copied UP one line, thus yielding the effect of scrolling down. The current text cursor position is ignored.
Note
The bottom line is not erased; you must erase or overwrite it yourself.
-
void fontlib_ScrollWindowUp(void)
Scrolls the contents of the text window up one line, i.e.
everything in the window is copied DOWN one line, thus yielding the effect of scrolling up. The current text cursor position is ignored.
Note
The bottom line is not erased; you must erase or overwrite it yourself.
Note
This doesn’t try to compute the location of the bottom line of text; it just blindly copies rows of pixels, so make sure the window height is an exact multiple of the font height.
-
char *fontlib_GetFontPackName(const char *appvar_name)
Gets the long name associated with a font pack.
Useful in a loop with ti_Detect() when searching a typeface with a specific name.
- Parameters
appvar_name – [in] Pointer to name of appvar
- Returns
Direct pointer to font’s name; or NULL if no such appvar exists, the appvar isn’t a font pack, or the font pack does not supply a name. NOTA BENE: Any operation that can move variables around in memory can invalidate this pointer!
-
fontlib_font_t *fontlib_GetFontByIndexRaw(const fontlib_font_pack_t *font_pack, uint8_t index)
Gets a pointer to a font, suitable for passing to SetFont(), given a font pack’s address.
Useful if you know caching the font pack’s address is safe.
See also
ti_GetDataPtr()
- Parameters
font_pack – [in] Pointer to font pack
index – [in] Index into font table of font pack
- Returns
Direct pointer to font, or NULL if the index is invalid.
-
fontlib_font_t *fontlib_GetFontByIndex(const char *font_pack_name, uint8_t index)
Gets a pointer to a font, suitable for passing to SetFont(), given a font pack’s appvar’s name.
Recommended to use after any file write, create, delete, or un/archive, as all those operations could invalidate the cached data pointers to the currently loaded font.
- Parameters
font_pack_name – [in] Pointer to font pack appvar’s name
index – [in] Index into font table of font pack
- Returns
Direct pointer to font, or NULL if the index is invalid.
-
fontlib_font_t *fontlib_GetFontByStyleRaw(const fontlib_font_pack_t *font_pack, uint8_t size_min, uint8_t size_max, uint8_t weight_min, uint8_t weight_max, uint8_t style_bits_set, uint8_t style_bits_reset)
Gets a pointer to a font, suitable for passing to SetFont(), given a font pack’s address and a set of font properties.
Useful if you know caching the font pack’s address is safe.
See also
ti_GetDataPtr()
- Parameters
font_pack – [in] Pointer to font pack
size_min – [in] Minimum heigh, in pixels, to accept. Space above and space below metrics are not considered.
size_max – [in] Maximum height
weight_min – [in] Minimum weight to accept. 0 may be used.
weight_max – [in] Maximum weight to accept. 0xFF may be used.
style_bits_set – [in] Mask of style bits you want set. For example, FONTLIB_SERIF | FONTLIB_MONOSPACE to look for a monospaced serifed font.
style_bits_reset – [in] Style bits you want RESET. For example, pass FONTLIB_MONOSPACE to REJECT monospaced fonts.
- Returns
Direct pointer to font, or NULL if no matching font is found
-
fontlib_font_t *fontlib_GetFontByStyle(const char *font_pack_name, uint8_t size_min, uint8_t size_max, uint8_t weight_min, uint8_t weight_max, uint8_t style_bits_set, uint8_t style_bits_reset)
Gets a pointer to a font, suitable for passing to SetFont(), given a font pack’s appvar’s name and a set of font properties.
Recommended to use after any file write, create, delete, or un/archive, as all those operations could invalidate the cached data pointers to the currently loaded font.
- Parameters
font_pack_name – [in] Pointer to font pack appvar’s name
size_min – [in] Minimum heigh, in pixels, to accept. Space above and space below metrics are not considered.
size_max – [in] Maximum height
weight_min – [in] Minimum weight to accept. 0 may be used.
weight_max – [in] Maximum weight to accept. 0xFF may be used.
style_bits_set – [in] Mask of style bits you want set. For example, FONTLIB_SERIF | FONTLIB_MONOSPACE to look for a monospaced serifed font.
style_bits_reset – [in] Style bits you want RESET. For example, pass FONTLIB_MONOSPACE to REJECT monospaced fonts.
- Returns
Direct pointer to font, or NULL if no matching font is found
-
struct fontlib_metadata_t
- #include <fontlibc.h>
Contains references to various metadata strings.
See also
Note
Any or all of these offsets may be NULL.
Note
These should be short null-terminated C strings, but this is not enforced. Check for malformed metadata!
Public Members
-
int24_t length
Size of this struct, basically functions as a version field.
This does NOT include the lengths of the strings!
-
int24_t font_family_name
A short, human-readable typeface name, such as “Times”.
-
int24_t font_author
A SHORT string naming the typeface designer.
-
int24_t font_pseudocopyright
A SHORT copyright claim.
Do not try to include a complete license in here! Space is limited!
Note
Typefaces and bitmapped fonts cannot be copyrighted under US law. This field is therefore referred to as a pseudocopyright. HOWEVER, it IS is applicable in other jusrisdictions, such as Germany.
-
int24_t font_description
A BRIEF description of the font.
-
int24_t font_version
Note
This is a STRING, so while this should be something like “1.0.0.0” it could also be something like “1 June 2019” or even “Hahaha versioning
is overrated!”
-
int24_t font_code_page
Suggested values: “ASCII” “TIOS” “ISO-8859-1” “Windows 1252” “Calculator 1252”.
-
int24_t length
-
struct fontlib_font_t
- #include <fontlibc.h>
This is the actual font format.
Directly reading from this struct is the only way to read a font’s cap_height, x_height, and baseline_height metrics.
For example:
unsigned char baseline; fontlib_font_t *my_font = fontlib_GetFontByStyle("FONTPACK", 12, 12, FONTLIB_NORMAL, FONTLIB_NORMAL, FONTLIB_SERIF, 0); if (!my_font || !fontlib_SetFont(my_font)) return; baseline = my_font->baseline_height;
Note
The font’s width table and bitmaps table should appear directly after this struct. The struct does not contain a member for the data because it is probably not useful for C code to parse the width or bitmap data directly.
Public Members
-
uint8_t fontVersion
Version ID.
Note
This must be zero or the font will be rejected as invalid.
-
uint8_t height
Height in pixels not including space above/below.
-
uint8_t total_glyphs
Total number of glyphs provided.
Note
If this is zero, then 256 glyphs are provided, not zero!
-
uint8_t first_glyph
Number of first glyph.
If you have no codepoints below 32, for example, you can omit the first 32 bitmaps.
-
int24_t widths_table
Offset/pointer to glyph widths table.
This is an OFFSET from the fontVersion member
Note
It is 24-bits long because it becomes a real pointer upon loading.
-
int24_t bitmaps
Offset to a table of offsets to glyph bitmaps.
Note
Parsing the bitmaps yourself is probably not useful.
Note
These offsets are only 16-bits each to save some space.
-
uint8_t italic_space_adjust
Specifies how much to move the cursor left after each glyph.
Total movement is width - overhang.
Note
Intended for italics.
-
uint8_t space_above
These suggest adding blank space above or below each line of text.
Note
This can be overridden
Note
This can increase legibility while saving space for always-blank lines.
-
uint8_t space_below
-
uint8_t weight
Specifies the boldness of the font.
See also
fontlib_weights_t
-
uint8_t style
Specifies the style of the font.
See also
fontlib_styles_t
-
uint8_t cap_height
For layout, allows aligning text of differing fonts vertically.
These count pixels going down, i.e. 0 means the top of the glyph.
-
uint8_t x_height
-
uint8_t baseline_height
-
uint8_t fontVersion
-
struct fontlib_font_pack_t
- #include <fontlibc.h>
This is the format of a font pack appvar.
Parsing this directly is the only way to get metadata other than the typeface name.
FILE font_pack_file; fontlib_font_pack_t *font_pack; fontlib_metadata_t *metadata; char *var_name; char *font_author; uint8_t *search_pos = NULL; // Just randomly select the first font pack found if ((var_name = ti_Detect(&search_pos, "FONTPACK")) == NULL) return; // Get font pack header font_pack_file = ti_Open(var_name, "r"); font_pack = ti_GetDataPtr(font_pack_file); // Is metadata present? if (!font->metadata) return; if (EOF == ti_Seek(font->metadata, SEEK_SET, font_pack_file)) return; // Is metadata semi-valid? metadata = ti_GetDataPtr(font_pack_file); if (metadata->length < sizeof(fontlib_metadata_t)) return; // Get font's author if (!metadata->font_author) return; if (EOF == ti_Seek(metadata->font_author, SEEK_SET, font_pack_file)) return; font_author = ti_GetDataPtr(font_pack_file); ti_Close(font_pack_file);
Public Members
-
char header[8]
Must be “FONTPACK”.
Note
This is NOT null-terminated!
-
int24_t metadata
Offset from first byte of header.
-
uint8_t fontCount
Number of fonts present.
Should be greater than zero… .
Note
Frankly, if you have more than 127 fonts in a pack, you have a problem.
-
int24_t font_list[1]
Array of offsets to each individual font.
Note
Despite being declared as a single element, this will be fontCount elements long.
-
char header[8]