› ›

FZX: a new standard format and driver for proportional fonts

edited January 2015 in Brand new software
FZX is a very compact and efficient (although extremely flexible and powerful) standard format to create new fonts for the ZX-Spectrum. It supports proportional fonts, you can print characters anywhere on screen, and it's very easy to use in Sinclair BASIC, or called directly from Assembly routines.

The official FZX font format definition (including several sample fonts) is now available in FZX_Standard.zip, a tape file containing some practical examples is available in FZX.tap.zip, and the source code for the proportional printing driver is available in FZX_Driver.zip

However let's skip all the tech details and go straight to the interesting stuff! Every character in a regular ZX-Spectrum font is designed using a 8x8 grid like this:

nxoprt.png

But using FZX, each character definition is fully configurable and uses an arbitrary sized grid, like this:

el7f6b.png

In the example above, the character pixels are defined in a smaller 5x5 grid, and everything else is configurable. This particular FZX font specifies that all characters are 9 pixels tall ("height"), character "a" is located at a distance of 2 pixels from the top ("shift"), character "a" is 5 pixels wide ("width"), and there should be 2 pixels of distance before the next character ("tracking").

All these configurations make it possible to define proportional fonts that are fully flexible and configurable, but still very compact, using about the same amount of memory as a regular font.

Now let's consider a practical example. This is the original Sinclair font:

2ntb77t.png

And here's the same text, using the same font style, but now converted to take advantage of FZX format using proportional spacing:

oqx7y1.png

Although it's the same font style and size, the latter version is more comfortable to read and doesn't take so much room on screen, so it's certainly an improvement!

Another nice feature of FZX format is that it supports quite large fonts, with characters up to 16 pixels wide. Here's another example, this time using a much larger font called "Grotesk" (also supplied in the link above):

o8tats.png

So how do you use FZX fonts in practice? It's actually very simple. First, load the driver from tape (together with any FZX font of your choice) and initialize it only once, like this:
CLEAR 59999: LOAD "Sinclair"CODE 60000: LOAD "FZXdriver"CODE 65000: RANDOMIZE USR 65000

Afterwards, simply use PRINT #4 to print your text, for instance:
PRINT #4;AT 0,0;"FZX driver code (c) Einar Saukas"'"FZX font format (c) Andrew Owen"
PRINT #4: FOR f=32 TO 127: PRINT #4;CHR$ f;: NEXT f

Using font "Zaibatsu" for instance (also supplied in this package), the program above will produce the following result:

2ry5288.png

That's easy, right? :)

As indicated in the screen above, Andrew Owen and I have worked together to create FZX. He concentrated on defining the standard (with some assistance from Paul van der Laan) and designing the sample fonts supplied in this package, while I focused on coding it. Anyway everything presented here is open source and royalty-free, so you are welcome to use any of this material in your own programs (even commercial releases) and to create new FZX fonts yourself!
Post edited by Einar Saukas on
Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
Thanked by 1farvardin
«134567…11

