Jump to content

Aros/Developer/Docs/Libraries/DiskFont

From Wikibooks, open books for an open world
Navbar for the Aros wikibook
Aros User
Aros User Docs
Aros User FAQs
Aros User Applications
Aros User DOS Shell
Aros/User/AmigaLegacy
Aros Dev Docs
Aros Developer Docs
Porting Software from AmigaOS/SDL
For Zune Beginners
Zune .MUI Classes
For SDL Beginners
Aros Developer BuildSystem
Specific platforms
Aros x86 Complete System HCL
Aros x86 Audio/Video Support
Aros x86 Network Support
Aros Intel AMD x86 Installing
Aros Storage Support IDE SATA etc
Aros Poseidon USB Support
x86-64 Support
Motorola 68k Amiga Support
Linux and FreeBSD Support
Windows Mingw and MacOSX Support
Android Support
Arm Raspberry Pi Support
PPC Power Architecture
misc
Aros Public License

Fonts

[edit | edit source]

AROS can use two different fonts and Other font types such as the more common TrueType (AROS uses FreeType equivalent) fonts, you need to use another library

A font is basically a mixture of the typeface (shape of letters), style (bold, plain, italic) and size (measured in fonts). The AROS has one built in font called Topaz which can be accessed at all times. If using a disk based font, then you need to use the diskfont.library to load a font from disk.


Bitmap Fonts

[edit | edit source]

bitplane data in a custom format along with some metadata for the horizontal offset and left/right side widths of each character. The loader is in Diskfont.library as OpenDiskFont(). Once loaded, a bitmap font is processed by OpenFont()

Wanderer calls IconList with NULL font, because diskfont.library is not able to open "arial.font". This happens on the other hand because diskfont.library is not finding the arial.font in FONTS:, because ExAll call returns 0 (== done) on its first call. This means not all fonts are returned, because the passed 1024 bytes buffer is too small to get them all in one go.

Loading a disk font

To load a diskfont, use the OpenDiskFont() function. You need to specify a TextAttr structure to state which font you require, the format of the command is:

TextFont font = OpenDiskFont(struct TextAttr textAttr)

The format of the TextAttr is:

struct TextAttr {
   STRPTR ta_Name; /* name of the font */
   UWORD ta_YSize; /* height of the font */
   UBYTE ta_Style; /* intrinsic font style */
   UBYTE ta_Flags; /* font preferences and flags */
};

For example, to specify a Topaz font, size 11 with Bold and Italic:

struct TextAttr myta = {
   "topaz.font"
   11,
   FSF_ITALIC | FSF_BOLD,
   NULL
};

If you are drawing with this font, you can change the default Rastport font with the SetFont() command and when done with it using the CloseFont() functions: e.g.

struct TextFont *myfont, *oldfont;
struct RastPort *myrp;
struct Window *mywin;

if (myfont = OpenDiskFont(&myta))
{
  /* you would probably set the font of the rastport you are going to use */
  myrp = mywin->RPort
  oldfont = myrp->Font;
  SetFont(myrp, myfont);

  /* perform whatever drawing you need to do */

  /* time to clean up. If the rastport is not exclusively yours,
  you may need to restore the original font or other Rasport values */
  SetFont(myrp, oldfont);
  CloseFont(myfont);
}

If you want to know what fonts are available in your program before trying to load one from disk, then you can use the AvailFonts() function which can read all the fonts from memory and disk and present them in an AvailFontsHeader structure, followed by a number of AvailFonts structures to be read by your program. You need to allocate some memory before calling this function to store the font information.

LONG error = AvailFonts(struct AvailFontsHeader *buffer, LONG bufBytes, ULONG flags )

For example,

int afShortage, afSize;
struct AvailFontsHeader *afh;

afSize = 400;
do {
   afh = (struct AvailFontsHeader *) AllocMem(afSize, 0);
   if (afh) {
       afShortage = AvailFonts(afh, afSize, AFF_MEMORY|AFF_DISK);
       if (afShortage) {
         FreeMem(afh, afSize);
         afSize += afShortage;
       }
  }
  else {
     fail("AllocMem of AvailFonts buffer afh failedn");
     break;
  }
}while (afShortage);

For each font size described in a FontContents (or TFontContents) structure, there is a corresponding file in that font's directory whose name is its size. For example, for the font size Sapphire-19, there is a file in the Sapphire directory called 19. That file is basically a DiskFontHeader disguised as a loadable DOS hunk and is known as a font descriptor file.

For a bitmap font, the ".font" file is a FontContentsHeader structure:

struct FontContentsHeader {
    UWORD   fch_FileID;             /* FCH_ID */
    UWORD   fch_NumEntries;         /* the number of FontContents elements */
    struct  FontContents fch_FC[];  /* or struct TFontContents fch_TFC[];  */
};

