Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags

Building a Font Importer

A topic by Internet Janitor created Sep 28, 2023 Views: 421 Replies: 1
Viewing posts 1 to 3
Developer(+5)

I recently came across Damien Guard's ZX Origin, a collection of hundreds of 8x8 fixed-width bitmapped fonts intended primarily for use on the ZX Spectrum. While these cannot be used directly in Decker, it is fairly straightforward to build a utility that takes a bitmap tilesheet like this one:


And converts it into a proper Decker font. Let's build one together, step-by-step!

Previews

First, let's make a system for previewing all the fonts in the current deck. Make a field widget named "preview" with some example text and a grid named "fonts" which will contain our font list:

We need to populate "fonts" with the names of all the fonts in the current deck. We can update this information in the "view[]" event handler for the card, which fires every time a card is visited (including when you first open a deck). Fill out a card script like so:

on view do
 fonts.value:select "Font Name":key from deck.fonts
 preview.font:first fonts.rowvalue
end

Piece by piece:


Note that "fonts.rowvalue" will be an empty dictionary if no row is selected. This is fine, because setting the font of "preview" to an invalid font name resets it to the default "body" font.

In order to make changing the selected row of the grid update the preview we also need to give the grid an event handler that kicks off the card "view[]" function when the row is changed:

on click do
 view[]
end

Switching to Interact mode will update our grid and allow us to try different builtin fonts:


Image Import

Next, let's make a system for reading in images. Create a canvas named "img" and a button labeled "Import Sheet". Use the Listener to resize the canvas to the exact dimensions of the ZX Origin sprite sheets, 256 by 24 pixels:

Now we flesh out the script for the button:

on click do
 img.paste[read["image"]]
end

The "read[]" function prompts the user to open an image and turns it into an Image Interface, and then "canvas.paste[]" splats the image onto the canvas:

Once again, note that we don't need to write explicit error-handling code: if a user cancels choosing an image with read["image"], it will return an empty image. Pasting an empty image onto a canvas is a harmless operation which has no effect.

Building a Font

Now we're ready to get to the heart of our tool: actually creating a font! Add a button labeled "Create" and a field named "name" which will specify the name of our new font:


Then, flesh out the button's script:

on click do
 f:deck.add["font" 8,8 name.text]
 f.space:0
 each p i in 8*32 cross 3
  f[i]:img.copy[p 8,8]
 end
 f[95]:image["%%IMG0AAgACAAAAAAAAFQA"]
 view[]
end

Piece by piece,

For additional reference, see the Font Interface.

With this script written, we can now import a tile sheet and create a usable font from it:


With the deck saved, we can then import our new font into other decks using the Font/DA Mover as usual.

Now that our minimal importer tool works, I'm sure you can imagine lots of ways of making it fancier! As an exercise, consider trying some of the following:

  • Add a button for deleting unwanted fonts
  • Make "create" prompt for a font name using "alert[]" instead of a name field
  • Disable "create" if the img canvas is empty
  • Warn a user if they attempt to create a font with a duplicate name, or replace such an existing font
  • Arrange and style the UI more nicely (for your personal definition of "more nicely")
  • Make the font spacing configurable
  • Adapt to font dimensions other than 8x8 when loading a larger or smaller tile sheet
  • Rework this tool into a Lilt script that can convert dozens of font images at once

Happy fontsmithing!

(+2)

This is SUPER COOL! And I love how well explained it is :)

Deleted 53 days ago
Deleted 53 days ago