phf file structure ?

Hello, All!

Is there any documentation about .phf file structure ?

With best regards, Mike Gorchak.

Mike Gorchak <mike@malva.ua.remove.this.for.no.spam> wrote:

Hello, All!

Is there any documentation about .phf file structure ?

With best regards, Mike Gorchak.

Try searching this newgroup, the newuser one, or comp.os.qnx,
the information has been posted many times. Under QNX6, it
is preferred that one uses the TrueType format.

Regards.

Hello, dleach@qnx.com!

d> Try searching this newgroup, the newuser one, or comp.os.qnx,
d> the information has been posted many times. Under QNX6, it
d> is preferred that one uses the TrueType format.

Sorry but I didn’t find any posts that describes internal structure of .phf
files, maybe you misunderstand me, but I asks not about ‘font installing
problems’, I ask about internal structure of phf file, maybe somewhere
exists reverse utility like phf2bdf ?

Thanks !

With best regards, Mike Gorchak.

Mike Gorchak <mike@malva.ua.remove.this.for.no.spam> wrote:

Hello, > dleach@qnx.com> !

d> Try searching this newgroup, the newuser one, or comp.os.qnx,
d> the information has been posted many times. Under QNX6, it
d> is preferred that one uses the TrueType format.

Sorry but I didn’t find any posts that describes internal structure of .phf
files, maybe you misunderstand me, but I asks not about ‘font installing
problems’, I ask about internal structure of phf file, maybe somewhere
exists reverse utility like phf2bdf ?

Thanks !

With best regards, Mike Gorchak.

I understood the question, the data must have been bumped from the news server.
Here is the format for QNX4 PHFs (v1). I do not have a document for the QNX6 PHF(v2)
format. I believe I gave the data structures to Igor for the PHF(v2) format.
If you cannot get in touch with him, I will dig them out when I get a chance.
Igor reads these newsgroups, as well as comp.os.qnx .


TABSTOP = 4

//
/** !!NOTE!! BEFORE EDITING ANY FONT FILE, MAKE /
/
A BACKUP!!! (You have been WARNED!!) **/
/
/

1.0 An Overview of the Photon Font (PHFv1) File

The Photon Font File (which we will refer to as a PHF from this point on),
is generated from universally available .bdf files. The utility used to
create the PHF is called bdf_2_phf, and ships standard with Photon.

There are four distinct components to a PHF. They are as follows:

  1. The header component
  2. The bitmap component.
  3. The metric component
  4. The index component

The PHF format is also structured in the order listed above. A visual
representation is below:


--------------------------------- Offset 0
| |
| Header Component |

Bitmap Component

| |
| Metric Component |

Index Component

--------------------------------- Offset N

Each component, with respect to character order, runs from the smallest Unicode
value to the largest. For example, if the PHF contains the Unicode range 0x0020 0x00FF,
the first element in the Bitmap, Metric, and Index component will correspond to 0x0020,
and the second element in each component to 0x0021, and so on.

1.1 THE HEADER COMPONENT

The header structure contains information relevant to
the entire font, and is defined as follows:

typedef struct
{ short Status; /* For a file, MUST be set to ‘QW’ */
unsigned short Flags;
_PointStruct Size;
_PointStruct Extent;
unsigned short Spare1;
unsigned short ImageOffset;
unsigned short BPChar;
unsigned short WidthTabOffset;
unsigned short Spare2[4];
short UnderLinePos;
short BaseLinePos;
unsigned short AsciiOffset;
unsigned short AsciiLength;
char Description;
} _FontStruct;

A _PointStruct is defined as follows:

typedef struct
{ short x, y;
} _PointStruct;

1.2 THE INDEX COMPONENT

Bitmaps for each glyph can be of varying sizes.
An offset into the PHF is required in order to
locate the desired bitmap. The _FONT_IndexPerChar
bit will be high in all currently published PHFs.

if(Header.Flags & _FONT_IndexPerChar)
{ Header.AsciiLength * sizeof(short);
}

Flags are as follows:

#define _FONT_IndexPerChar 0x0100

1.3 THE METRIC COMPONENT