#define MAXFONTPATH 256

Where the fch_FileID field can be either:

FCH_ID    0x0f00    uses FontContents structures to describe the available sizes of this font.
TFCH_ID   0x0f02    uses TFontContents structures to describe the available sizes of this font.

The FontContents structure:

struct FontContents {
    char    fc_FileName[MAXFONTPATH];
    UWORD   fc_YSize;
    UBYTE   fc_Style;
    UBYTE   fc_Flags;
};
struct TFontContents {
    char    tfc_FileName[MAXFONTPATH-2];
    UWORD   tfc_TagCount;       /* including the TAG_DONE tag */
        /*
         *  if tfc_TagCount is non-zero, tfc_FileName is overlaid with
         *  Text Tags starting at:  (struct TagItem *)
         *      &tfc_FileName[MAXFONTPATH-(tfc_TagCount*sizeof
         *                                 (struct TagItem))]
         */
    UWORD   tfc_YSize;
    UBYTE   tfc_Style;
    UBYTE   tfc_Flags;
};
struct DiskFontHeader {
    ULONG     dfh_NextSegment;
    ULONG     dfh_ReturnCode;
    STRUCT    dfh,LN_SIZE;
    UWORD     dfh_FileID;
    UWORD     dfh_Revision;
    LONG      dfh_Segment;
    STRUCT    dfh,MAXFONTNAME;
    STRUCT    dfh-TF,tf_SIZEOF;
};


Does anyone know what program was used to generate the ttcourier fonts? They were committed by Georg in 2001.

IIRC BitLine (see Aminet, comes with source code). Loads font into memory using diskfont.library and then saves it to disk. Source font was truetype font which diskfont.library transforms into bitmap font during loading (if there's a font engine like the freetype based ones which can handle it).

There's a small problem with these fonts: the glyphs are all aligned to the left of their box rather than to the centre (this is one of the papercut bugs).

A quick look at the ttcourier font (with tools like sys:tools/fontinfo and the bitmap font editor "TypeFace" in sys:extras/misc/aminet/). It seems only some sizes (like 14) have the problem and problem is missing/zero kerning/spacing tables.

Also looking at the svn log of the font files ("14", etc.) in workbench/fonts/ it seems problem may have happened when the Euro character was (manually) added to the fonts (IIRC with Typeface font editor running under AROS -> maybe a bug there), as I did a quick test with the initial revision of the "14" file which did not seem to have the kerning/spacing tables missing.


FreeType Outline Fonts

[edit | edit source]

Note that depending on style and other things fonts are not not always rendered with the same HIDD method. See rom/graphics/text.c. The text not visible on the screenshot is those which gets rendered with BlitColorexpansion method.


Examples

[edit | edit source]
#include <diskfont/diskfont.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/diskfont.h>
#include <proto/utility.h>
#include <proto/graphics.h>

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

struct Library *DiskfontBase;
struct UtilityBase *UtilityBase;

UBYTE *buf;

void cleanup(char *msg)
{
    if (msg) printf("aftest: %s\n", msg);
    
    if (buf) FreeVec(buf);
    
    if (UtilityBase) CloseLibrary((struct Library *)UtilityBase);
    if (DiskfontBase) CloseLibrary(DiskfontBase);
    
    exit(0);
}

void openlibs(void)
{
    DiskfontBase = OpenLibrary("diskfont.library", 0);
    if (!DiskfontBase) cleanup("Cant open diskfont.library!");
    UtilityBase = (struct UtilityBase *) OpenLibrary("utility.library", 0);
    if (!UtilityBase) cleanup("Cant open utility.library!");
}

void action(void)
{
    struct TextFont *font;
    struct TextAttr ta;

    ta.ta_Name = "Vera Sans Bold Italic.font";
    ta.ta_Name = "xhelvetica.font";
    ta.ta_YSize = 11;
    ta.ta_Style = 0;
    ta.ta_Flags = 0;

    font = OpenDiskFont(&ta);
    if (font)
    {
	CloseFont(font);
    }
}

int main(void)
{
    openlibs();
    action();
    cleanup(0);

    return 0; /* keep compiler happy */
}

References

[edit | edit source]
struct TextFont *OpenDiskFont(struct TextAttr *textAttr)

LONG AvailFonts(STRPTR buffer, LONG bufBytes, LONG flags) 
 AFF_MEMORY
 AFF_DISK
 AFF_SCALED
 AFF_TAGGED
struct FontContentsHeader *NewFontContents(BPTR fontsLock, STRPTR fontName) 
struct DiskFont *NewScaledDiskFont(struct TextFont *sourceFont, struct TextAttr *destTextAttr)

void DisposeFontContents(struct FontContentsHeader *fontContentsHeader)