Comments

  • edited June 2013
    Oooh, this looks great - I will have to try his out to see if it can replace the original proportional font routine in MRT.

    Great work Chaps.

    Paddy
  • edited June 2013
    We Need Tech details!!!!! I wrote a proportional print routine 18 years ago which worked on a similar principal. It wasn't however useable from basic so nowhere near as useful, but pretty quick like this one is. How would one encode an FZX character set?

    IIRC my effort used 2 bytes for height, width and then the character itself. I'm guessing FZX works on a similar principal?
  • edited June 2013
    This is a great initiative, and I'm very happy to have been asked by Andrew for feedback during the development of FZX. I think this is a great way to make proportional fonts work on the Spectrum.

    One thing that needs correction in the example above however, is some of the terminology.
    • What is called “baseline” should actually be called “body height”. In Latin typography the baseline is the imaginary line where most uppercase and lowercase letters are standing on.
    • “Leading” is also not the correct word to describe the situation above. I would rather use the word “vertical offset”. The term “leading”, also sometimes referred to as “line spacing”, is the distance between two lines of text, measured from baseline to baseline.

    Also see this Wikipedia article. :)
  • edited June 2013
    And here's the same text, using the same font style, but now converted to take advantage of FZX format using proportional spacing:

    oqx7y1.png

    Looks great and the FZX is a very nice initiative. Kudos to you and Andrew on this!

    One question I have is whether the spacing (space) width is configurable?
  • edited June 2013
    I was just thinking the same, is the print position only specifiable to character spaces or can it utilise specific screen coordinates? That would get around having to put loads of pointless extra spaces in sometimes?
  • edited June 2013
    But using FZX, each character definition is fully configurable and uses an arbitrary sized grid, like this:

    30nk6k2.png

    In the example above, the character pixels are defined in a smaller 5x5 grid, and everything else is configurable. This particular FZX font specifies that all characters are 9 pixels tall ("baseline"), character "a" is located at a distance of 2 pixels from the top ("leading"), character "a" is 5 pixels wide ("width"), and there should be 2 pixels of distance before the next character ("tracking").

    Any reason why you need both "leading" and "baseline"? Given you know height already, I would assume knowing offset above baseline is enough. At least that always sufficed for me...

    And AFAIK, your "tracking" is often referred to as "kerning". Just nitpicking... :)

    Patrik
  • edited June 2013
    Patrik Rak wrote: »
    Any reason why you need both "leading" and "baseline"? Given you know height already, I would assume knowing offset above baseline is enough. At least that always sufficed for me...
    Did you read my response? I think there is a little mix-up in terminology.
    Patrik Rak wrote: »
    And AFAIK, your "tracking" is often referred to as "kerning". Just nitpicking... :)
    I am afraid that is not correct. They are two different things related to the horizontal spacing of characters. I’ll try to explain it as good as I can, although this is a bit specialist.

    First of all, in traditional typefaces letters always have a certain width that already includes some whitespace on the left and on the right of the black shape. These are called the left and right “sidebearings” or “margins”. This makes sure that when different letters are placed next to each other they have a certain distance, and don't clash.

    The designer of a typeface may find that certain combinations of two letters are too close, or too far apart. So in that case he can make an exception to the default spacing for that particular letter combination, and create a “kerning pair”. That is kerning.

    The user of a typeface may find that the normal spacing (including kerning) of a typeface looks too tight, or too wide. In that case many software allows users to give more spacing to the text overall, and that is called “tracking”.

    As far as I understood from Andrew when he wrote about the FZX format, spacing can be defined in two different ways (but correct me if I’m wrong). It is possible to define with one value how many pixels will be put between all letters all the time. So in this case only black shapes are defined for the font, and the spacing is done automatically. This could be called “tracking”, more or less.

    On the other hand it is also possible to define an advance width for every character individually. This will make the font data bigger, but gives the font designer the possibility to customise the spacing of every character.
  • edited June 2013
    jamorski wrote: »
    We Need Tech details!!!!!

    All tech details are available in file FZX_Standard.zip, this is the reason I didn't bother to put them in this post. The package also contains file "Sinclair.fzx.asm" with the source code of this font, so it can be used as an example (and template) to create others.
    jamorski wrote: »
    IIRC my effort used 2 bytes for height, width and then the character itself. I'm guessing FZX works on a similar principal?

    The FZX format has 3 parts:
    • Header: describes the general characteristics of the entire font that applies to all characters, such as body height ([strike]baseline[/strike] height) and tracking.
    • Table: describes the individual characteristics of each font, such as character width and vertical offset ([strike]leading[/strike] shift).
    • Definition: contains the character pixels.

    This way, there's no need to waste room in the character grid with the empty space above, below, and after each character, thus making this format very flexible and compact. :)
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited June 2013
    This is a great initiative, and I'm very happy to have been asked by Andrew for feedback during the development of FZX.

    Ops, Andrew told me but I forgot to mention your help in the original post. :(

    Sorry, I have just edited it to add this information now!

    I think this is a great way to make proportional fonts work on the Spectrum.

    Thanks!

    One thing that needs correction in the example above however, is some of the terminology.
    ? What is called ?baseline? should actually be called ?body height?. In Latin typography the baseline is the imaginary line where most uppercase and lowercase letters are standing on.

    OK, I will fix this terminology in the next update.

    ? ?Leading? is also not the correct word to describe the situation above. I would rather use the word ?vertical offset?. The term ?leading?, also sometimes referred to as ?line spacing?, is the distance between two lines of text, measured from baseline to baseline.

    Is there another term instead of vertical offset? The term offset also applies to the difference between 2 addresses in memory, which is part of the FZX format, thus also using offset for another purpose would be confusing...
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited June 2013
    Is there another term instead of vertical offset? The term offset also applies to the difference between 2 addresses in memory, which is part of the FZX format, thus also using offset for another purpose would be confusing...
    Vertical shift?
  • edited June 2013
    Arjun wrote: »
    Looks great and the FZX is a very nice initiative. Kudos to you and Andrew on this!

    Thanks!
    Arjun wrote: »
    One question I have is whether the spacing (space) width is configurable?

    All 4 parameters in this figure are configurable:

    el7f6b.png

    Actually the FZX format also supports "kern" (not shown in figure above), which basically "moves" an specific character a few pixels to the left, printing it closer to the previous character. Take a look at this example:

    azbgpc.png

    The example above shows font "Sinclair" that uses 2 pixels of distance (tracking) between characters. However if you look carefully, you should notice that letter semi-colon and letter "j" are only 1 pixel away from previous character. Both these characters are defined with "kern=1".
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited June 2013
    jamorski wrote: »
    I was just thinking the same, is the print position only specifiable to character spaces or can it utilise specific screen coordinates?

    The printing routine uses hires coordinates, so you can print anywhere on screen. For instance:
    PRINT #4;AT y,x;"FZX"
    

    In example above, y is the vertical coordinate (pixel line from 0 to 191) and x is the horizontal coordinate (pixel column from 0 to 255).
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited June 2013
    Patrik Rak wrote: »
    Any reason why you need both "leading" and "baseline"? Given you know height already, I would assume knowing offset above baseline is enough.

    The [strike]"baseline"[/strike] "height" is defined just once for the entire font. Each character only specifies its [strike]"leading"[/strike] "shift".
    Patrik Rak wrote: »
    And AFAIK, your "tracking" is often referred to as "kerning". Just nitpicking... :)

    We have both "tracking" and "kern", but they have different meanings. "Tracking" is the regular distance between every 2 characters, defined only once for the entire font. "Kern" is a smaller adjust in distance, specified for certain characters only.

    For instance, font "Sinclair" has "tracking=2", but characters "j" and semi-colon have "kern=1". Technically the alternative would be using "tracking=1" for this font and use additional empty spaces on the left of every character except "j" and semi-colon, but this would give users more work, spend more bytes in certain fonts, and do not allow printing most characters at pixel column zero. So there are some advantages in making this distinction...
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited June 2013
    As far as I understood from Andrew when he wrote about the FZX format, spacing can be defined in two different ways (but correct me if I?m wrong). It is possible to define with one value how many pixels will be put between all letters all the time. So in this case only black shapes are defined for the font, and the spacing is done automatically. This could be called ?tracking?, more or less.

    Exactly!
    On the other hand it is also possible to define an advance width for every character individually. This will make the font data bigger, but gives the font designer the possibility to customise the spacing of every character.

    No, this is not correct. The second alternative is "kern", which is a small adjust (3 pixels at most) in distance, as described in my previous post. In practice, it works as if the specified "kern" value was subtracted from "tracking" when calculating distance from previous character.

    Fortunately using "kern" doesn't make the font data any bigger, although this is the reason "kern" is limited to 3 pixels maximum.
    The designer of a typeface may find that certain combinations of two letters are too close, or too far apart. So in that case he can make an exception to the default spacing for that particular letter combination, and create a ?kerning pair?. That is kerning.

    Right. However "kerning pairs" are not very viable in 8 bit computers because they would make the font a lot larger, and the printing routine a lot slower. This is the reason FZX only provides a simplified version of "kern" for single characters, as described above.
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited June 2013
    Crisis wrote: »
    Very cool, usable and flexible indeed

    Thanks!
    Crisis wrote: »
    btw, since your demo loads the driver again, but as a FZX file, it crashes on it !

    Only if you configure your emulator to restart the tape automatically from the beginning...

    I could add some checking to prevent this, but I prefer to keep the demo as simple as possible, so people can easily understand the listing. Thanks for the notice anyway!
    Crisis wrote: »
    and a little nitpicking:
    inconsequent use, but with equal result of course,
        defw    hyphen_minus -$
        defb    [COLOR=Red]64[/COLOR]+5-1
    

    instead of overall use:
        defw    hyphen_minus -$
        defb    [COLOR=Red]16*4[/COLOR]+5-1
    

    Thanks, I will fix this definition in the next update!
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited June 2013
    Vertical shift?

    Perfect!
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited June 2013
    Ooh. Very exciting.

    You realise you've basically deprecated all my text driver stuff for Boriel's ZX Basic now, don't you? :P

    Ah well. Clearly we need to get this into the ZX Basic library wiki next.


    (And I had this idea bouncing around in my head for a text based game, too. And this is /perfect/ for it, I think. Awesome timing.)
  • edited June 2013
    Oh dear,
    I do like this font driver and its usage. It's soooo amazing! :-)
    If I had this routine in the 80s. We would have done an E-Book reader in the early 80s... ;-)
    But seriously: Small code, amazing abilities and easy to use. For me, nothing can be done better... Thanks to these creative programmers!

    There are no problems, only solutions (K. Flynn)

    Visit my ZX-Modules homepage with lot of free programs!
    Or visit my music-related website if you're interested in synthesizer music or computer animations and movies I've created
  • edited June 2013
    clausjahn wrote: »
    Oh dear,
    I do like this font driver and its usage. It's soooo amazing! :-)
    If I had this routine in the 80s. We would have done an E-Book reader in the early 80s... ;-)
    But seriously: Small code, amazing abilities and easy to use. For me, nothing can be done better... Thanks to these creative programmers!

    Thanks!

    Now we only need a good FZX editor. Any chance we could convince someone with a special talent for creating graphical editing tools, such as the author of ZX-Paintbrush? :)
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited June 2013
    Did you read my response? I think there is a little mix-up in terminology.

    Sorry, I skimmed over that...
    I am afraid that is not correct. They are two different things related to the horizontal spacing of characters. I’ll try to explain it as good as I can, although this is a bit specialist.

    Well, I have quite a bit of history with typesetting, so don't worry.
    First of all, in traditional typefaces letters always have a certain width that already includes some whitespace on the left and on the right of the black shape. These are called the left and right “sidebearings” or “margins”. This makes sure that when different letters are placed next to each other they have a certain distance, and don't clash.

    Right, these are assumed to be 0 here.
    The designer of a typeface may find that certain combinations of two letters are too close, or too far apart. So in that case he can make an exception to the default spacing for that particular letter combination, and create a “kerning pair”. That is kerning.

    Not exactly. The (extra) horizontal spacing between two glyphs is called kerning. If you increase it or decrease it (between neighboring glyphs), you refer to it as adjusting the kerning. So you are right about the kerning pair, but that is just specifying an exception for the otherwise default kerning of a glyph (which may or may not be zero).
    The user of a typeface may find that the normal spacing (including kerning) of a typeface looks too tight, or too wide. In that case many software allows users to give more spacing to the text overall, and that is called “tracking”.

    Indeed, but that it is not an attribute of a glyph at all, so it's unlikely what the OP had in mind in his image.
    As far as I understood from Andrew when he wrote about the FZX format, spacing can be defined in two different ways (but correct me if I’m wrong). It is possible to define with one value how many pixels will be put between all letters all the time. So in this case only black shapes are defined for the font, and the spacing is done automatically. This could be called “tracking”, more or less.

    On the other hand it is also possible to define an advance width for every character individually. This will make the font data bigger, but gives the font designer the possibility to customise the spacing of every character.

    Right. So what was the problem?

    EDIT: Ah, reading the later messages reveals what he meant. Perhaps it might be better to have a figure which shows few more letters printed and which illustrates which are per glyph parameters and which are not.

    Patrik
  • edited June 2013
    Crisis wrote: »
    true, but thats not the point. I think the routine might want a limiter on the drawing area. or different if you already implemented it.
    Then the driver wont crash, no matter what kind of garbage will be dumped.

    The routine already implements proper error handling, so it will never crash if a program tries to use it incorrectly. For instance, if the user tries to print something outside the screen, it will give you error "5 Out of screen".

    However it always assume the provided FZX font is valid, because checking font consistency every time a character is printed would make the routine extremely slow. Remember that the ZX-Spectrum is just a 8 bits machine, so we need to make some sacrifices to achieve good speed. Besides, how many machine code routines do you know for the Spectrum, that won't crash if you don't load it correctly in memory?
    Crisis wrote: »
    with indexing i look ahead to a bigger font-library, which would enhance the use of it.

    Current driver version already supports loading several fonts in memory at the same time, then switching between them using a pair of POKEs. This is described in the documentation.

    We are also planning to release another "enhanced" version of the FZX driver (slightly bigger but more powerful), that will provide an easier way to switch between multiple fonts. Both versions of the driver will be available, so you can choose which one you want.
    Crisis wrote: »
    we might need /want converters for existing PC / Alien fonts.
    In fact we DO need such converters by now !

    FZX is an open standard. If other people wants to create additional tools such as this converter, they are welcome!

    Would you be interested to implement this converter yourself? :)
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited June 2013
    Crisis wrote: »
    edit: ok something with 'kern', i guess by setting bit 15 and 14 you give 'kern' info.

    Exactly! The example you mentioned defines a 1 pixel "kern" for semi-colon.
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited June 2013
    Patrik Rak wrote: »
    Perhaps it might be better to have a figure which shows few more letters printed and which illustrates which are per glyph parameters and which are not.

    Thanks for the suggestion!

    I plan to post later a proper tutorial that should help clarify these issues, although I won't have time this week unfortunately...
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited June 2013
    Crisis wrote: »

    Any of them would be fine. Personally I suggest BDF because it seems to be simpler, well documented, and quite popular. A conversor from BDF to FZX would be great...
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited June 2013
    BTW I updated the files mentioned in the original post to incorporate the terminology changes proposed by Paul van der Laan. Please download them again!
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited June 2013
    Actually the FZX format also supports "kern" (not shown in figure above), which basically "moves" an specific character a few pixels to the left, printing it closer to the previous character. Take a look at this example:

    Ah.. I was actually referring to the SPACE (blank) character (Chr$ 32) which in Sinclair font is 8-pixels wide. But am I correct in thinking that if we specify kerning and leading for this character as well, we can reduce the spacing left between words?
  • edited June 2013
    BTW, FWIW, the Universum's excellent Desktop (yes, real DTP system on your humble Speccy - Proxima even used it to typeset their magazine with it) came with quite a few proportional fonts, some of which were VERY nice, IMHO. It might be worth putting them to use with this driver.

    Patrik
  • edited June 2013
    Arjun wrote: »
    Ah.. I was actually referring to the SPACE (blank) character (Chr$ 32) which in Sinclair font is 8-pixels wide. But am I correct in thinking that if we specify kerning and leading for this character as well, we can reduce the spacing left between words?

    The width of character SPACE is configurable, so it's easier to change it directly.

    For instance, font "Sinclair" defines width=6 for character SPACE:
    ; defw address -$ + kern
    ; defb 16 * shift + width - 1
    
    table:
    	defw	space -$
    	defb	16*0+6-1
    	defw	exclamation_mark -$
    	...
    

    Since "Sinclair" defines tracking=2 (which is a configuration that applies to the entire font), it means current spacing between words is:

    previous letter tracking + SPACE width + SPACE tracking = 2+6+2 = 10

    If you reduce the width of character SPACE to 1, the spacing between words will be:

    previous letter tracking + SPACE width + SPACE tracking = 2+1+2 = 5

    Now if you want an even smaller spacing between words, you can also add "kern" to character SPACE. If you use kern=3, it will be:

    previous letter tracking - SPACE kern + SPACE width + SPACE tracking = 2-3+1+2 = 2

    However that would be too small :)
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited June 2013
    Patrik Rak wrote: »
    BTW, FWIW, the Universum's excellent Desktop (yes, real DTP system on your humble Speccy - Proxima even used it to typeset their magazine with it) came with quite a few proportional fonts, some of which were VERY nice, IMHO. It might be worth putting them to use with this driver.

    These fonts look great!

    However the manual mentions lots of proportional fonts and at least 1 large font, but I could only find 4 regular sized fonts inside this program (using EXT-1 to EXT-4, or EXT-I). Where can I find the others?
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
Sign In or Register to comment.