Depending on the type of PHF (there are currently two), the metric
component will be different. The definitions are below.

if(Header.Flags & _FONT_WidthPerChar)
{ Header.AsciiLength * sizeof(short)
}
else if(Heaader.Flags & _FONT_MetricPerChar)
{ Header.AsciiLength * sizeof(_FontMetricStruct)
}
else
return(FALSE);

A _FontMetricStruct is defined as:

typedef struct
{ _PointStruct Size; /* Bytes per line == (Size.x+7)>>3 */
signed char BaseLinePos;
signed char LeftBearing;
short Width;
} _FontMetricStruct;

Flags are as follows:

#define _FONT_WidthPerChar 0x0200
#define _FONT_MetricPerChar 0x0400 /* Metrics and Width are exclusive */

1.4 THE BITMAP COMPONENT

This component consists of a byte array. Each glyph bitmap
is access by seeking to the offset specified in the Index
Component, then reading/writing the bitmap.

1.5 EXAMPLE

What follows is a simple terminal based program that allows text based
editing of a PHF. Also appended, are necessary header files.

/* edit.c */

#include <fcntl.h>
#include <stdio.h>
#include <sys/qnxterm.h>
#include <unistd.h>
#include <photon/PhInternal.h>
#include <photon/Pf.h>
#include “__g_fontfile.h”

#define INDENT 2

_FontStruct hdr;
short * width = NULL, * ix = NULL;
_FontMetricStruct * metric = NULL;
char bitmap[1024];
int fd = -1, posx = 0, posy = 0, szx = 0, szy = 0, bitmaplen = 0, bitmapbpl = 0;

int FindDef(int from, int dir)
{ int i = 0;

if(dir == 1)
{ for (i = (from != -1) ? from + 1 : 0; i < hdr.AsciiLength; ++i)
if(hdr.Flags & _FONT_WidthPerChar && width _!= 0)
return(i);
else if(hdr.Flags & _FONT_MetricPerChar && metric.Width != 0)
return(i);
else
return(i);

return(from);
}
else if (dir == -1)
{ for(i = (from != -1) ? from - 1 : hdr.AsciiLength - 1; i >= 0; --i)
if(hdr.Flags & _FONT_WidthPerChar && width != 0)
return(i);
else if(hdr.Flags & _FONT_MetricPerChar && metric.Width != 0)
return(i);
else
return(i);

return(from);
}

return(-1);
}

