summaryrefslogtreecommitdiff
path: root/DOCUMENTATION
blob: c72c99b38bc0e09176bc7b21b1e8fb02aaa016fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
mmap-unifont - Documentation
============================

The mmap-unifont package provides a pre-compiled font based on GNU-Unifont. It
installs two files into the system, namely:
    $prefix/lib/pkgconfig/mmap-unifont.pc
    $prefix/share/mmap-unifont/mmap-unifont.bin

The first file is a pkg-config file to test whether mmap-unifont is installed
and to retrieve configuration options. It includes the following definition
(amongst others):
    pkgdatadir=${datadir}/@PACKAGE@

The second file is the actual pre-compiled font. To access it, you're highly
recommended to read the 'pkgdatadir' variable from the pkg-config file. The font
file can then be accessed via:
    ${pkgdatadir}/mmap-unifont.bin

The usual way to access the file is:
    fd = open(PATH, O_RDONLY | O_CLOEXEC);
    fstat(fd, &st);
    p = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);

For a full forward- and backward-compatible example, see:
    ./test/test-example.c
It contains a _very_ small API that retrieves font-information efficiently from
by mmap()ing the font file.


Binary Format
-------------

The mmap-unifont.bin file provides all glyphs plus metadata in a simple
binary-format, easily accessible from C programs. See ./test/test-glyphs.c for
an example how to render arbitrary glyphs.

The font-file has the following structure:
    +--------------------+
    |     HEADER SIZE    |  4 bytes
    +--------------------+
    |       HEADER       |  n bytes
    ~                    ~
    ~                    ~
    +--------------------+
    |       GLYPHS       |  x bytes
    ~                    ~
    ~                    ~
    +--------------------+

A few global rules exist:
  - all multi-byte integers are in little-endian format
  - no alignment is enforced
  - the format is fully backwards- and forwards-compatible

The first 4 bytes of the file contain a 4-byte unsigned integer which defines
the size of the header-block (excluding the 4 initial bytes of the header-size
field) in bytes.
Following the header-size is the full header. It's length is defined by the
header-size field. No alignment is enforced. If new header-fields are added, the
header-size is simply increased. You're therefore supposed to skip the full
header including any unknown fields to access the glyphs.

After the header, an array of glyphs is appended. All glyphs occupy the same
number of bytes. This allows direct access to any glyph in the array.

  Header
  ------

    The header can have any size, it may be empty or it may be bigger than
    required. Its size can be inquired by reading the preceding header-size
    field.
    The header consists of a list of fields in a well-defined order. If the
    header-size is too small to contain a specific field, the caller has to
    assume it's set to the default value (as specified below). For instance, if
    the header has size 3, it's too small to contain the glyph-header-size
    field, therefore, glyph-header-size is 1. But it's also too small to contain
    any following field (as the field-order is fixed), therefore, all fields get
    the default value.
    If the header-size is 8, both glyph-header-size and glyph-data-size are
    present and can be parsed in that order.

    Currently, the header is defined as:
        +--------------------+
        | GLYPH HEADER SIZE  |  4 bytes
        +--------------------+
        |  GLYPH DATA SIZE   |  4 bytes
        +--------------------+
        |      UNKNOWN       |  x bytes
        ~                    ~
        ~                    ~
        +--------------------+

    Defined fields are:
      glyph-header-size: 4byte unsigned integer which defines the size of the
                         header of each glyph in bytes. Default is 1.
      glyph-data-size: 4byte unsigned integer which defines the size of the
                       data-body of each glyph in bytes. Default is 32.

    No other fields are defined and any following bytes are undefined.


  Glyphs
  ------

    After the header, the file contains an array of glyphs. Each glyph consists
    of a header, followed by the data-body. The size of both fields is specified
    in the font-header. The overall size of a single glyph is the sum of both.
    This size is not restricted by any alignment and the array is packed.

    The array is ordered by Unicode codepoints. Therefore, the n-th entry is the
    glyph for the n-th Unicode codepoint.

    A glyph itself has the following format:
        +--------------------+
        |     GLYPH WIDTH    |  1 byte
        +--------------------+
        ~       PADDING      ~  x bytes (depending on glyph-header-size)
        ~                    ~
        +--------------------+
        |        DATA        |  16*n bytes
        ~                    ~
        ~                    ~
        +--------------------+
        ~       PADDING      ~  x bytes (depending on glyph-data-size)
        ~                    ~
        +--------------------+

    The glyph-width specifies the character-width of the glyph. Default value is
    1, which means, a normal glyph occupies 8x16 pixels. If the width is 'n',
    the glyph will occupy "(n*8)x16" pixels. The height is fixed to 16 lines.

    If the global glyph-data-size parameter is smaller than required for a
    glyph, you are supposed to down-scale the glyph-width until it fits. You may
    also consider the data corrupted and abort.

    The actual data section contains a 1-bit alpha-mask for the glyph. Format is
    packed A1, which means, a single byte contains 8 packed alpha-masks for 8
    horizontal pixels. The left-most pixel is encoded in the MSB, the right-most
    pixel is encoded in the LSB.

    Any following bytes have to be ignored.