1.0 An Overview of the Photon Font (PHF) 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[i] != 0)
   return(i);
    else if(hdr.Flags & _FONT_MetricPerChar && metric[i].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[i] != 0)
    return(i);
     else if(hdr.Flags & _FONT_MetricPerChar && metric[i].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
 
 
 
 

Сайт создан в системе uCoz