void DrawImage(int ch)
{ int i = 0, x = 0, y = 0;

if(hdr.Flags & _FONT_WidthPerChar)
{ szx = width[ch], szy = hdr.Size.y;
}
else if(hdr.Flags & _FONT_MetricPerChar)
{ szx = metric[ch].Size.x, szy = metric[ch].Size.y;
}
else
{ /* should never happen at this point /
}

lseek(fd, ix[ch], SEEK_SET);
read(fd, bitmap, bitmaplen = (bitmapbpl = ((szx + 7) >> 3)) * szy);
term_clear(TERM_CLS_SCR);
term_printf(0, 0, TERM_HILIGHT, “U+%04X”, hdr.AsciiOffset + ch);

for(y = 0; y < szy; ++y)
for(x = 0; x < bitmapbpl; ++x)
for(i = 0; i < 8; ++i)
term_printf(INDENT + y, INDENT + x * 8 + i, TERM_NORMAL, (bitmap[y * bitmapbpl + x] & (0x80 >> i)) ? "
" : " “);

term_printf(INDENT + szy + 1, 0, TERM_HILIGHT, “BROWSE?”);
term_clear(TERM_CLS_EOL);
term_flush();
}

void SaveImage(int ch)
{ lseek(fd, ix[ch], SEEK_SET);
write(fd, bitmap, bitmaplen);
}

void main(int argc, char argv[])
{ int ch = 0, bit = 0, quit = 0, edit = 0, dirty = 0;
unsigned char byte;

if((fd = open(argv[1], O_RDWR)) == -1)
return;

read(fd, &hdr, sizeof(_FontStruct));

if(hdr.Flags & _FONT_IndexPerChar)
{ if((ix = malloc(hdr.AsciiLength * sizeof(short))) == NULL)
return;

lseek(fd, hdr.ImageOffset, SEEK_SET);
read(fd, ix, hdr.AsciiLength * sizeof(short));
}

if(hdr.Flags & _FONT_WidthPerChar)
{ if((width = malloc(hdr.AsciiLength * sizeof(short))) == NULL)
return;

lseek(fd, hdr.WidthTabOffset, SEEK_SET);
read(fd, width, hdr.AsciiLength * sizeof(short));
}
else if(hdr.Flags & _FONT_MetricPerChar)
{ if((metric = malloc(hdr.AsciiLength * sizeof(_FontMetricStruct))) == NULL)
return;

lseek(fd, hdr.WidthTabOffset, SEEK_SET);
read(fd, metric, hdr.AsciiLength * sizeof(_FontMetricStruct));
}
else
{ return;
}

term_load();
term_clear(TERM_CLS_SCR);
ch = FindDef(-1, 1);
DrawImage(ch);

quit = edit = 0;

while(!quit)
switch(term_key())
{ case K_LEFT: if(edit)
{ if(posx > 0)
–posx;

term_cur(INDENT + posy, INDENT + posx);
}
else
{ ch = FindDef(ch, -1);
DrawImage(ch);
}
break;

case K_RIGHT: if(edit)
{ if(posx < szx - 1)
++posx;

term_cur(INDENT + posy, INDENT + posx);
}
else
{ ch = FindDef(ch, 1);
DrawImage(ch);
}
break;

case K_UP: if(edit)
{ if(posy > 0)
–posy;

term_cur(INDENT + posy, INDENT + posx);
}
else
{ ch = FindDef(ch, -1);
DrawImage(ch);
}
break;

case K_DOWN: if(edit)
{ if(posy < szy - 1)
++posy;

term_cur(INDENT + posy, INDENT + posx);
}
else
{ ch = FindDef(ch, 1);
DrawImage(ch);
}
break;

case K_ENTER: if(edit = !edit)
{ dirty = 0;
posx = posy = 0;
term_printf(INDENT + szy + 1, 0, TERM_HILIGHT, “EDIT?”);
term_clear(TERM_CLS_EOL);
term_cur(INDENT + posy, INDENT + posx);
}
else
{ if(dirty)
SaveImage(ch);

term_printf(INDENT + szy + 1, 0, TERM_HILIGHT, “BROWSE?”);
term_clear(TERM_CLS_EOL);
}
break;

case ’ ': if(edit)
{ bit = posx & 0x7;
byte = bitmap[posy * bitmapbpl + (posx >> 3)] ^= (0x80 >> bit);
term_printf(INDENT + posy, INDENT + posx, TERM_NORMAL, (byte & (0x80 >> bit)) ? "
” : " ");
term_cur(INDENT + posy, INDENT + posx);
++dirty;
}
break;

case ‘0’: if(edit)
{ bit = posx & 0x7;
byte = bitmap[posy * bitmapbpl + (posx >> 3)] &= ~(0x80 >> bit);
term_printf(INDENT + posy, INDENT + posx, TERM_NORMAL, (byte & (0x80 >> bit)) ? “" : " ");
term_cur(INDENT + posy, INDENT + posx);
++dirty;
}
break;

case ‘1’: if(edit)
{ bit = posx & 0x7;
byte = bitmap[posy * bitmapbpl + (posx >> 3)] |= (0x80 >> bit);
term_printf(INDENT + posy, INDENT + posx, TERM_NORMAL, (byte & (0x80 >> bit)) ? "
” : " ");
term_cur(INDENT + posy, INDENT + posx);
++dirty;
}
break;

case K_ESC:
case ‘q’:
case ‘Q’: if(edit)
{ edit = 0;
DrawImage(ch);
}
else
{ ++quit;
}
break;

}

term_restore();
close(fd);
}


/* __g_fontfile.h /

/
_GR_FontStruct.Flags definitions /
#define _FONT_TypeMask 0x000F /
Mask for font type /
#define _FONT_Bitmapped 0x0000 /
Font type: Bitmapped /

#define _FONT_IndexPerChar 0x0100
#define _FONT_WidthPerChar 0x0200
#define _FONT_MetricPerChar 0x0400 /
Metrics and Width are exclusive /

#define _FS_Italic 0x0001
#define _FS_Oblique 0x0002
#define _FS_RevItalic 0x0004
#define _FS_Bold 0x0010

typedef struct {
short x, y;
} _PointStruct;

typedef struct {
_PointStruct Size; /
Bytes per line == (Size.x+7)>>3 /
signed char BaseLinePos;
signed char LeftBearing;
short Width;
} _FontMetricStruct;

typedef struct {
short Status; /
For a file, MUST be set to ‘QW’ */
unsigned short Flags;
_PointStruct Size;
_PointStruct Extent;
unsigned short Spare1;
unsigned short ImageOffset;
unsigned short BPChar;
unsigned short WidthTabOffset;
unsigned short Spare2[4];
short UnderLinePos;
short BaseLinePos;
unsigned short AsciiOffset;
unsigned short AsciiLength;
char Description;
} _FontStruct;

1.5 CAVEATS ABOUT A PHF
-------------------

bdf_2_phf ships with Photon. You will want UNICODE BDF
files (a MUST). Try www.unicode.org as a starting point.
One caveat, PHFs cannot be larger than 64k per file.
Here is a script used to create a font, where size
had to be manipulated. The -S (start) and -N (amount) switches
were modified to get each file <= 64k.

If you encounter a font that requires it
to be split up, you will have to put it in your
extension list (fontcfg). Non-asain BDF files usually
do not need to be split up …

MAKEFONTS SCRIPT:

#!/bin/sh

Usage: makefonts bdf_filename

If you change the size, you’ll probably have to modify

the ranges to keep the files below 64k apiece.\


SIZE=16
BDF_FILE=something_big.bdf
CMD_BDF2PHF=/usr/photon/bin/bdf_2_phf


$CMD_BDF2PHF -S0x20 -N0x1Fe0 -Ouk00-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x2000 -N0xC00 -Ouk20-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x3000 -N0x1000 -Ouk30-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x4000 -N0x1600 -Ouk40-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x5600 -N0x400 -Ouk56-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x5a00 -N0x400 -Ouk5A-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x5e00 -N0x500 -Ouk5E-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x6300 -N0x500 -Ouk63-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x6800 -N0x700 -Ouk68-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x6F00 -N0x500 -Ouk6F-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x7400 -N0x500 -Ouk74-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x7900 -N0x500 -Ouk79-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x7E00 -N0x500 -Ouk7E-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x8300 -N0x500 -Ouk83-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x8800 -N0x600 -Ouk88-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x8E00 -N0x600 -Ouk8E-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x9400 -N0x500 -Ouk94-$SIZE.phf $BDF_FILE

$CMD_BDF2PHF -S0x9900 -N0xA00 -Ouk99-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xa300 -N0xA00 -OukA3-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xad00 -N0x500 -OukAD-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xb200 -N0x500 -OukB2-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xb700 -N0x500 -OukB7-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xbc00 -N0x500 -OukBC-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xc100 -N0x500 -OukC1-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xc600 -N0x500 -OukC6-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xd000 -N0x500 -OukD0-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xd500 -N0x1b00 -OukD5-$SIZE.phf $BDF_FILE

$CMD_BDF2PHF -S0xF000 -N0xFE6 -OukF0-$SIZE.phf $BDF_FILE_

Hi Derek

This is very interesting, though I must admit I don’t understand all of it.
I just haven’t taken the time to scrutinize it all with an actual font file,
yet.

But here’s my thought. If I wanted to make up say two special characters
(for which I currently use graphic bitmaps) I could:

  1. make up my own new font name
  2. define just these two characters
  3. tell photon that if a character is missing from my font, to substitute
    some other font
  4. then specify my font and use my characters ANYWHERE I can currently use a
    text character and those text fields will use my font for just those two
    characters and the other font for every other character in that text field

If so, that’s way cool. It sucks having to overlay a graphic label on top
of a text widget.

So here’s the question: After I make up my bitmaps, which I already have,
how much extra work it is to make up a font that uses these bitmaps from
scratch?

Also, I assume that I would have to make up a bitmap for each font size, or
would these be scaleable?

“Derek Leach” <dleach@qnx.com> wrote in message
news:alann2$5ft$2@inn.qnx.com

Mike Gorchak <> mike@malva.ua.remove.this.for.no.spam> > wrote:
Hello, > dleach@qnx.com> !

d> Try searching this newgroup, the newuser one, or comp.os.qnx,
d> the information has been posted many times. Under QNX6, it
d> is preferred that one uses the TrueType format.

Sorry but I didn’t find any posts that describes internal structure of
…phf
files, maybe you misunderstand me, but I asks not about ‘font installing
problems’, I ask about internal structure of phf file, maybe somewhere
exists reverse utility like phf2bdf ?

Thanks !

With best regards, Mike Gorchak.

I understood the question, the data must have been bumped from the news
server.
Here is the format for QNX4 PHFs (v1). I do not have a document for the
QNX6 PHF(v2)
format. I believe I gave the data structures to Igor for the PHF(v2)
format.
If you cannot get in touch with him, I will dig them out when I get a
chance.
Igor reads these newsgroups, as well as comp.os.qnx .


TABSTOP = 4

//
/** !!NOTE!! BEFORE EDITING ANY FONT FILE, MAKE /
/
A BACKUP!!! (You have been WARNED!!) **/
/
/

1.0 An Overview of the Photon Font (PHFv1) File

The Photon Font File (which we will refer to as a PHF from this point on),
is generated from universally available .bdf files. The utility used to
create the PHF is called bdf_2_phf, and ships standard with Photon.

There are four distinct components to a PHF. They are as follows:

  1. The header component
  2. The bitmap component.
  3. The metric component
  4. The index component

The PHF format is also structured in the order listed above. A visual
representation is below:


--------------------------------- Offset 0
| |
| Header Component |

Bitmap Component

| |
| Metric Component |

Index Component

--------------------------------- Offset N

Each component, with respect to character order, runs from the smallest
Unicode
value to the largest. For example, if the PHF contains the Unicode range
0x0020 0x00FF,
the first element in the Bitmap, Metric, and Index component will
correspond to 0x0020,
and the second element in each component to 0x0021, and so on.

1.1 THE HEADER COMPONENT

The header structure contains information relevant to
the entire font, and is defined as follows:

typedef struct
{ short Status; /* For a file, MUST be set to ‘QW’
*/
unsigned short Flags;
_PointStruct Size;
_PointStruct Extent;
unsigned short Spare1;
unsigned short ImageOffset;
unsigned short BPChar;
unsigned short WidthTabOffset;
unsigned short Spare2[4];
short UnderLinePos;
short BaseLinePos;
unsigned short AsciiOffset;
unsigned short AsciiLength;
char Description;
} _FontStruct;

A _PointStruct is defined as follows:

typedef struct
{ short x, y;
} _PointStruct;

1.2 THE INDEX COMPONENT

Bitmaps for each glyph can be of varying sizes.
An offset into the PHF is required in order to
locate the desired bitmap. The _FONT_IndexPerChar
bit will be high in all currently published PHFs.

if(Header.Flags & _FONT_IndexPerChar)
{ Header.AsciiLength * sizeof(short);
}

Flags are as follows:

#define _FONT_IndexPerChar 0x0100

1.3 THE METRIC COMPONENT

Depending on the type of PHF (there are currently two), the metric
component will be different. The definitions are below.

if(Header.Flags & _FONT_WidthPerChar)
{ Header.AsciiLength * sizeof(short)
}
else if(Heaader.Flags & _FONT_MetricPerChar)
{ Header.AsciiLength * sizeof(_FontMetricStruct)
}
else
return(FALSE);

A _FontMetricStruct is defined as:

typedef struct
{ _PointStruct Size; /* Bytes per line == (Size.x+7)>>3
*/
signed char BaseLinePos;
signed char LeftBearing;
short Width;
} _FontMetricStruct;

Flags are as follows:

#define _FONT_WidthPerChar 0x0200
#define _FONT_MetricPerChar 0x0400 /* Metrics and Width are exclusive
*/

1.4 THE BITMAP COMPONENT

This component consists of a byte array. Each glyph bitmap
is access by seeking to the offset specified in the Index
Component, then reading/writing the bitmap.

1.5 EXAMPLE

What follows is a simple terminal based program that allows text based
editing of a PHF. Also appended, are necessary header files.

/* edit.c */

#include <fcntl.h
#include <stdio.h
#include <sys/qnxterm.h
#include <unistd.h
#include <photon/PhInternal.h
#include <photon/Pf.h
#include “__g_fontfile.h”

#define INDENT 2

_FontStruct hdr;
short * width = NULL, * ix = NULL;
_FontMetricStruct * metric = NULL;
char bitmap[1024];
int fd = -1, posx = 0, posy = 0, szx = 0, szy = 0, bitmaplen = 0,
bitmapbpl = 0;

int FindDef(int from, int dir)
{ int i = 0;

if(dir == 1)
{ for (i = (from != -1) ? from + 1 : 0; i < hdr.AsciiLength; ++i)
if(hdr.Flags & _FONT_WidthPerChar && width > _!= 0)
return(i);
else if(hdr.Flags & _FONT_MetricPerChar && metric> .Width != 0)
return(i);
else
return(i);

return(from);
}
else if (dir == -1)
{ for(i = (from != -1) ? from - 1 : hdr.AsciiLength - 1; i >= 0; --i)
if(hdr.Flags & _FONT_WidthPerChar && width > != 0)
return(i);
else if(hdr.Flags & _FONT_MetricPerChar && metric> .Width != 0)
return(i);
else
return(i);

return(from);
}

return(-1);
}

void DrawImage(int ch)
{ int i = 0, x = 0, y = 0;

if(hdr.Flags & _FONT_WidthPerChar)
{ szx = width[ch], szy = hdr.Size.y;
}
else if(hdr.Flags & _FONT_MetricPerChar)
{ szx = metric[ch].Size.x, szy = metric[ch].Size.y;
}
else
{ /* should never happen at this point /
}

lseek(fd, ix[ch], SEEK_SET);
read(fd, bitmap, bitmaplen = (bitmapbpl = ((szx + 7) >> 3)) * szy);
term_clear(TERM_CLS_SCR);
term_printf(0, 0, TERM_HILIGHT, “U+%04X”, hdr.AsciiOffset + ch);

for(y = 0; y < szy; ++y)
for(x = 0; x < bitmapbpl; ++x)
for(i = 0; i < 8; ++i)
term_printf(INDENT + y, INDENT + x * 8 + i, TERM_NORMAL, (bitmap[y *
bitmapbpl + x] & (0x80 >> i)) ? "
" : " “);

term_printf(INDENT + szy + 1, 0, TERM_HILIGHT, “BROWSE?”);
term_clear(TERM_CLS_EOL);
term_flush();
}

void SaveImage(int ch)
{ lseek(fd, ix[ch], SEEK_SET);
write(fd, bitmap, bitmaplen);
}

void main(int argc, char argv[])
{ int ch = 0, bit = 0, quit = 0, edit = 0, dirty = 0;
unsigned char byte;

if((fd = open(argv[1], O_RDWR)) == -1)
return;

read(fd, &hdr, sizeof(_FontStruct));

if(hdr.Flags & _FONT_IndexPerChar)
{ if((ix = malloc(hdr.AsciiLength * sizeof(short))) == NULL)
return;

lseek(fd, hdr.ImageOffset, SEEK_SET);
read(fd, ix, hdr.AsciiLength * sizeof(short));
}

if(hdr.Flags & _FONT_WidthPerChar)
{ if((width = malloc(hdr.AsciiLength * sizeof(short))) == NULL)
return;

lseek(fd, hdr.WidthTabOffset, SEEK_SET);
read(fd, width, hdr.AsciiLength * sizeof(short));
}
else if(hdr.Flags & _FONT_MetricPerChar)
{ if((metric = malloc(hdr.AsciiLength * sizeof(_FontMetricStruct))) ==
NULL)
return;

lseek(fd, hdr.WidthTabOffset, SEEK_SET);
read(fd, metric, hdr.AsciiLength * sizeof(_FontMetricStruct));
}
else
{ return;
}

term_load();
term_clear(TERM_CLS_SCR);
ch = FindDef(-1, 1);
DrawImage(ch);

quit = edit = 0;

while(!quit)
switch(term_key())
{ case K_LEFT: if(edit)
{ if(posx > 0)
–posx;

term_cur(INDENT + posy, INDENT + posx);
}
else
{ ch = FindDef(ch, -1);
DrawImage(ch);
}
break;

case K_RIGHT: if(edit)
{ if(posx < szx - 1)
++posx;

term_cur(INDENT + posy, INDENT + posx);
}
else
{ ch = FindDef(ch, 1);
DrawImage(ch);
}
break;

case K_UP: if(edit)
{ if(posy > 0)
–posy;

term_cur(INDENT + posy, INDENT + posx);
}
else
{ ch = FindDef(ch, -1);
DrawImage(ch);
}
break;

case K_DOWN: if(edit)
{ if(posy < szy - 1)
++posy;

term_cur(INDENT + posy, INDENT + posx);
}
else
{ ch = FindDef(ch, 1);
DrawImage(ch);
}
break;

case K_ENTER: if(edit = !edit)
{ dirty = 0;
posx = posy = 0;
term_printf(INDENT + szy + 1, 0, TERM_HILIGHT, “EDIT?”);
term_clear(TERM_CLS_EOL);
term_cur(INDENT + posy, INDENT + posx);
}
else
{ if(dirty)
SaveImage(ch);

term_printf(INDENT + szy + 1, 0, TERM_HILIGHT, “BROWSE?”);
term_clear(TERM_CLS_EOL);
}
break;

case ’ ': if(edit)
{ bit = posx & 0x7;
byte = bitmap[posy * bitmapbpl + (posx >> 3)] ^= (0x80 >> bit);
term_printf(INDENT + posy, INDENT + posx, TERM_NORMAL, (byte & (0x80
bit)) ? "
” : " ");
term_cur(INDENT + posy, INDENT + posx);
++dirty;
}
break;

case ‘0’: if(edit)
{ bit = posx & 0x7;
byte = bitmap[posy * bitmapbpl + (posx >> 3)] &= ~(0x80 >> bit);
term_printf(INDENT + posy, INDENT + posx, TERM_NORMAL, (byte & (0x80
bit)) ? “" : " ");
term_cur(INDENT + posy, INDENT + posx);
++dirty;
}
break;

case ‘1’: if(edit)
{ bit = posx & 0x7;
byte = bitmap[posy * bitmapbpl + (posx >> 3)] |= (0x80 >> bit);
term_printf(INDENT + posy, INDENT + posx, TERM_NORMAL, (byte & (0x80
bit)) ? "
” : " ");
term_cur(INDENT + posy, INDENT + posx);
++dirty;
}
break;

case K_ESC:
case ‘q’:
case ‘Q’: if(edit)
{ edit = 0;
DrawImage(ch);
}
else
{ ++quit;
}
break;

}

term_restore();
close(fd);
}


/* __g_fontfile.h /

/
_GR_FontStruct.Flags definitions /
#define _FONT_TypeMask 0x000F /
Mask for font type /
#define _FONT_Bitmapped 0x0000 /
Font type: Bitmapped /

#define _FONT_IndexPerChar 0x0100
#define _FONT_WidthPerChar 0x0200
#define _FONT_MetricPerChar 0x0400 /
Metrics and Width are exclusive /

#define _FS_Italic 0x0001
#define _FS_Oblique 0x0002
#define _FS_RevItalic 0x0004
#define _FS_Bold 0x0010

typedef struct {
short x, y;
} _PointStruct;

typedef struct {
_PointStruct Size; /
Bytes per line == (Size.x+7)>>3 /
signed char BaseLinePos;
signed char LeftBearing;
short Width;
} _FontMetricStruct;

typedef struct {
short Status; /
For a file, MUST be set to ‘QW’ */
unsigned short Flags;
_PointStruct Size;
_PointStruct Extent;
unsigned short Spare1;
unsigned short ImageOffset;
unsigned short BPChar;
unsigned short WidthTabOffset;
unsigned short Spare2[4];
short UnderLinePos;
short BaseLinePos;
unsigned short AsciiOffset;
unsigned short AsciiLength;
char Description;
} _FontStruct;

1.5 CAVEATS ABOUT A PHF
-------------------

bdf_2_phf ships with Photon. You will want UNICODE BDF
files (a MUST). Try > www.unicode.org > as a starting point.
One caveat, PHFs cannot be larger than 64k per file.
Here is a script used to create a font, where size
had to be manipulated. The -S (start) and -N (amount) switches
were modified to get each file <= 64k.

If you encounter a font that requires it
to be split up, you will have to put it in your
extension list (fontcfg). Non-asain BDF files usually
do not need to be split up …

MAKEFONTS SCRIPT:

#!/bin/sh

Usage: makefonts bdf_filename

If you change the size, you’ll probably have to modify

the ranges to keep the files below 64k apiece.\


SIZE=16
BDF_FILE=something_big.bdf
CMD_BDF2PHF=/usr/photon/bin/bdf_2_phf


$CMD_BDF2PHF -S0x20 -N0x1Fe0 -Ouk00-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x2000 -N0xC00 -Ouk20-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x3000 -N0x1000 -Ouk30-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x4000 -N0x1600 -Ouk40-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x5600 -N0x400 -Ouk56-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x5a00 -N0x400 -Ouk5A-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x5e00 -N0x500 -Ouk5E-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x6300 -N0x500 -Ouk63-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x6800 -N0x700 -Ouk68-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x6F00 -N0x500 -Ouk6F-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x7400 -N0x500 -Ouk74-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x7900 -N0x500 -Ouk79-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x7E00 -N0x500 -Ouk7E-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x8300 -N0x500 -Ouk83-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x8800 -N0x600 -Ouk88-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x8E00 -N0x600 -Ouk8E-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0x9400 -N0x500 -Ouk94-$SIZE.phf $BDF_FILE

$CMD_BDF2PHF -S0x9900 -N0xA00 -Ouk99-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xa300 -N0xA00 -OukA3-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xad00 -N0x500 -OukAD-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xb200 -N0x500 -OukB2-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xb700 -N0x500 -OukB7-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xbc00 -N0x500 -OukBC-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xc100 -N0x500 -OukC1-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xc600 -N0x500 -OukC6-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xd000 -N0x500 -OukD0-$SIZE.phf $BDF_FILE
$CMD_BDF2PHF -S0xd500 -N0x1b00 -OukD5-$SIZE.phf $BDF_FILE

$CMD_BDF2PHF -S0xF000 -N0xFE6 -OukF0-$SIZE.phf $BDF_FILE_

“Bill Caroselli (Q-TPS)” <QTPS@earthlink.net> wrote:

Hi Derek

This is very interesting, though I must admit I don’t understand all of it.
I just haven’t taken the time to scrutinize it all with an actual font file,
yet.

But here’s my thought. If I wanted to make up say two special characters
(for which I currently use graphic bitmaps) I could:

  1. make up my own new font name
  2. define just these two characters
  3. tell photon that if a character is missing from my font, to substitute
    some other font
  4. then specify my font and use my characters ANYWHERE I can currently use a
    text character and those text fields will use my font for just those two
    characters and the other font for every other character in that text field

If so, that’s way cool. It sucks having to overlay a graphic label on top
of a text widget.

So here’s the question: After I make up my bitmaps, which I already have,
how much extra work it is to make up a font that uses these bitmaps from
scratch?

Also, I assume that I would have to make up a bitmap for each font size, or
would these be scaleable?
[snip]

BDFs are not scalable, so yes, you would have to make one for each size.
In Rtp, you can use bdftophf2 to get the PHFv2 formatted font, results
in faster access usually. If you search the web, you should come
across many Unicode BDFs for examples. BDFs are just text files.

If this is for a product, you may wish to buy a TrueType creation program.
FontSuite or something or other, or commision someone on the web to
do it. With few characters, you could have them hint it and such, and
it would probably not cost much. This would also give you anti-aliased output.

Regards.