GNU Unifont 16.0.02
Pan-Unicode font with complete Unicode Plane 0 coverage and partial coverage of higher planes
hex2otf.c File Reference

hex2otf - Convert GNU Unifont .hex file to OpenType font More...

#include <assert.h>
#include <ctype.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hex2otf.h"
Include dependency graph for hex2otf.c:

Go to the source code of this file.

Data Structures

struct  Buffer
 Generic data structure for a linked list of buffer elements. More...
 
struct  Glyph
 Data structure to hold data for one bitmap glyph. More...
 
struct  Font
 Data structure to hold information for one font. More...
 
struct  Table
 Data structure for an OpenType table. More...
 
struct  TableRecord
 Data structure for data associated with one OpenType table. More...
 
struct  Options
 Data structure to hold options for OpenType font output. More...
 

Macros

#define VERSION   "1.0.1"
 Program version, for "--version" option. More...
 
#define U16MAX   0xffff
 Maximum UTF-16 code point value. More...
 
#define U32MAX   0xffffffff
 Maximum UTF-32 code point value. More...
 
#define PRI_CP   "U+%.4"PRIXFAST32
 Format string to print Unicode code point. More...
 
#define static_assert(a, b)   (assert(a))
 If "a" is true, return string "b". More...
 
#define BX(shift, x)   ((uintmax_t)(!!(x)) << (shift))
 Truncate & shift word. More...
 
#define B0(shift)   BX((shift), 0)
 Clear a given bit in a word. More...
 
#define B1(shift)   BX((shift), 1)
 Set a given bit in a word. More...
 
#define GLYPH_MAX_WIDTH   16
 Maximum glyph width, in pixels. More...
 
#define GLYPH_HEIGHT   16
 Maximum glyph height, in pixels. More...
 
#define GLYPH_MAX_BYTE_COUNT   (GLYPH_HEIGHT * GLYPH_MAX_WIDTH / 8)
 Number of bytes to represent one bitmap glyph as a binary array. More...
 
#define DESCENDER   2
 Count of pixels below baseline. More...
 
#define ASCENDER   (GLYPH_HEIGHT - DESCENDER)
 Count of pixels above baseline. More...
 
#define FUPEM   64
 Font units per em. More...
 
#define MAX_GLYPHS   65536
 An OpenType font has at most 65536 glyphs. More...
 
#define MAX_NAME_IDS   256
 Name IDs 0-255 are used for standard names. More...
 
#define FU(x)   ((x) * FUPEM / GLYPH_HEIGHT)
 Convert pixels to font units. More...
 
#define PW(x)   ((x) / (GLYPH_HEIGHT / 8))
 Convert glyph byte count to pixel width. More...
 
#define defineStore(name, type)
 Temporary define to look up an element in an array of given type. More...
 
#define addByte(shift)
 
#define getRowBit(rows, x, y)   ((rows)[(y)] & x0 >> (x))
 
#define flipRowBit(rows, x, y)   ((rows)[(y)] ^= x0 >> (x))
 
#define stringCount   (sizeof strings / sizeof *strings)
 
#define cacheCFF32(buf, x)   (cacheU8 ((buf), 29), cacheU32 ((buf), (x)))
 

Typedefs

typedef unsigned char byte
 Definition of "byte" type as an unsigned char. More...
 
typedef int_least8_t pixels_t
 This type must be able to represent max(GLYPH_MAX_WIDTH, GLYPH_HEIGHT). More...
 
typedef struct Buffer Buffer
 Generic data structure for a linked list of buffer elements. More...
 
typedef const char * NameStrings[MAX_NAME_IDS]
 Array of OpenType names indexed directly by Name IDs. More...
 
typedef struct Glyph Glyph
 Data structure to hold data for one bitmap glyph. More...
 
typedef struct Font Font
 Data structure to hold information for one font.
 
typedef struct Table Table
 Data structure for an OpenType table. More...
 
typedef struct Options Options
 Data structure to hold options for OpenType font output. More...
 

Enumerations

enum  LocaFormat { LOCA_OFFSET16 = 0 , LOCA_OFFSET32 = 1 }
 Index to Location ("loca") offset information. More...
 
enum  ContourOp { OP_CLOSE , OP_POINT }
 Specify the current contour drawing operation. More...
 
enum  FillSide { FILL_LEFT , FILL_RIGHT }
 Fill to the left side (CFF) or right side (TrueType) of a contour. More...
 

Functions

void fail (const char *reason,...)
 Print an error message on stderr, then exit. More...
 
void initBuffers (size_t count)
 Initialize an array of buffer pointers to all zeroes. More...
 
void cleanBuffers ()
 Free all allocated buffer pointers. More...
 
BuffernewBuffer (size_t initialCapacity)
 Create a new buffer. More...
 
void ensureBuffer (Buffer *buf, size_t needed)
 Ensure that the buffer has at least the specified minimum size. More...
 
void freeBuffer (Buffer *buf)
 Free the memory previously allocated for a buffer. More...
 
 defineStore (storeU8, uint_least8_t)
 
void cacheU8 (Buffer *buf, uint_fast8_t value)
 Append one unsigned byte to the end of a byte array. More...
 
void cacheU16 (Buffer *buf, uint_fast16_t value)
 Append two unsigned bytes to the end of a byte array. More...
 
void cacheU32 (Buffer *buf, uint_fast32_t value)
 Append four unsigned bytes to the end of a byte array. More...
 
void cacheCFFOperand (Buffer *buf, int_fast32_t value)
 Cache charstring number encoding in a CFF buffer. More...
 
void cacheZeros (Buffer *buf, size_t count)
 Append 1 to 4 bytes of zeroes to a buffer, for padding. More...
 
void cacheBytes (Buffer *restrict buf, const void *restrict src, size_t count)
 Append a string of bytes to a buffer. More...
 
void cacheBuffer (Buffer *restrict bufDest, const Buffer *restrict bufSrc)
 Append bytes of a table to a byte buffer. More...
 
void writeBytes (const byte bytes[], size_t count, FILE *file)
 Write an array of bytes to an output file. More...
 
void writeU16 (uint_fast16_t value, FILE *file)
 Write an unsigned 16-bit value to an output file. More...
 
void writeU32 (uint_fast32_t value, FILE *file)
 Write an unsigned 32-bit value to an output file. More...
 
void addTable (Font *font, const char tag[static 4], Buffer *content)
 Add a TrueType or OpenType table to the font. More...
 
void organizeTables (Font *font, bool isCFF)
 Sort tables according to OpenType recommendations. More...
 
int byTableTag (const void *a, const void *b)
 Compare tables by 4-byte unsigned table tag value. More...
 
void writeFont (Font *font, bool isCFF, const char *fileName)
 Write OpenType font to output file. More...
 
bool readCodePoint (uint_fast32_t *codePoint, const char *fileName, FILE *file)
 Read up to 6 hexadecimal digits and a colon from file. More...
 
void readGlyphs (Font *font, const char *fileName)
 Read glyph definitions from a Unifont .hex format file. More...
 
int byCodePoint (const void *a, const void *b)
 Compare two Unicode code points to determine which is greater. More...
 
void positionGlyphs (Font *font, const char *fileName, pixels_t *xMin)
 Position a glyph within a 16-by-16 pixel bounding box. More...
 
void sortGlyphs (Font *font)
 Sort the glyphs in a font by Unicode code point. More...
 
void buildOutline (Buffer *result, const byte bitmap[], const size_t byteCount, const enum FillSide fillSide)
 Build a glyph outline. More...
 
void prepareOffsets (size_t *sizes)
 Prepare 32-bit glyph offsets in a font table. More...
 
BufferprepareStringIndex (const NameStrings names)
 Prepare a font name string index. More...
 
void fillCFF (Font *font, int version, const NameStrings names)
 Add a CFF table to a font. More...
 
void fillTrueType (Font *font, enum LocaFormat *format, uint_fast16_t *maxPoints, uint_fast16_t *maxContours)
 Add a TrueType table to a font. More...
 
void fillBlankOutline (Font *font)
 Create a dummy blank outline in a font table. More...
 
void fillBitmap (Font *font)
 Fill OpenType bitmap data and location tables. More...
 
void fillHeadTable (Font *font, enum LocaFormat locaFormat, pixels_t xMin)
 Fill a "head" font table. More...
 
void fillHheaTable (Font *font, pixels_t xMin)
 Fill a "hhea" font table. More...
 
void fillMaxpTable (Font *font, bool isCFF, uint_fast16_t maxPoints, uint_fast16_t maxContours)
 Fill a "maxp" font table. More...
 
void fillOS2Table (Font *font)
 Fill an "OS/2" font table. More...
 
void fillHmtxTable (Font *font)
 Fill an "hmtx" font table. More...
 
void fillCmapTable (Font *font)
 Fill a "cmap" font table. More...
 
void fillPostTable (Font *font)
 Fill a "post" font table. More...
 
void fillGposTable (Font *font)
 Fill a "GPOS" font table. More...
 
void fillGsubTable (Font *font)
 Fill a "GSUB" font table. More...
 
void cacheStringAsUTF16BE (Buffer *buf, const char *str)
 Cache a string as a big-ending UTF-16 surrogate pair. More...
 
void fillNameTable (Font *font, NameStrings nameStrings)
 Fill a "name" font table. More...
 
void printVersion ()
 Print program version string on stdout. More...
 
void printHelp ()
 Print help message to stdout and then exit. More...
 
const char * matchToken (const char *operand, const char *key, char delimiter)
 Match a command line option with its key for enabling. More...
 
Options parseOptions (char *const argv[const])
 Parse command line options. More...
 
int main (int argc, char *argv[])
 The main function. More...
 

Variables

BufferallBuffers
 Initial allocation of empty array of buffer pointers. More...
 
size_t bufferCount
 Number of buffers in a Buffer * array. More...
 
size_t nextBufferIndex
 Index number to tail element of Buffer * array. More...
 

Detailed Description

hex2otf - Convert GNU Unifont .hex file to OpenType font

This program reads a Unifont .hex format file and a file containing combining mark offset information, and produces an OpenType font file.

Author
何志翔 (He Zhixiang)

Definition in file hex2otf.c.

Macro Definition Documentation

◆ addByte

#define addByte (   shift)
Value:
if (p == end) \
break; \
record->checksum += (uint_fast32_t)*p++ << (shift);

◆ ASCENDER

#define ASCENDER   (GLYPH_HEIGHT - DESCENDER)

Count of pixels above baseline.

Definition at line 79 of file hex2otf.c.

◆ B0

#define B0 (   shift)    BX((shift), 0)

Clear a given bit in a word.

Definition at line 66 of file hex2otf.c.

◆ B1

#define B1 (   shift)    BX((shift), 1)

Set a given bit in a word.

Definition at line 67 of file hex2otf.c.

◆ BX

#define BX (   shift,
 
)    ((uintmax_t)(!!(x)) << (shift))

Truncate & shift word.

Definition at line 65 of file hex2otf.c.

◆ defineStore

#define defineStore (   name,
  type 
)
Value:
void name (Buffer *buf, type value) \
{ \
type *slot = getBufferSlot (buf, sizeof value); \
*slot = value; \
}
Generic data structure for a linked list of buffer elements.
Definition: hex2otf.c:134

Temporary define to look up an element in an array of given type.

This defintion is used to create lookup functions to return a given element in unsigned arrays of size 8, 16, and 32 bytes, and in an array of pixels.

Definition at line 350 of file hex2otf.c.

◆ DESCENDER

#define DESCENDER   2

Count of pixels below baseline.

Definition at line 76 of file hex2otf.c.

◆ FU

#define FU (   x)    ((x) * FUPEM / GLYPH_HEIGHT)

Convert pixels to font units.

Definition at line 91 of file hex2otf.c.

◆ FUPEM

#define FUPEM   64

Font units per em.

Definition at line 82 of file hex2otf.c.

◆ GLYPH_HEIGHT

#define GLYPH_HEIGHT   16

Maximum glyph height, in pixels.

Definition at line 70 of file hex2otf.c.

◆ GLYPH_MAX_BYTE_COUNT

#define GLYPH_MAX_BYTE_COUNT   (GLYPH_HEIGHT * GLYPH_MAX_WIDTH / 8)

Number of bytes to represent one bitmap glyph as a binary array.

Definition at line 73 of file hex2otf.c.

◆ GLYPH_MAX_WIDTH

#define GLYPH_MAX_WIDTH   16

Maximum glyph width, in pixels.

Definition at line 69 of file hex2otf.c.

◆ MAX_GLYPHS

#define MAX_GLYPHS   65536

An OpenType font has at most 65536 glyphs.

Definition at line 85 of file hex2otf.c.

◆ MAX_NAME_IDS

#define MAX_NAME_IDS   256

Name IDs 0-255 are used for standard names.

Definition at line 88 of file hex2otf.c.

◆ PRI_CP

#define PRI_CP   "U+%.4"PRIXFAST32

Format string to print Unicode code point.

Definition at line 58 of file hex2otf.c.

◆ PW

#define PW (   x)    ((x) / (GLYPH_HEIGHT / 8))

Convert glyph byte count to pixel width.

Definition at line 94 of file hex2otf.c.

◆ static_assert

#define static_assert (   a,
 
)    (assert(a))

If "a" is true, return string "b".

Definition at line 61 of file hex2otf.c.

◆ U16MAX

#define U16MAX   0xffff

Maximum UTF-16 code point value.

Definition at line 55 of file hex2otf.c.

◆ U32MAX

#define U32MAX   0xffffffff

Maximum UTF-32 code point value.

Definition at line 56 of file hex2otf.c.

◆ VERSION

#define VERSION   "1.0.1"

Program version, for "--version" option.

Definition at line 51 of file hex2otf.c.

Typedef Documentation

◆ Buffer

typedef struct Buffer Buffer

Generic data structure for a linked list of buffer elements.

A buffer can act as a vector (when filled with 'store*' functions), or a temporary output area (when filled with 'cache*' functions). The 'store*' functions use native endian. The 'cache*' functions use big endian or other formats in OpenType. Beware of memory alignment.

◆ byte

typedef unsigned char byte

Definition of "byte" type as an unsigned char.

Definition at line 97 of file hex2otf.c.

◆ Glyph

typedef struct Glyph Glyph

Data structure to hold data for one bitmap glyph.

This data structure holds data to represent one Unifont bitmap glyph: Unicode code point, number of bytes in its bitmap array, whether or not it is a combining character, and an offset from the glyph origin to the start of the bitmap.

◆ NameStrings

typedef const char* NameStrings[MAX_NAME_IDS]

Array of OpenType names indexed directly by Name IDs.

Definition at line 604 of file hex2otf.c.

◆ Options

typedef struct Options Options

Data structure to hold options for OpenType font output.

This data structure holds the status of options that can be specified as command line arguments for creating the output OpenType font file.

◆ pixels_t

typedef int_least8_t pixels_t

This type must be able to represent max(GLYPH_MAX_WIDTH, GLYPH_HEIGHT).

Definition at line 100 of file hex2otf.c.

◆ Table

typedef struct Table Table

Data structure for an OpenType table.

This data structure contains a table tag and a pointer to the start of the buffer that holds data for this OpenType table.

For information on the OpenType tables and their structure, see https://docs.microsoft.com/en-us/typography/opentype/spec/otff#font-tables.

Enumeration Type Documentation

◆ ContourOp

enum ContourOp

Specify the current contour drawing operation.

Enumerator
OP_CLOSE 

Close the current contour path that was being drawn.

OP_POINT 

Add one more (x,y) point to the contor being drawn.

Definition at line 1136 of file hex2otf.c.

1136 {
1137 OP_CLOSE, ///< Close the current contour path that was being drawn.
1138 OP_POINT ///< Add one more (x,y) point to the contor being drawn.
1139};
@ OP_POINT
Add one more (x,y) point to the contor being drawn.
Definition: hex2otf.c:1138
@ OP_CLOSE
Close the current contour path that was being drawn.
Definition: hex2otf.c:1137

◆ FillSide

enum FillSide

Fill to the left side (CFF) or right side (TrueType) of a contour.

Enumerator
FILL_LEFT 

Draw outline counter-clockwise (CFF, PostScript).

FILL_RIGHT 

Draw outline clockwise (TrueType).

Definition at line 1144 of file hex2otf.c.

1144 {
1145 FILL_LEFT, ///< Draw outline counter-clockwise (CFF, PostScript).
1146 FILL_RIGHT ///< Draw outline clockwise (TrueType).
1147};
@ FILL_RIGHT
Draw outline clockwise (TrueType).
Definition: hex2otf.c:1146
@ FILL_LEFT
Draw outline counter-clockwise (CFF, PostScript).
Definition: hex2otf.c:1145

◆ LocaFormat

enum LocaFormat

Index to Location ("loca") offset information.

This enumerated type encodes the type of offset to locations in a table. It denotes Offset16 (16-bit) and Offset32 (32-bit) offset types.

Enumerator
LOCA_OFFSET16 

Offset to location is a 16-bit Offset16 value.

LOCA_OFFSET32 

Offset to location is a 32-bit Offset32 value.

Definition at line 658 of file hex2otf.c.

658 {
659 LOCA_OFFSET16 = 0, ///< Offset to location is a 16-bit Offset16 value
660 LOCA_OFFSET32 = 1 ///< Offset to location is a 32-bit Offset32 value
661};
@ LOCA_OFFSET16
Offset to location is a 16-bit Offset16 value.
Definition: hex2otf.c:659
@ LOCA_OFFSET32
Offset to location is a 32-bit Offset32 value.
Definition: hex2otf.c:660

Function Documentation

◆ addTable()

void addTable ( Font font,
const char  tag[static 4],
Buffer content 
)

Add a TrueType or OpenType table to the font.

This function adds a TrueType or OpenType table to a font. The 4-byte table tag is passed as an unsigned 32-bit integer in big-endian format.

Parameters
[in,out]fontThe font to which a font table will be added.
[in]tagThe 4-byte table name.
[in]contentThe table bytes to add, of type Buffer *.

Definition at line 694 of file hex2otf.c.

695{
696 Table *table = getBufferSlot (font->tables, sizeof (Table));
697 table->tag = tagAsU32 (tag);
698 table->content = content;
699}
Data structure for an OpenType table.
Definition: hex2otf.c:646
Here is the caller graph for this function:

◆ buildOutline()

void buildOutline ( Buffer result,
const byte  bitmap[],
const size_t  byteCount,
const enum FillSide  fillSide 
)

Build a glyph outline.

This function builds a glyph outline from a Unifont glyph bitmap.

Parameters
[out]resultThe resulting glyph outline.
[in]bitmapA bitmap array.
[in]byteCountthe number of bytes in the input bitmap array.
[in]fillSideEnumerated indicator to fill left or right side.

Get the value of a given bit that is in a given row.

Invert the value of a given bit that is in a given row.

Definition at line 1160 of file hex2otf.c.

1162{
1163 enum Direction {RIGHT, LEFT, DOWN, UP}; // order is significant
1164
1165 // respective coordinate deltas
1166 const pixels_t dx[] = {1, -1, 0, 0}, dy[] = {0, 0, -1, 1};
1167
1168 assert (byteCount % GLYPH_HEIGHT == 0);
1169 const uint_fast8_t bytesPerRow = byteCount / GLYPH_HEIGHT;
1170 const pixels_t glyphWidth = bytesPerRow * 8;
1171 assert (glyphWidth <= GLYPH_MAX_WIDTH);
1172
1173 #if GLYPH_MAX_WIDTH < 32
1174 typedef uint_fast32_t row_t;
1175 #elif GLYPH_MAX_WIDTH < 64
1176 typedef uint_fast64_t row_t;
1177 #else
1178 #error GLYPH_MAX_WIDTH is too large.
1179 #endif
1180
1181 row_t pixels[GLYPH_HEIGHT + 2] = {0};
1182 for (pixels_t row = GLYPH_HEIGHT; row > 0; row--)
1183 for (pixels_t b = 0; b < bytesPerRow; b++)
1184 pixels[row] = pixels[row] << 8 | *bitmap++;
1185 typedef row_t graph_t[GLYPH_HEIGHT + 1];
1186 graph_t vectors[4];
1187 const row_t *lower = pixels, *upper = pixels + 1;
1188 for (pixels_t row = 0; row <= GLYPH_HEIGHT; row++)
1189 {
1190 const row_t m = (fillSide == FILL_RIGHT) - 1;
1191 vectors[RIGHT][row] = (m ^ (*lower << 1)) & (~m ^ (*upper << 1));
1192 vectors[LEFT ][row] = (m ^ (*upper )) & (~m ^ (*lower ));
1193 vectors[DOWN ][row] = (m ^ (*lower )) & (~m ^ (*lower << 1));
1194 vectors[UP ][row] = (m ^ (*upper << 1)) & (~m ^ (*upper ));
1195 lower++;
1196 upper++;
1197 }
1198 graph_t selection = {0};
1199 const row_t x0 = (row_t)1 << glyphWidth;
1200
1201 /// Get the value of a given bit that is in a given row.
1202 #define getRowBit(rows, x, y) ((rows)[(y)] & x0 >> (x))
1203
1204 /// Invert the value of a given bit that is in a given row.
1205 #define flipRowBit(rows, x, y) ((rows)[(y)] ^= x0 >> (x))
1206
1207 for (pixels_t y = GLYPH_HEIGHT; y >= 0; y--)
1208 {
1209 for (pixels_t x = 0; x <= glyphWidth; x++)
1210 {
1211 assert (!getRowBit (vectors[LEFT], x, y));
1212 assert (!getRowBit (vectors[UP], x, y));
1213 enum Direction initial;
1214
1215 if (getRowBit (vectors[RIGHT], x, y))
1216 initial = RIGHT;
1217 else if (getRowBit (vectors[DOWN], x, y))
1218 initial = DOWN;
1219 else
1220 continue;
1221
1222 static_assert ((GLYPH_MAX_WIDTH + 1) * (GLYPH_HEIGHT + 1) * 2 <=
1223 U16MAX, "potential overflow");
1224
1225 uint_fast16_t lastPointCount = 0;
1226 for (bool converged = false;;)
1227 {
1228 uint_fast16_t pointCount = 0;
1229 enum Direction heading = initial;
1230 for (pixels_t tx = x, ty = y;;)
1231 {
1232 if (converged)
1233 {
1234 storePixels (result, OP_POINT);
1235 storePixels (result, tx);
1236 storePixels (result, ty);
1237 }
1238 do
1239 {
1240 if (converged)
1241 flipRowBit (vectors[heading], tx, ty);
1242 tx += dx[heading];
1243 ty += dy[heading];
1244 } while (getRowBit (vectors[heading], tx, ty));
1245 if (tx == x && ty == y)
1246 break;
1247 static_assert ((UP ^ DOWN) == 1 && (LEFT ^ RIGHT) == 1,
1248 "wrong enums");
1249 heading = (heading & 2) ^ 2;
1250 heading |= !!getRowBit (selection, tx, ty);
1251 heading ^= !getRowBit (vectors[heading], tx, ty);
1252 assert (getRowBit (vectors[heading], tx, ty));
1253 flipRowBit (selection, tx, ty);
1254 pointCount++;
1255 }
1256 if (converged)
1257 break;
1258 converged = pointCount == lastPointCount;
1259 lastPointCount = pointCount;
1260 }
1261
1262 storePixels (result, OP_CLOSE);
1263 }
1264 }
1265 #undef getRowBit
1266 #undef flipRowBit
1267}
#define U16MAX
Maximum UTF-16 code point value.
Definition: hex2otf.c:55
#define GLYPH_MAX_WIDTH
Maximum glyph width, in pixels.
Definition: hex2otf.c:69
#define GLYPH_HEIGHT
Maximum glyph height, in pixels.
Definition: hex2otf.c:70
int_least8_t pixels_t
This type must be able to represent max(GLYPH_MAX_WIDTH, GLYPH_HEIGHT).
Definition: hex2otf.c:100

◆ byCodePoint()

int byCodePoint ( const void *  a,
const void *  b 
)

Compare two Unicode code points to determine which is greater.

This function compares the Unicode code points contained within two Glyph data structures. The function returns 1 if the first code point is greater, and -1 if the second is greater.

Parameters
[in]aA Glyph data structure containing the first code point.
[in]bA Glyph data structure containing the second code point.
Returns
1 if the code point a is greater, -1 if less, 0 if equal.

Definition at line 1040 of file hex2otf.c.

1041{
1042 const Glyph *const ga = a, *const gb = b;
1043 int gt = ga->codePoint > gb->codePoint;
1044 int lt = ga->codePoint < gb->codePoint;
1045 return gt - lt;
1046}
Data structure to hold data for one bitmap glyph.
Definition: hex2otf.c:615
uint_least32_t codePoint
undefined for glyph 0
Definition: hex2otf.c:616

◆ byTableTag()

int byTableTag ( const void *  a,
const void *  b 
)

Compare tables by 4-byte unsigned table tag value.

This function takes two pointers to a TableRecord data structure and extracts the four-byte tag structure element for each. The two 32-bit numbers are then compared. If the first tag is greater than the first, then gt = 1 and lt = 0, and so 1 - 0 = 1 is returned. If the first is less than the second, then gt = 0 and lt = 1, and so 0 - 1 = -1 is returned.

Parameters
[in]aPointer to the first TableRecord structure.
[in]bPointer to the second TableRecord structure.
Returns
1 if the tag in "a" is greater, -1 if less, 0 if equal.

Definition at line 767 of file hex2otf.c.

768{
769 const struct TableRecord *const ra = a, *const rb = b;
770 int gt = ra->tag > rb->tag;
771 int lt = ra->tag < rb->tag;
772 return gt - lt;
773}
Data structure for data associated with one OpenType table.
Definition: hex2otf.c:748

◆ cacheBuffer()

void cacheBuffer ( Buffer *restrict  bufDest,
const Buffer *restrict  bufSrc 
)

Append bytes of a table to a byte buffer.

Parameters
[in,out]bufDestThe buffer to which the new bytes are appended.
[in]bufSrcThe bytes to append to the buffer array.

Definition at line 523 of file hex2otf.c.

524{
525 size_t length = countBufferedBytes (bufSrc);
526 ensureBuffer (bufDest, length);
527 memcpy (bufDest->next, bufSrc->begin, length);
528 bufDest->next += length;
529}
void ensureBuffer(Buffer *buf, size_t needed)
Ensure that the buffer has at least the specified minimum size.
Definition: hex2otf.c:239

◆ cacheBytes()

void cacheBytes ( Buffer *restrict  buf,
const void *restrict  src,
size_t  count 
)

Append a string of bytes to a buffer.

This function appends an array of 1 to 4 bytes to the end of a buffer.

Parameters
[in,out]bufThe buffer to which the bytes are appended.
[in]srcThe array of bytes to append to the buffer.
[in]countThe number of bytes containing zeroes to append.

Definition at line 509 of file hex2otf.c.

510{
511 ensureBuffer (buf, count);
512 memcpy (buf->next, src, count);
513 buf->next += count;
514}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cacheCFFOperand()

void cacheCFFOperand ( Buffer buf,
int_fast32_t  value 
)

Cache charstring number encoding in a CFF buffer.

This function caches two's complement 8-, 16-, and 32-bit words as per Adobe's Type 2 Charstring encoding for operands. These operands are used in Compact Font Format data structures.

Byte values can have offsets, for which this function compensates, optionally followed by additional bytes:

Byte Range   Offset   Bytes   Adjusted Range
----------   ------   -----   --------------
  0 to 11        0      1     0 to 11 (operators)
    12           0      2     Next byte is 8-bit op code
 13 to 18        0      1     13 to 18 (operators)
 19 to 20        0      2+    hintmask and cntrmask operators
 21 to 27        0      1     21 to 27 (operators)
    28           0      3     16-bit 2's complement number
 29 to 31        0      1     29 to 31 (operators)
 32 to 246    -139      1     -107 to +107
247 to 250    +108      2     +108 to +1131
251 to 254    -108      2     -108 to -1131
   255           0      5     16-bit integer and 16-bit fraction
Parameters
[in,out]bufThe buffer to which the operand value is appended.
[in]valueThe operand value.

Definition at line 460 of file hex2otf.c.

461{
462 if (-107 <= value && value <= 107)
463 cacheU8 (buf, value + 139);
464 else if (108 <= value && value <= 1131)
465 {
466 cacheU8 (buf, (value - 108) / 256 + 247);
467 cacheU8 (buf, (value - 108) % 256);
468 }
469 else if (-32768 <= value && value <= 32767)
470 {
471 cacheU8 (buf, 28);
472 cacheU16 (buf, value);
473 }
474 else if (-2147483647 <= value && value <= 2147483647)
475 {
476 cacheU8 (buf, 29);
477 cacheU32 (buf, value);
478 }
479 else
480 assert (false); // other encodings are not used and omitted
481 static_assert (GLYPH_MAX_WIDTH <= 107, "More encodings are needed.");
482}
void cacheU32(Buffer *buf, uint_fast32_t value)
Append four unsigned bytes to the end of a byte array.
Definition: hex2otf.c:427
void cacheU16(Buffer *buf, uint_fast16_t value)
Append two unsigned bytes to the end of a byte array.
Definition: hex2otf.c:412
void cacheU8(Buffer *buf, uint_fast8_t value)
Append one unsigned byte to the end of a byte array.
Definition: hex2otf.c:397
Here is the call graph for this function:

◆ cacheStringAsUTF16BE()

void cacheStringAsUTF16BE ( Buffer buf,
const char *  str 
)

Cache a string as a big-ending UTF-16 surrogate pair.

This function encodes a UTF-8 string as a big-endian UTF-16 surrogate pair.

Parameters
[in,out]bufPointer to a Buffer struct to update.
[in]strThe character array to encode.

Definition at line 2316 of file hex2otf.c.

2317{
2318 for (const char *p = str; *p; p++)
2319 {
2320 byte c = *p;
2321 if (c < 0x80)
2322 {
2323 cacheU16 (buf, c);
2324 continue;
2325 }
2326 int length = 1;
2327 byte mask = 0x40;
2328 for (; c & mask; mask >>= 1)
2329 length++;
2330 if (length == 1 || length > 4)
2331 fail ("Ill-formed UTF-8 sequence.");
2332 uint_fast32_t codePoint = c & (mask - 1);
2333 for (int i = 1; i < length; i++)
2334 {
2335 c = *++p;
2336 if ((c & 0xc0) != 0x80) // NUL checked here
2337 fail ("Ill-formed UTF-8 sequence.");
2338 codePoint = (codePoint << 6) | (c & 0x3f);
2339 }
2340 const int lowerBits = length==2 ? 7 : length==3 ? 11 : 16;
2341 if (codePoint >> lowerBits == 0)
2342 fail ("Ill-formed UTF-8 sequence."); // sequence should be shorter
2343 if (codePoint >= 0xd800 && codePoint <= 0xdfff)
2344 fail ("Ill-formed UTF-8 sequence.");
2345 if (codePoint > 0x10ffff)
2346 fail ("Ill-formed UTF-8 sequence.");
2347 if (codePoint > 0xffff)
2348 {
2349 cacheU16 (buf, 0xd800 | (codePoint - 0x10000) >> 10);
2350 cacheU16 (buf, 0xdc00 | (codePoint & 0x3ff));
2351 }
2352 else
2353 cacheU16 (buf, codePoint);
2354 }
2355}
void fail(const char *reason,...)
Print an error message on stderr, then exit.
Definition: hex2otf.c:113
Here is the call graph for this function:

◆ cacheU16()

void cacheU16 ( Buffer buf,
uint_fast16_t  value 
)

Append two unsigned bytes to the end of a byte array.

This function adds two bytes to the end of a byte array. The buffer is updated to account for the newly-added bytes.

Parameters
[in,out]bufThe array of bytes to which to append two new bytes.
[in]valueThe 16-bit unsigned value to append to the buf array.

Definition at line 412 of file hex2otf.c.

413{
414 cacheU (buf, value, 2);
415}
Here is the caller graph for this function:

◆ cacheU32()

void cacheU32 ( Buffer buf,
uint_fast32_t  value 
)

Append four unsigned bytes to the end of a byte array.

This function adds four bytes to the end of a byte array. The buffer is updated to account for the newly-added bytes.

Parameters
[in,out]bufThe array of bytes to which to append four new bytes.
[in]valueThe 32-bit unsigned value to append to the buf array.

Definition at line 427 of file hex2otf.c.

428{
429 cacheU (buf, value, 4);
430}
Here is the caller graph for this function:

◆ cacheU8()

void cacheU8 ( Buffer buf,
uint_fast8_t  value 
)

Append one unsigned byte to the end of a byte array.

This function adds one byte to the end of a byte array. The buffer is updated to account for the newly-added byte.

Parameters
[in,out]bufThe array of bytes to which to append a new byte.
[in]valueThe 8-bit unsigned value to append to the buf array.

Definition at line 397 of file hex2otf.c.

398{
399 storeU8 (buf, value & 0xff);
400}
Here is the caller graph for this function:

◆ cacheZeros()

void cacheZeros ( Buffer buf,
size_t  count 
)

Append 1 to 4 bytes of zeroes to a buffer, for padding.

Parameters
[in,out]bufThe buffer to which the operand value is appended.
[in]countThe number of bytes containing zeroes to append.

Definition at line 491 of file hex2otf.c.

492{
493 ensureBuffer (buf, count);
494 memset (buf->next, 0, count);
495 buf->next += count;
496}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cleanBuffers()

void cleanBuffers ( )

Free all allocated buffer pointers.

This function frees all buffer pointers previously allocated in the initBuffers function.

Definition at line 170 of file hex2otf.c.

171{
172 for (size_t i = 0; i < bufferCount; i++)
173 if (allBuffers[i].capacity)
174 free (allBuffers[i].begin);
175 free (allBuffers);
176 bufferCount = 0;
177}
Buffer * allBuffers
Initial allocation of empty array of buffer pointers.
Definition: hex2otf.c:139
size_t bufferCount
Number of buffers in a Buffer * array.
Definition: hex2otf.c:140
Here is the caller graph for this function:

◆ defineStore()

defineStore ( storeU8  ,
uint_least8_t   
)

Definition at line 356 of file hex2otf.c.

375{
376 assert (1 <= bytes && bytes <= 4);
377 ensureBuffer (buf, bytes);
378 switch (bytes)
379 {
380 case 4: *buf->next++ = value >> 24 & 0xff; // fall through
381 case 3: *buf->next++ = value >> 16 & 0xff; // fall through
382 case 2: *buf->next++ = value >> 8 & 0xff; // fall through
383 case 1: *buf->next++ = value & 0xff;
384 }
385}

◆ ensureBuffer()

void ensureBuffer ( Buffer buf,
size_t  needed 
)

Ensure that the buffer has at least the specified minimum size.

This function takes a buffer array of type Buffer and the necessary minimum number of elements as inputs, and attempts to increase the size of the buffer if it must be larger.

If the buffer is too small and cannot be resized, the program will terminate with an error message and an exit status of EXIT_FAILURE.

Parameters
[in,out]bufThe buffer to check.
[in]neededThe required minimum number of elements in the buffer.

Definition at line 239 of file hex2otf.c.

240{
241 if (buf->end - buf->next >= needed)
242 return;
243 ptrdiff_t occupied = buf->next - buf->begin;
244 size_t required = occupied + needed;
245 if (required < needed) // overflow
246 fail ("Cannot allocate %zu + %zu bytes of memory.", occupied, needed);
247 if (required > SIZE_MAX / 2)
248 buf->capacity = required;
249 else while (buf->capacity < required)
250 buf->capacity *= 2;
251 void *extended = realloc (buf->begin, buf->capacity);
252 if (!extended)
253 fail ("Failed to allocate %zu bytes of memory.", buf->capacity);
254 buf->begin = extended;
255 buf->next = buf->begin + occupied;
256 buf->end = buf->begin + buf->capacity;
257}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fail()

void fail ( const char *  reason,
  ... 
)

Print an error message on stderr, then exit.

This function prints the provided error string and optional following arguments to stderr, and then exits with a status of EXIT_FAILURE.

Parameters
[in]reasonThe output string to describe the error.
[in]...Optional following arguments to output.

Definition at line 113 of file hex2otf.c.

114{
115 fputs ("ERROR: ", stderr);
116 va_list args;
117 va_start (args, reason);
118 vfprintf (stderr, reason, args);
119 va_end (args);
120 putc ('\n', stderr);
121 exit (EXIT_FAILURE);
122}
Here is the caller graph for this function:

◆ fillBitmap()

void fillBitmap ( Font font)

Fill OpenType bitmap data and location tables.

This function fills an Embedded Bitmap Data (EBDT) Table and an Embedded Bitmap Location (EBLC) Table with glyph bitmap information. These tables enable embedding bitmaps in OpenType fonts. No Embedded Bitmap Scaling (EBSC) table is used for the bitmap glyphs, only EBDT and EBLC.

Parameters
[in,out]fontPointer to a Font struct in which to add bitmaps.

Definition at line 1728 of file hex2otf.c.

1729{
1730 const Glyph *const glyphs = getBufferHead (font->glyphs);
1731 const Glyph *const glyphsEnd = getBufferTail (font->glyphs);
1732 size_t bitmapsSize = 0;
1733 for (const Glyph *glyph = glyphs; glyph < glyphsEnd; glyph++)
1734 bitmapsSize += glyph->byteCount;
1735 Buffer *ebdt = newBuffer (4 + bitmapsSize);
1736 addTable (font, "EBDT", ebdt);
1737 cacheU16 (ebdt, 2); // majorVersion
1738 cacheU16 (ebdt, 0); // minorVersion
1739 uint_fast8_t byteCount = 0; // unequal to any glyph
1740 pixels_t pos = 0;
1741 bool combining = false;
1742 Buffer *rangeHeads = newBuffer (32);
1743 Buffer *offsets = newBuffer (64);
1744 for (const Glyph *glyph = glyphs; glyph < glyphsEnd; glyph++)
1745 {
1746 if (glyph->byteCount != byteCount || glyph->pos != pos ||
1747 glyph->combining != combining)
1748 {
1749 storeU16 (rangeHeads, glyph - glyphs);
1750 storeU32 (offsets, countBufferedBytes (ebdt));
1751 byteCount = glyph->byteCount;
1752 pos = glyph->pos;
1753 combining = glyph->combining;
1754 }
1755 cacheBytes (ebdt, glyph->bitmap, byteCount);
1756 }
1757 const uint_least16_t *ranges = getBufferHead (rangeHeads);
1758 const uint_least16_t *rangesEnd = getBufferTail (rangeHeads);
1759 uint_fast32_t rangeCount = rangesEnd - ranges;
1760 storeU16 (rangeHeads, font->glyphCount);
1761 Buffer *eblc = newBuffer (4096);
1762 addTable (font, "EBLC", eblc);
1763 cacheU16 (eblc, 2); // majorVersion
1764 cacheU16 (eblc, 0); // minorVersion
1765 cacheU32 (eblc, 1); // numSizes
1766 { // bitmapSizes[0]
1767 cacheU32 (eblc, 56); // indexSubTableArrayOffset
1768 cacheU32 (eblc, (8 + 20) * rangeCount); // indexTablesSize
1769 cacheU32 (eblc, rangeCount); // numberOfIndexSubTables
1770 cacheU32 (eblc, 0); // colorRef
1771 { // hori
1772 cacheU8 (eblc, ASCENDER); // ascender
1773 cacheU8 (eblc, -DESCENDER); // descender
1774 cacheU8 (eblc, font->maxWidth); // widthMax
1775 cacheU8 (eblc, 1); // caretSlopeNumerator
1776 cacheU8 (eblc, 0); // caretSlopeDenominator
1777 cacheU8 (eblc, 0); // caretOffset
1778 cacheU8 (eblc, 0); // minOriginSB
1779 cacheU8 (eblc, 0); // minAdvanceSB
1780 cacheU8 (eblc, ASCENDER); // maxBeforeBL
1781 cacheU8 (eblc, -DESCENDER); // minAfterBL
1782 cacheU8 (eblc, 0); // pad1
1783 cacheU8 (eblc, 0); // pad2
1784 }
1785 { // vert
1786 cacheU8 (eblc, ASCENDER); // ascender
1787 cacheU8 (eblc, -DESCENDER); // descender
1788 cacheU8 (eblc, font->maxWidth); // widthMax
1789 cacheU8 (eblc, 1); // caretSlopeNumerator
1790 cacheU8 (eblc, 0); // caretSlopeDenominator
1791 cacheU8 (eblc, 0); // caretOffset
1792 cacheU8 (eblc, 0); // minOriginSB
1793 cacheU8 (eblc, 0); // minAdvanceSB
1794 cacheU8 (eblc, ASCENDER); // maxBeforeBL
1795 cacheU8 (eblc, -DESCENDER); // minAfterBL
1796 cacheU8 (eblc, 0); // pad1
1797 cacheU8 (eblc, 0); // pad2
1798 }
1799 cacheU16 (eblc, 0); // startGlyphIndex
1800 cacheU16 (eblc, font->glyphCount - 1); // endGlyphIndex
1801 cacheU8 (eblc, 16); // ppemX
1802 cacheU8 (eblc, 16); // ppemY
1803 cacheU8 (eblc, 1); // bitDepth
1804 cacheU8 (eblc, 1); // flags = Horizontal
1805 }
1806 { // IndexSubTableArray
1807 uint_fast32_t offset = rangeCount * 8;
1808 for (const uint_least16_t *p = ranges; p < rangesEnd; p++)
1809 {
1810 cacheU16 (eblc, *p); // firstGlyphIndex
1811 cacheU16 (eblc, p[1] - 1); // lastGlyphIndex
1812 cacheU32 (eblc, offset); // additionalOffsetToIndexSubtable
1813 offset += 20;
1814 }
1815 }
1816 { // IndexSubTables
1817 const uint_least32_t *offset = getBufferHead (offsets);
1818 for (const uint_least16_t *p = ranges; p < rangesEnd; p++)
1819 {
1820 const Glyph *glyph = &glyphs[*p];
1821 cacheU16 (eblc, 2); // indexFormat
1822 cacheU16 (eblc, 5); // imageFormat
1823 cacheU32 (eblc, *offset++); // imageDataOffset
1824 cacheU32 (eblc, glyph->byteCount); // imageSize
1825 { // bigMetrics
1826 cacheU8 (eblc, GLYPH_HEIGHT); // height
1827 const uint_fast8_t width = PW (glyph->byteCount);
1828 cacheU8 (eblc, width); // width
1829 cacheU8 (eblc, glyph->pos); // horiBearingX
1830 cacheU8 (eblc, ASCENDER); // horiBearingY
1831 cacheU8 (eblc, glyph->combining ? 0 : width); // horiAdvance
1832 cacheU8 (eblc, 0); // vertBearingX
1833 cacheU8 (eblc, 0); // vertBearingY
1834 cacheU8 (eblc, GLYPH_HEIGHT); // vertAdvance
1835 }
1836 }
1837 }
1838 freeBuffer (rangeHeads);
1839 freeBuffer (offsets);
1840}
void addTable(Font *font, const char tag[static 4], Buffer *content)
Add a TrueType or OpenType table to the font.
Definition: hex2otf.c:694
#define PW(x)
Convert glyph byte count to pixel width.
Definition: hex2otf.c:94
#define DESCENDER
Count of pixels below baseline.
Definition: hex2otf.c:76
void cacheBytes(Buffer *restrict buf, const void *restrict src, size_t count)
Append a string of bytes to a buffer.
Definition: hex2otf.c:509
void freeBuffer(Buffer *buf)
Free the memory previously allocated for a buffer.
Definition: hex2otf.c:337
#define ASCENDER
Count of pixels above baseline.
Definition: hex2otf.c:79
Buffer * newBuffer(size_t initialCapacity)
Create a new buffer.
Definition: hex2otf.c:188
uint_least8_t byteCount
length of bitmap data
Definition: hex2otf.c:618
pixels_t pos
Definition: hex2otf.c:620
bool combining
whether this is a combining glyph
Definition: hex2otf.c:619
Here is the caller graph for this function:

◆ fillBlankOutline()

void fillBlankOutline ( Font font)

Create a dummy blank outline in a font table.

Parameters
[in,out]fontPointer to a Font struct to insert a blank outline.

Definition at line 1697 of file hex2otf.c.

1698{
1699 Buffer *glyf = newBuffer (12);
1700 addTable (font, "glyf", glyf);
1701 // Empty table is not allowed, but an empty outline for glyph 0 suffices.
1702 cacheU16 (glyf, 0); // numberOfContours
1703 cacheU16 (glyf, FU (0)); // xMin
1704 cacheU16 (glyf, FU (0)); // yMin
1705 cacheU16 (glyf, FU (0)); // xMax
1706 cacheU16 (glyf, FU (0)); // yMax
1707 cacheU16 (glyf, 0); // instructionLength
1708 Buffer *loca = newBuffer (2 * (font->glyphCount + 1));
1709 addTable (font, "loca", loca);
1710 cacheU16 (loca, 0); // offsets[0]
1711 assert (countBufferedBytes (glyf) % 2 == 0);
1712 for (uint_fast32_t i = 1; i <= font->glyphCount; i++)
1713 cacheU16 (loca, countBufferedBytes (glyf) / 2); // offsets[i]
1714}
#define FU(x)
Convert pixels to font units.
Definition: hex2otf.c:91
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fillCFF()

void fillCFF ( Font font,
int  version,
const NameStrings  names 
)

Add a CFF table to a font.

Parameters
[in,out]fontPointer to a Font struct to contain the CFF table.
[in]versionVersion of CFF table, with value 1 or 2.
[in]namesList of NameStrings.

Use fixed width integer for variables to simplify offset calculation.

Definition at line 1329 of file hex2otf.c.

1330{
1331 // HACK: For convenience, CFF data structures are hard coded.
1332 assert (0 < version && version <= 2);
1333 Buffer *cff = newBuffer (65536);
1334 addTable (font, version == 1 ? "CFF " : "CFF2", cff);
1335
1336 /// Use fixed width integer for variables to simplify offset calculation.
1337 #define cacheCFF32(buf, x) (cacheU8 ((buf), 29), cacheU32 ((buf), (x)))
1338
1339 // In Unifont, 16px glyphs are more common. This is used by CFF1 only.
1340 const pixels_t defaultWidth = 16, nominalWidth = 8;
1341 if (version == 1)
1342 {
1343 Buffer *strings = prepareStringIndex (names);
1344 size_t stringsSize = countBufferedBytes (strings);
1345 const char *cffName = names[6];
1346 assert (cffName);
1347 size_t nameLength = strlen (cffName);
1348 size_t namesSize = nameLength + 5;
1349 // These sizes must be updated together with the data below.
1350 size_t offsets[] = {4, namesSize, 45, stringsSize, 2, 5, 8, 32, 4, 0};
1351 prepareOffsets (offsets);
1352 { // Header
1353 cacheU8 (cff, 1); // major
1354 cacheU8 (cff, 0); // minor
1355 cacheU8 (cff, 4); // hdrSize
1356 cacheU8 (cff, 1); // offSize
1357 }
1358 assert (countBufferedBytes (cff) == offsets[0]);
1359 { // Name INDEX (should not be used by OpenType readers)
1360 cacheU16 (cff, 1); // count
1361 cacheU8 (cff, 1); // offSize
1362 cacheU8 (cff, 1); // offset[0]
1363 if (nameLength + 1 > 255) // must be too long; spec limit is 63
1364 fail ("PostScript name is too long.");
1365 cacheU8 (cff, nameLength + 1); // offset[1]
1366 cacheBytes (cff, cffName, nameLength);
1367 }
1368 assert (countBufferedBytes (cff) == offsets[1]);
1369 { // Top DICT INDEX
1370 cacheU16 (cff, 1); // count
1371 cacheU8 (cff, 1); // offSize
1372 cacheU8 (cff, 1); // offset[0]
1373 cacheU8 (cff, 41); // offset[1]
1374 cacheCFFOperand (cff, 391); // "Adobe"
1375 cacheCFFOperand (cff, 392); // "Identity"
1376 cacheCFFOperand (cff, 0);
1377 cacheBytes (cff, (byte[]){12, 30}, 2); // ROS
1378 cacheCFF32 (cff, font->glyphCount);
1379 cacheBytes (cff, (byte[]){12, 34}, 2); // CIDCount
1380 cacheCFF32 (cff, offsets[6]);
1381 cacheBytes (cff, (byte[]){12, 36}, 2); // FDArray
1382 cacheCFF32 (cff, offsets[5]);
1383 cacheBytes (cff, (byte[]){12, 37}, 2); // FDSelect
1384 cacheCFF32 (cff, offsets[4]);
1385 cacheU8 (cff, 15); // charset
1386 cacheCFF32 (cff, offsets[8]);
1387 cacheU8 (cff, 17); // CharStrings
1388 }
1389 assert (countBufferedBytes (cff) == offsets[2]);
1390 { // String INDEX
1391 cacheBuffer (cff, strings);
1392 freeBuffer (strings);
1393 }
1394 assert (countBufferedBytes (cff) == offsets[3]);
1395 cacheU16 (cff, 0); // Global Subr INDEX
1396 assert (countBufferedBytes (cff) == offsets[4]);
1397 { // Charsets
1398 cacheU8 (cff, 2); // format
1399 { // Range2[0]
1400 cacheU16 (cff, 1); // first
1401 cacheU16 (cff, font->glyphCount - 2); // nLeft
1402 }
1403 }
1404 assert (countBufferedBytes (cff) == offsets[5]);
1405 { // FDSelect
1406 cacheU8 (cff, 3); // format
1407 cacheU16 (cff, 1); // nRanges
1408 cacheU16 (cff, 0); // first
1409 cacheU8 (cff, 0); // fd
1410 cacheU16 (cff, font->glyphCount); // sentinel
1411 }
1412 assert (countBufferedBytes (cff) == offsets[6]);
1413 { // FDArray
1414 cacheU16 (cff, 1); // count
1415 cacheU8 (cff, 1); // offSize
1416 cacheU8 (cff, 1); // offset[0]
1417 cacheU8 (cff, 28); // offset[1]
1418 cacheCFFOperand (cff, 393);
1419 cacheBytes (cff, (byte[]){12, 38}, 2); // FontName
1420 // Windows requires FontMatrix in Font DICT.
1421 const byte unit[] = {0x1e,0x15,0x62,0x5c,0x6f}; // 1/64 (0.015625)
1422 cacheBytes (cff, unit, sizeof unit);
1423 cacheCFFOperand (cff, 0);
1424 cacheCFFOperand (cff, 0);
1425 cacheBytes (cff, unit, sizeof unit);
1426 cacheCFFOperand (cff, 0);
1427 cacheCFFOperand (cff, 0);
1428 cacheBytes (cff, (byte[]){12, 7}, 2); // FontMatrix
1429 cacheCFFOperand (cff, offsets[8] - offsets[7]); // size
1430 cacheCFF32 (cff, offsets[7]); // offset
1431 cacheU8 (cff, 18); // Private
1432 }
1433 assert (countBufferedBytes (cff) == offsets[7]);
1434 { // Private
1435 cacheCFFOperand (cff, FU (defaultWidth));
1436 cacheU8 (cff, 20); // defaultWidthX
1437 cacheCFFOperand (cff, FU (nominalWidth));
1438 cacheU8 (cff, 21); // nominalWidthX
1439 }
1440 assert (countBufferedBytes (cff) == offsets[8]);
1441 }
1442 else
1443 {
1444 assert (version == 2);
1445 // These sizes must be updated together with the data below.
1446 size_t offsets[] = {5, 21, 4, 10, 0};
1447 prepareOffsets (offsets);
1448 { // Header
1449 cacheU8 (cff, 2); // majorVersion
1450 cacheU8 (cff, 0); // minorVersion
1451 cacheU8 (cff, 5); // headerSize
1452 cacheU16 (cff, offsets[1] - offsets[0]); // topDictLength
1453 }
1454 assert (countBufferedBytes (cff) == offsets[0]);
1455 { // Top DICT
1456 const byte unit[] = {0x1e,0x15,0x62,0x5c,0x6f}; // 1/64 (0.015625)
1457 cacheBytes (cff, unit, sizeof unit);
1458 cacheCFFOperand (cff, 0);
1459 cacheCFFOperand (cff, 0);
1460 cacheBytes (cff, unit, sizeof unit);
1461 cacheCFFOperand (cff, 0);
1462 cacheCFFOperand (cff, 0);
1463 cacheBytes (cff, (byte[]){12, 7}, 2); // FontMatrix
1464 cacheCFFOperand (cff, offsets[2]);
1465 cacheBytes (cff, (byte[]){12, 36}, 2); // FDArray
1466 cacheCFFOperand (cff, offsets[3]);
1467 cacheU8 (cff, 17); // CharStrings
1468 }
1469 assert (countBufferedBytes (cff) == offsets[1]);
1470 cacheU32 (cff, 0); // Global Subr INDEX
1471 assert (countBufferedBytes (cff) == offsets[2]);
1472 { // Font DICT INDEX
1473 cacheU32 (cff, 1); // count
1474 cacheU8 (cff, 1); // offSize
1475 cacheU8 (cff, 1); // offset[0]
1476 cacheU8 (cff, 4); // offset[1]
1477 cacheCFFOperand (cff, 0);
1478 cacheCFFOperand (cff, 0);
1479 cacheU8 (cff, 18); // Private
1480 }
1481 assert (countBufferedBytes (cff) == offsets[3]);
1482 }
1483 { // CharStrings INDEX
1484 Buffer *offsets = newBuffer (4096);
1485 Buffer *charstrings = newBuffer (4096);
1486 Buffer *outline = newBuffer (1024);
1487 const Glyph *glyph = getBufferHead (font->glyphs);
1488 const Glyph *const endGlyph = glyph + font->glyphCount;
1489 for (; glyph < endGlyph; glyph++)
1490 {
1491 // CFF offsets start at 1
1492 storeU32 (offsets, countBufferedBytes (charstrings) + 1);
1493
1494 pixels_t rx = -glyph->pos;
1495 pixels_t ry = DESCENDER;
1496 resetBuffer (outline);
1497 buildOutline (outline, glyph->bitmap, glyph->byteCount, FILL_LEFT);
1498 enum CFFOp {rmoveto=21, hmoveto=22, vmoveto=4, hlineto=6,
1499 vlineto=7, endchar=14};
1500 enum CFFOp pendingOp = 0;
1501 const int STACK_LIMIT = version == 1 ? 48 : 513;
1502 int stackSize = 0;
1503 bool isDrawing = false;
1504 pixels_t width = glyph->combining ? 0 : PW (glyph->byteCount);
1505 if (version == 1 && width != defaultWidth)
1506 {
1507 cacheCFFOperand (charstrings, FU (width - nominalWidth));
1508 stackSize++;
1509 }
1510 for (const pixels_t *p = getBufferHead (outline),
1511 *const end = getBufferTail (outline); p < end;)
1512 {
1513 int s = 0;
1514 const enum ContourOp op = *p++;
1515 if (op == OP_POINT)
1516 {
1517 const pixels_t x = *p++, y = *p++;
1518 if (x != rx)
1519 {
1520 cacheCFFOperand (charstrings, FU (x - rx));
1521 rx = x;
1522 stackSize++;
1523 s |= 1;
1524 }
1525 if (y != ry)
1526 {
1527 cacheCFFOperand (charstrings, FU (y - ry));
1528 ry = y;
1529 stackSize++;
1530 s |= 2;
1531 }
1532 assert (!(isDrawing && s == 3));
1533 }
1534 if (s)
1535 {
1536 if (!isDrawing)
1537 {
1538 const enum CFFOp moves[] = {0, hmoveto, vmoveto,
1539 rmoveto};
1540 cacheU8 (charstrings, moves[s]);
1541 stackSize = 0;
1542 }
1543 else if (!pendingOp)
1544 pendingOp = (enum CFFOp[]){0, hlineto, vlineto}[s];
1545 }
1546 else if (!isDrawing)
1547 {
1548 // only when the first point happens to be (0, 0)
1549 cacheCFFOperand (charstrings, FU (0));
1550 cacheU8 (charstrings, hmoveto);
1551 stackSize = 0;
1552 }
1553 if (op == OP_CLOSE || stackSize >= STACK_LIMIT)
1554 {
1555 assert (stackSize <= STACK_LIMIT);
1556 cacheU8 (charstrings, pendingOp);
1557 pendingOp = 0;
1558 stackSize = 0;
1559 }
1560 isDrawing = op != OP_CLOSE;
1561 }
1562 if (version == 1)
1563 cacheU8 (charstrings, endchar);
1564 }
1565 size_t lastOffset = countBufferedBytes (charstrings) + 1;
1566 #if SIZE_MAX > U32MAX
1567 if (lastOffset > U32MAX)
1568 fail ("CFF data exceeded size limit.");
1569 #endif
1570 storeU32 (offsets, lastOffset);
1571 int offsetSize = 1 + (lastOffset > 0xff)
1572 + (lastOffset > 0xffff)
1573 + (lastOffset > 0xffffff);
1574 // count (must match 'numGlyphs' in 'maxp' table)
1575 cacheU (cff, font->glyphCount, version * 2);
1576 cacheU8 (cff, offsetSize); // offSize
1577 const uint_least32_t *p = getBufferHead (offsets);
1578 const uint_least32_t *const end = getBufferTail (offsets);
1579 for (; p < end; p++)
1580 cacheU (cff, *p, offsetSize); // offsets
1581 cacheBuffer (cff, charstrings); // data
1582 freeBuffer (offsets);
1583 freeBuffer (charstrings);
1584 freeBuffer (outline);
1585 }
1586 #undef cacheCFF32
1587}
ContourOp
Specify the current contour drawing operation.
Definition: hex2otf.c:1136
void cacheCFFOperand(Buffer *buf, int_fast32_t value)
Cache charstring number encoding in a CFF buffer.
Definition: hex2otf.c:460
void cacheBuffer(Buffer *restrict bufDest, const Buffer *restrict bufSrc)
Append bytes of a table to a byte buffer.
Definition: hex2otf.c:523
void buildOutline(Buffer *result, const byte bitmap[], const size_t byteCount, const enum FillSide fillSide)
Build a glyph outline.
Definition: hex2otf.c:1160
#define U32MAX
Maximum UTF-32 code point value.
Definition: hex2otf.c:56
void prepareOffsets(size_t *sizes)
Prepare 32-bit glyph offsets in a font table.
Definition: hex2otf.c:1275
Buffer * prepareStringIndex(const NameStrings names)
Prepare a font name string index.
Definition: hex2otf.c:1291
byte bitmap[GLYPH_MAX_BYTE_COUNT]
hexadecimal bitmap character array
Definition: hex2otf.c:617
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fillCmapTable()

void fillCmapTable ( Font font)

Fill a "cmap" font table.

The "cmap" table contains character to glyph index mapping information.

Parameters
[in,out]fontThe Font struct to which to add the table.

Definition at line 2109 of file hex2otf.c.

2110{
2111 Glyph *const glyphs = getBufferHead (font->glyphs);
2112 Buffer *rangeHeads = newBuffer (16);
2113 uint_fast32_t rangeCount = 0;
2114 uint_fast32_t bmpRangeCount = 1; // 1 for the last 0xffff-0xffff range
2115 glyphs[0].codePoint = glyphs[1].codePoint; // to start a range at glyph 1
2116 for (uint_fast16_t i = 1; i < font->glyphCount; i++)
2117 {
2118 if (glyphs[i].codePoint != glyphs[i - 1].codePoint + 1)
2119 {
2120 storeU16 (rangeHeads, i);
2121 rangeCount++;
2122 bmpRangeCount += glyphs[i].codePoint < 0xffff;
2123 }
2124 }
2125 Buffer *cmap = newBuffer (256);
2126 addTable (font, "cmap", cmap);
2127 // Format 4 table is always generated for compatibility.
2128 bool hasFormat12 = glyphs[font->glyphCount - 1].codePoint > 0xffff;
2129 cacheU16 (cmap, 0); // version
2130 cacheU16 (cmap, 1 + hasFormat12); // numTables
2131 { // encodingRecords[0]
2132 cacheU16 (cmap, 3); // platformID
2133 cacheU16 (cmap, 1); // encodingID
2134 cacheU32 (cmap, 12 + 8 * hasFormat12); // subtableOffset
2135 }
2136 if (hasFormat12) // encodingRecords[1]
2137 {
2138 cacheU16 (cmap, 3); // platformID
2139 cacheU16 (cmap, 10); // encodingID
2140 cacheU32 (cmap, 36 + 8 * bmpRangeCount); // subtableOffset
2141 }
2142 const uint_least16_t *ranges = getBufferHead (rangeHeads);
2143 const uint_least16_t *const rangesEnd = getBufferTail (rangeHeads);
2144 storeU16 (rangeHeads, font->glyphCount);
2145 { // format 4 table
2146 cacheU16 (cmap, 4); // format
2147 cacheU16 (cmap, 16 + 8 * bmpRangeCount); // length
2148 cacheU16 (cmap, 0); // language
2149 if (bmpRangeCount * 2 > U16MAX)
2150 fail ("Too many ranges in 'cmap' table.");
2151 cacheU16 (cmap, bmpRangeCount * 2); // segCountX2
2152 uint_fast16_t searchRange = 1, entrySelector = -1;
2153 while (searchRange <= bmpRangeCount)
2154 {
2155 searchRange <<= 1;
2156 entrySelector++;
2157 }
2158 cacheU16 (cmap, searchRange); // searchRange
2159 cacheU16 (cmap, entrySelector); // entrySelector
2160 cacheU16 (cmap, bmpRangeCount * 2 - searchRange); // rangeShift
2161 { // endCode[]
2162 const uint_least16_t *p = ranges;
2163 for (p++; p < rangesEnd && glyphs[*p].codePoint < 0xffff; p++)
2164 cacheU16 (cmap, glyphs[*p - 1].codePoint);
2165 uint_fast32_t cp = glyphs[*p - 1].codePoint;
2166 if (cp > 0xfffe)
2167 cp = 0xfffe;
2168 cacheU16 (cmap, cp);
2169 cacheU16 (cmap, 0xffff);
2170 }
2171 cacheU16 (cmap, 0); // reservedPad
2172 { // startCode[]
2173 for (uint_fast32_t i = 0; i < bmpRangeCount - 1; i++)
2174 cacheU16 (cmap, glyphs[ranges[i]].codePoint);
2175 cacheU16 (cmap, 0xffff);
2176 }
2177 { // idDelta[]
2178 const uint_least16_t *p = ranges;
2179 for (; p < rangesEnd && glyphs[*p].codePoint < 0xffff; p++)
2180 cacheU16 (cmap, *p - glyphs[*p].codePoint);
2181 uint_fast16_t delta = 1;
2182 if (p < rangesEnd && *p == 0xffff)
2183 delta = *p - glyphs[*p].codePoint;
2184 cacheU16 (cmap, delta);
2185 }
2186 { // idRangeOffsets[]
2187 for (uint_least16_t i = 0; i < bmpRangeCount; i++)
2188 cacheU16 (cmap, 0);
2189 }
2190 }
2191 if (hasFormat12) // format 12 table
2192 {
2193 cacheU16 (cmap, 12); // format
2194 cacheU16 (cmap, 0); // reserved
2195 cacheU32 (cmap, 16 + 12 * rangeCount); // length
2196 cacheU32 (cmap, 0); // language
2197 cacheU32 (cmap, rangeCount); // numGroups
2198
2199 // groups[]
2200 for (const uint_least16_t *p = ranges; p < rangesEnd; p++)
2201 {
2202 cacheU32 (cmap, glyphs[*p].codePoint); // startCharCode
2203 cacheU32 (cmap, glyphs[p[1] - 1].codePoint); // endCharCode
2204 cacheU32 (cmap, *p); // startGlyphID
2205 }
2206 }
2207 freeBuffer (rangeHeads);
2208}
Here is the caller graph for this function:

◆ fillGposTable()

void fillGposTable ( Font font)

Fill a "GPOS" font table.

The "GPOS" table contains information for glyph positioning.

Parameters
[in,out]fontThe Font struct to which to add the table.

Definition at line 2241 of file hex2otf.c.

2242{
2243 Buffer *gpos = newBuffer (16);
2244 addTable (font, "GPOS", gpos);
2245 cacheU16 (gpos, 1); // majorVersion
2246 cacheU16 (gpos, 0); // minorVersion
2247 cacheU16 (gpos, 10); // scriptListOffset
2248 cacheU16 (gpos, 12); // featureListOffset
2249 cacheU16 (gpos, 14); // lookupListOffset
2250 { // ScriptList table
2251 cacheU16 (gpos, 0); // scriptCount
2252 }
2253 { // Feature List table
2254 cacheU16 (gpos, 0); // featureCount
2255 }
2256 { // Lookup List Table
2257 cacheU16 (gpos, 0); // lookupCount
2258 }
2259}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fillGsubTable()

void fillGsubTable ( Font font)

Fill a "GSUB" font table.

The "GSUB" table contains information for glyph substitution.

Parameters
[in,out]fontThe Font struct to which to add the table.

Definition at line 2269 of file hex2otf.c.

2270{
2271 Buffer *gsub = newBuffer (38);
2272 addTable (font, "GSUB", gsub);
2273 cacheU16 (gsub, 1); // majorVersion
2274 cacheU16 (gsub, 0); // minorVersion
2275 cacheU16 (gsub, 10); // scriptListOffset
2276 cacheU16 (gsub, 34); // featureListOffset
2277 cacheU16 (gsub, 36); // lookupListOffset
2278 { // ScriptList table
2279 cacheU16 (gsub, 2); // scriptCount
2280 { // scriptRecords[0]
2281 cacheBytes (gsub, "DFLT", 4); // scriptTag
2282 cacheU16 (gsub, 14); // scriptOffset
2283 }
2284 { // scriptRecords[1]
2285 cacheBytes (gsub, "thai", 4); // scriptTag
2286 cacheU16 (gsub, 14); // scriptOffset
2287 }
2288 { // Script table
2289 cacheU16 (gsub, 4); // defaultLangSysOffset
2290 cacheU16 (gsub, 0); // langSysCount
2291 { // Default Language System table
2292 cacheU16 (gsub, 0); // lookupOrderOffset
2293 cacheU16 (gsub, 0); // requiredFeatureIndex
2294 cacheU16 (gsub, 0); // featureIndexCount
2295 }
2296 }
2297 }
2298 { // Feature List table
2299 cacheU16 (gsub, 0); // featureCount
2300 }
2301 { // Lookup List Table
2302 cacheU16 (gsub, 0); // lookupCount
2303 }
2304}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fillHeadTable()

void fillHeadTable ( Font font,
enum LocaFormat  locaFormat,
pixels_t  xMin 
)

Fill a "head" font table.

The "head" table contains font header information common to the whole font.

Parameters
[in,out]fontThe Font struct to which to add the table.
[in]locaFormatThe "loca" offset index location table.
[in]xMinThe minimum x-coordinate for a glyph.

Definition at line 1853 of file hex2otf.c.

1854{
1855 Buffer *head = newBuffer (56);
1856 addTable (font, "head", head);
1857 cacheU16 (head, 1); // majorVersion
1858 cacheU16 (head, 0); // minorVersion
1859 cacheZeros (head, 4); // fontRevision (unused)
1860 // The 'checksumAdjustment' field is a checksum of the entire file.
1861 // It is later calculated and written directly in the 'writeFont' function.
1862 cacheU32 (head, 0); // checksumAdjustment (placeholder)
1863 cacheU32 (head, 0x5f0f3cf5); // magicNumber
1864 const uint_fast16_t flags =
1865 + B1 ( 0) // baseline at y=0
1866 + B1 ( 1) // LSB at x=0 (doubtful; probably should be LSB=xMin)
1867 + B0 ( 2) // instructions may depend on point size
1868 + B0 ( 3) // force internal ppem to integers
1869 + B0 ( 4) // instructions may alter advance width
1870 + B0 ( 5) // not used in OpenType
1871 + B0 ( 6) // not used in OpenType
1872 + B0 ( 7) // not used in OpenType
1873 + B0 ( 8) // not used in OpenType
1874 + B0 ( 9) // not used in OpenType
1875 + B0 (10) // not used in OpenType
1876 + B0 (11) // font transformed
1877 + B0 (12) // font converted
1878 + B0 (13) // font optimized for ClearType
1879 + B0 (14) // last resort font
1880 + B0 (15) // reserved
1881 ;
1882 cacheU16 (head, flags); // flags
1883 cacheU16 (head, FUPEM); // unitsPerEm
1884 cacheZeros (head, 8); // created (unused)
1885 cacheZeros (head, 8); // modified (unused)
1886 cacheU16 (head, FU (xMin)); // xMin
1887 cacheU16 (head, FU (-DESCENDER)); // yMin
1888 cacheU16 (head, FU (font->maxWidth)); // xMax
1889 cacheU16 (head, FU (ASCENDER)); // yMax
1890 // macStyle (must agree with 'fsSelection' in 'OS/2' table)
1891 const uint_fast16_t macStyle =
1892 + B0 (0) // bold
1893 + B0 (1) // italic
1894 + B0 (2) // underline
1895 + B0 (3) // outline
1896 + B0 (4) // shadow
1897 + B0 (5) // condensed
1898 + B0 (6) // extended
1899 // 7-15 reserved
1900 ;
1901 cacheU16 (head, macStyle);
1902 cacheU16 (head, GLYPH_HEIGHT); // lowestRecPPEM
1903 cacheU16 (head, 2); // fontDirectionHint
1904 cacheU16 (head, locaFormat); // indexToLocFormat
1905 cacheU16 (head, 0); // glyphDataFormat
1906}
void cacheZeros(Buffer *buf, size_t count)
Append 1 to 4 bytes of zeroes to a buffer, for padding.
Definition: hex2otf.c:491
#define B0(shift)
Clear a given bit in a word.
Definition: hex2otf.c:66
#define B1(shift)
Set a given bit in a word.
Definition: hex2otf.c:67
#define FUPEM
Font units per em.
Definition: hex2otf.c:82
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fillHheaTable()

void fillHheaTable ( Font font,
pixels_t  xMin 
)

Fill a "hhea" font table.

The "hhea" table contains horizontal header information, for example left and right side bearings.

Parameters
[in,out]fontThe Font struct to which to add the table.
[in]xMinThe minimum x-coordinate for a glyph.

Definition at line 1918 of file hex2otf.c.

1919{
1920 Buffer *hhea = newBuffer (36);
1921 addTable (font, "hhea", hhea);
1922 cacheU16 (hhea, 1); // majorVersion
1923 cacheU16 (hhea, 0); // minorVersion
1924 cacheU16 (hhea, FU (ASCENDER)); // ascender
1925 cacheU16 (hhea, FU (-DESCENDER)); // descender
1926 cacheU16 (hhea, FU (0)); // lineGap
1927 cacheU16 (hhea, FU (font->maxWidth)); // advanceWidthMax
1928 cacheU16 (hhea, FU (xMin)); // minLeftSideBearing
1929 cacheU16 (hhea, FU (0)); // minRightSideBearing (unused)
1930 cacheU16 (hhea, FU (font->maxWidth)); // xMaxExtent
1931 cacheU16 (hhea, 1); // caretSlopeRise
1932 cacheU16 (hhea, 0); // caretSlopeRun
1933 cacheU16 (hhea, 0); // caretOffset
1934 cacheU16 (hhea, 0); // reserved
1935 cacheU16 (hhea, 0); // reserved
1936 cacheU16 (hhea, 0); // reserved
1937 cacheU16 (hhea, 0); // reserved
1938 cacheU16 (hhea, 0); // metricDataFormat
1939 cacheU16 (hhea, font->glyphCount); // numberOfHMetrics
1940}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fillHmtxTable()

void fillHmtxTable ( Font font)

Fill an "hmtx" font table.

The "hmtx" table contains horizontal metrics information.

Parameters
[in,out]fontThe Font struct to which to add the table.

Definition at line 2087 of file hex2otf.c.

2088{
2089 Buffer *hmtx = newBuffer (4 * font->glyphCount);
2090 addTable (font, "hmtx", hmtx);
2091 const Glyph *const glyphs = getBufferHead (font->glyphs);
2092 const Glyph *const glyphsEnd = getBufferTail (font->glyphs);
2093 for (const Glyph *glyph = glyphs; glyph < glyphsEnd; glyph++)
2094 {
2095 int_fast16_t aw = glyph->combining ? 0 : PW (glyph->byteCount);
2096 cacheU16 (hmtx, FU (aw)); // advanceWidth
2097 cacheU16 (hmtx, FU (glyph->lsb)); // lsb
2098 }
2099}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fillMaxpTable()

void fillMaxpTable ( Font font,
bool  isCFF,
uint_fast16_t  maxPoints,
uint_fast16_t  maxContours 
)

Fill a "maxp" font table.

The "maxp" table contains maximum profile information, such as the memory required to contain the font.

Parameters
[in,out]fontThe Font struct to which to add the table.
[in]isCFFtrue if a CFF font is included, false otherwise.
[in]maxPointsMaximum points in a non-composite glyph.
[in]maxContoursMaximum contours in a non-composite glyph.

Definition at line 1954 of file hex2otf.c.

1956{
1957 Buffer *maxp = newBuffer (32);
1958 addTable (font, "maxp", maxp);
1959 cacheU32 (maxp, isCFF ? 0x00005000 : 0x00010000); // version
1960 cacheU16 (maxp, font->glyphCount); // numGlyphs
1961 if (isCFF)
1962 return;
1963 cacheU16 (maxp, maxPoints); // maxPoints
1964 cacheU16 (maxp, maxContours); // maxContours
1965 cacheU16 (maxp, 0); // maxCompositePoints
1966 cacheU16 (maxp, 0); // maxCompositeContours
1967 cacheU16 (maxp, 0); // maxZones
1968 cacheU16 (maxp, 0); // maxTwilightPoints
1969 cacheU16 (maxp, 0); // maxStorage
1970 cacheU16 (maxp, 0); // maxFunctionDefs
1971 cacheU16 (maxp, 0); // maxInstructionDefs
1972 cacheU16 (maxp, 0); // maxStackElements
1973 cacheU16 (maxp, 0); // maxSizeOfInstructions
1974 cacheU16 (maxp, 0); // maxComponentElements
1975 cacheU16 (maxp, 0); // maxComponentDepth
1976}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fillNameTable()

void fillNameTable ( Font font,
NameStrings  nameStrings 
)

Fill a "name" font table.

The "name" table contains name information, for example for Name IDs.

Parameters
[in,out]fontThe Font struct to which to add the table.
[in]namesList of NameStrings.

Definition at line 2366 of file hex2otf.c.

2367{
2368 Buffer *name = newBuffer (2048);
2369 addTable (font, "name", name);
2370 size_t nameStringCount = 0;
2371 for (size_t i = 0; i < MAX_NAME_IDS; i++)
2372 nameStringCount += !!nameStrings[i];
2373 cacheU16 (name, 0); // version
2374 cacheU16 (name, nameStringCount); // count
2375 cacheU16 (name, 2 * 3 + 12 * nameStringCount); // storageOffset
2376 Buffer *stringData = newBuffer (1024);
2377 // nameRecord[]
2378 for (size_t i = 0; i < MAX_NAME_IDS; i++)
2379 {
2380 if (!nameStrings[i])
2381 continue;
2382 size_t offset = countBufferedBytes (stringData);
2383 cacheStringAsUTF16BE (stringData, nameStrings[i]);
2384 size_t length = countBufferedBytes (stringData) - offset;
2385 if (offset > U16MAX || length > U16MAX)
2386 fail ("Name strings are too long.");
2387 // Platform ID 0 (Unicode) is not well supported.
2388 // ID 3 (Windows) seems to be the best for compatibility.
2389 cacheU16 (name, 3); // platformID = Windows
2390 cacheU16 (name, 1); // encodingID = Unicode BMP
2391 cacheU16 (name, 0x0409); // languageID = en-US
2392 cacheU16 (name, i); // nameID
2393 cacheU16 (name, length); // length
2394 cacheU16 (name, offset); // stringOffset
2395 }
2396 cacheBuffer (name, stringData);
2397 freeBuffer (stringData);
2398}
#define MAX_NAME_IDS
Name IDs 0-255 are used for standard names.
Definition: hex2otf.c:88
void cacheStringAsUTF16BE(Buffer *buf, const char *str)
Cache a string as a big-ending UTF-16 surrogate pair.
Definition: hex2otf.c:2316
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fillOS2Table()

void fillOS2Table ( Font font)

Fill an "OS/2" font table.

The "OS/2" table contains OS/2 and Windows font metrics information.

Parameters
[in,out]fontThe Font struct to which to add the table.

Definition at line 1986 of file hex2otf.c.

1987{
1988 Buffer *os2 = newBuffer (100);
1989 addTable (font, "OS/2", os2);
1990 cacheU16 (os2, 5); // version
1991 // HACK: Average glyph width is not actually calculated.
1992 cacheU16 (os2, FU (font->maxWidth)); // xAvgCharWidth
1993 cacheU16 (os2, 400); // usWeightClass = Normal
1994 cacheU16 (os2, 5); // usWidthClass = Medium
1995 const uint_fast16_t typeFlags =
1996 + B0 (0) // reserved
1997 // usage permissions, one of:
1998 // Default: Installable embedding
1999 + B0 (1) // Restricted License embedding
2000 + B0 (2) // Preview & Print embedding
2001 + B0 (3) // Editable embedding
2002 // 4-7 reserved
2003 + B0 (8) // no subsetting
2004 + B0 (9) // bitmap embedding only
2005 // 10-15 reserved
2006 ;
2007 cacheU16 (os2, typeFlags); // fsType
2008 cacheU16 (os2, FU (5)); // ySubscriptXSize
2009 cacheU16 (os2, FU (7)); // ySubscriptYSize
2010 cacheU16 (os2, FU (0)); // ySubscriptXOffset
2011 cacheU16 (os2, FU (1)); // ySubscriptYOffset
2012 cacheU16 (os2, FU (5)); // ySuperscriptXSize
2013 cacheU16 (os2, FU (7)); // ySuperscriptYSize
2014 cacheU16 (os2, FU (0)); // ySuperscriptXOffset
2015 cacheU16 (os2, FU (4)); // ySuperscriptYOffset
2016 cacheU16 (os2, FU (1)); // yStrikeoutSize
2017 cacheU16 (os2, FU (5)); // yStrikeoutPosition
2018 cacheU16 (os2, 0x080a); // sFamilyClass = Sans Serif, Matrix
2019 const byte panose[] =
2020 {
2021 2, // Family Kind = Latin Text
2022 11, // Serif Style = Normal Sans
2023 4, // Weight = Thin
2024 // Windows would render all glyphs to the same width,
2025 // if 'Proportion' is set to 'Monospaced' (as Unifont should be).
2026 // 'Condensed' is the best alternative according to metrics.
2027 6, // Proportion = Condensed
2028 2, // Contrast = None
2029 2, // Stroke = No Variation
2030 2, // Arm Style = Straight Arms
2031 8, // Letterform = Normal/Square
2032 2, // Midline = Standard/Trimmed
2033 4, // X-height = Constant/Large
2034 };
2035 cacheBytes (os2, panose, sizeof panose); // panose
2036 // HACK: All defined Unicode ranges are marked functional for convenience.
2037 cacheU32 (os2, 0xffffffff); // ulUnicodeRange1
2038 cacheU32 (os2, 0xffffffff); // ulUnicodeRange2
2039 cacheU32 (os2, 0xffffffff); // ulUnicodeRange3
2040 cacheU32 (os2, 0x0effffff); // ulUnicodeRange4
2041 cacheBytes (os2, "GNU ", 4); // achVendID
2042 // fsSelection (must agree with 'macStyle' in 'head' table)
2043 const uint_fast16_t selection =
2044 + B0 (0) // italic
2045 + B0 (1) // underscored
2046 + B0 (2) // negative
2047 + B0 (3) // outlined
2048 + B0 (4) // strikeout
2049 + B0 (5) // bold
2050 + B1 (6) // regular
2051 + B1 (7) // use sTypo* metrics in this table
2052 + B1 (8) // font name conforms to WWS model
2053 + B0 (9) // oblique
2054 // 10-15 reserved
2055 ;
2056 cacheU16 (os2, selection);
2057 const Glyph *glyphs = getBufferHead (font->glyphs);
2058 uint_fast32_t first = glyphs[1].codePoint;
2059 uint_fast32_t last = glyphs[font->glyphCount - 1].codePoint;
2060 cacheU16 (os2, first < U16MAX ? first : U16MAX); // usFirstCharIndex
2061 cacheU16 (os2, last < U16MAX ? last : U16MAX); // usLastCharIndex
2062 cacheU16 (os2, FU (ASCENDER)); // sTypoAscender
2063 cacheU16 (os2, FU (-DESCENDER)); // sTypoDescender
2064 cacheU16 (os2, FU (0)); // sTypoLineGap
2065 cacheU16 (os2, FU (ASCENDER)); // usWinAscent
2066 cacheU16 (os2, FU (DESCENDER)); // usWinDescent
2067 // HACK: All reasonable code pages are marked functional for convenience.
2068 cacheU32 (os2, 0x603f01ff); // ulCodePageRange1
2069 cacheU32 (os2, 0xffff0000); // ulCodePageRange2
2070 cacheU16 (os2, FU (8)); // sxHeight
2071 cacheU16 (os2, FU (10)); // sCapHeight
2072 cacheU16 (os2, 0); // usDefaultChar
2073 cacheU16 (os2, 0x20); // usBreakChar
2074 cacheU16 (os2, 0); // usMaxContext
2075 cacheU16 (os2, 0); // usLowerOpticalPointSize
2076 cacheU16 (os2, 0xffff); // usUpperOpticalPointSize
2077}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fillPostTable()

void fillPostTable ( Font font)

Fill a "post" font table.

The "post" table contains information for PostScript printers.

Parameters
[in,out]fontThe Font struct to which to add the table.

Definition at line 2218 of file hex2otf.c.

2219{
2220 Buffer *post = newBuffer (32);
2221 addTable (font, "post", post);
2222 cacheU32 (post, 0x00030000); // version = 3.0
2223 cacheU32 (post, 0); // italicAngle
2224 cacheU16 (post, 0); // underlinePosition
2225 cacheU16 (post, 1); // underlineThickness
2226 cacheU32 (post, 1); // isFixedPitch
2227 cacheU32 (post, 0); // minMemType42
2228 cacheU32 (post, 0); // maxMemType42
2229 cacheU32 (post, 0); // minMemType1
2230 cacheU32 (post, 0); // maxMemType1
2231}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fillTrueType()

void fillTrueType ( Font font,
enum LocaFormat format,
uint_fast16_t *  maxPoints,
uint_fast16_t *  maxContours 
)

Add a TrueType table to a font.

Parameters
[in,out]fontPointer to a Font struct to contain the TrueType table.
[in]formatThe TrueType "loca" table format, Offset16 or Offset32.
[in]namesList of NameStrings.

Definition at line 1597 of file hex2otf.c.

1599{
1600 Buffer *glyf = newBuffer (65536);
1601 addTable (font, "glyf", glyf);
1602 Buffer *loca = newBuffer (4 * (font->glyphCount + 1));
1603 addTable (font, "loca", loca);
1604 *format = LOCA_OFFSET32;
1605 Buffer *endPoints = newBuffer (256);
1606 Buffer *flags = newBuffer (256);
1607 Buffer *xs = newBuffer (256);
1608 Buffer *ys = newBuffer (256);
1609 Buffer *outline = newBuffer (1024);
1610 Glyph *const glyphs = getBufferHead (font->glyphs);
1611 const Glyph *const glyphsEnd = getBufferTail (font->glyphs);
1612 for (Glyph *glyph = glyphs; glyph < glyphsEnd; glyph++)
1613 {
1614 cacheU32 (loca, countBufferedBytes (glyf));
1615 pixels_t rx = -glyph->pos;
1616 pixels_t ry = DESCENDER;
1617 pixels_t xMin = GLYPH_MAX_WIDTH, xMax = 0;
1618 pixels_t yMin = ASCENDER, yMax = -DESCENDER;
1619 resetBuffer (endPoints);
1620 resetBuffer (flags);
1621 resetBuffer (xs);
1622 resetBuffer (ys);
1623 resetBuffer (outline);
1624 buildOutline (outline, glyph->bitmap, glyph->byteCount, FILL_RIGHT);
1625 uint_fast32_t pointCount = 0, contourCount = 0;
1626 for (const pixels_t *p = getBufferHead (outline),
1627 *const end = getBufferTail (outline); p < end;)
1628 {
1629 const enum ContourOp op = *p++;
1630 if (op == OP_CLOSE)
1631 {
1632 contourCount++;
1633 assert (contourCount <= U16MAX);
1634 cacheU16 (endPoints, pointCount - 1);
1635 continue;
1636 }
1637 assert (op == OP_POINT);
1638 pointCount++;
1639 assert (pointCount <= U16MAX);
1640 const pixels_t x = *p++, y = *p++;
1641 uint_fast8_t pointFlags =
1642 + B1 (0) // point is on curve
1643 + BX (1, x != rx) // x coordinate is 1 byte instead of 2
1644 + BX (2, y != ry) // y coordinate is 1 byte instead of 2
1645 + B0 (3) // repeat
1646 + BX (4, x >= rx) // when x is 1 byte: x is positive;
1647 // when x is 2 bytes: x unchanged and omitted
1648 + BX (5, y >= ry) // when y is 1 byte: y is positive;
1649 // when y is 2 bytes: y unchanged and omitted
1650 + B1 (6) // contours may overlap
1651 + B0 (7) // reserved
1652 ;
1653 cacheU8 (flags, pointFlags);
1654 if (x != rx)
1655 cacheU8 (xs, FU (x > rx ? x - rx : rx - x));
1656 if (y != ry)
1657 cacheU8 (ys, FU (y > ry ? y - ry : ry - y));
1658 if (x < xMin) xMin = x;
1659 if (y < yMin) yMin = y;
1660 if (x > xMax) xMax = x;
1661 if (y > yMax) yMax = y;
1662 rx = x;
1663 ry = y;
1664 }
1665 if (contourCount == 0)
1666 continue; // blank glyph is indicated by the 'loca' table
1667 glyph->lsb = glyph->pos + xMin;
1668 cacheU16 (glyf, contourCount); // numberOfContours
1669 cacheU16 (glyf, FU (glyph->pos + xMin)); // xMin
1670 cacheU16 (glyf, FU (yMin)); // yMin
1671 cacheU16 (glyf, FU (glyph->pos + xMax)); // xMax
1672 cacheU16 (glyf, FU (yMax)); // yMax
1673 cacheBuffer (glyf, endPoints); // endPtsOfContours[]
1674 cacheU16 (glyf, 0); // instructionLength
1675 cacheBuffer (glyf, flags); // flags[]
1676 cacheBuffer (glyf, xs); // xCoordinates[]
1677 cacheBuffer (glyf, ys); // yCoordinates[]
1678 if (pointCount > *maxPoints)
1679 *maxPoints = pointCount;
1680 if (contourCount > *maxContours)
1681 *maxContours = contourCount;
1682 }
1683 cacheU32 (loca, countBufferedBytes (glyf));
1684 freeBuffer (endPoints);
1685 freeBuffer (flags);
1686 freeBuffer (xs);
1687 freeBuffer (ys);
1688 freeBuffer (outline);
1689}
#define BX(shift, x)
Truncate & shift word.
Definition: hex2otf.c:65
Here is the call graph for this function:
Here is the caller graph for this function:

◆ freeBuffer()

void freeBuffer ( Buffer buf)

Free the memory previously allocated for a buffer.

This function frees the memory allocated to an array of type Buffer *.

Parameters
[in]bufThe pointer to an array of type Buffer *.

Definition at line 337 of file hex2otf.c.

338{
339 free (buf->begin);
340 buf->capacity = 0;
341}

◆ initBuffers()

void initBuffers ( size_t  count)

Initialize an array of buffer pointers to all zeroes.

This function initializes the "allBuffers" array of buffer pointers to all zeroes.

Parameters
[in]countThe number of buffer array pointers to allocate.

Definition at line 152 of file hex2otf.c.

153{
154 assert (count > 0);
155 assert (bufferCount == 0); // uninitialized
156 allBuffers = calloc (count, sizeof *allBuffers);
157 if (!allBuffers)
158 fail ("Failed to initialize buffers.");
159 bufferCount = count;
160 nextBufferIndex = 0;
161}
size_t nextBufferIndex
Index number to tail element of Buffer * array.
Definition: hex2otf.c:141
Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char *  argv[] 
)

The main function.

Parameters
[in]argcThe number of command-line arguments.
[in]argvThe array of command-line arguments.
Returns
EXIT_FAILURE upon fatal error, EXIT_SUCCESS otherwise.

Definition at line 2603 of file hex2otf.c.

2604{
2605 initBuffers (16);
2606 atexit (cleanBuffers);
2607 Options opt = parseOptions (argv);
2608 Font font;
2609 font.tables = newBuffer (sizeof (Table) * 16);
2610 font.glyphs = newBuffer (sizeof (Glyph) * MAX_GLYPHS);
2611 readGlyphs (&font, opt.hex);
2612 sortGlyphs (&font);
2613 enum LocaFormat loca = LOCA_OFFSET16;
2614 uint_fast16_t maxPoints = 0, maxContours = 0;
2615 pixels_t xMin = 0;
2616 if (opt.pos)
2617 positionGlyphs (&font, opt.pos, &xMin);
2618 if (opt.gpos)
2619 fillGposTable (&font);
2620 if (opt.gsub)
2621 fillGsubTable (&font);
2622 if (opt.cff)
2623 fillCFF (&font, opt.cff, opt.nameStrings);
2624 if (opt.truetype)
2625 fillTrueType (&font, &loca, &maxPoints, &maxContours);
2626 if (opt.blankOutline)
2627 fillBlankOutline (&font);
2628 if (opt.bitmap)
2629 fillBitmap (&font);
2630 fillHeadTable (&font, loca, xMin);
2631 fillHheaTable (&font, xMin);
2632 fillMaxpTable (&font, opt.cff, maxPoints, maxContours);
2633 fillOS2Table (&font);
2634 fillNameTable (&font, opt.nameStrings);
2635 fillHmtxTable (&font);
2636 fillCmapTable (&font);
2637 fillPostTable (&font);
2638 organizeTables (&font, opt.cff);
2639 writeFont (&font, opt.cff, opt.out);
2640 return EXIT_SUCCESS;
2641}
void organizeTables(Font *font, bool isCFF)
Sort tables according to OpenType recommendations.
Definition: hex2otf.c:711
void fillGsubTable(Font *font)
Fill a "GSUB" font table.
Definition: hex2otf.c:2269
void writeFont(Font *font, bool isCFF, const char *fileName)
Write OpenType font to output file.
Definition: hex2otf.c:786
void fillPostTable(Font *font)
Fill a "post" font table.
Definition: hex2otf.c:2218
#define MAX_GLYPHS
An OpenType font has at most 65536 glyphs.
Definition: hex2otf.c:85
void fillHheaTable(Font *font, pixels_t xMin)
Fill a "hhea" font table.
Definition: hex2otf.c:1918
void fillTrueType(Font *font, enum LocaFormat *format, uint_fast16_t *maxPoints, uint_fast16_t *maxContours)
Add a TrueType table to a font.
Definition: hex2otf.c:1597
void fillCFF(Font *font, int version, const NameStrings names)
Add a CFF table to a font.
Definition: hex2otf.c:1329
void fillHeadTable(Font *font, enum LocaFormat locaFormat, pixels_t xMin)
Fill a "head" font table.
Definition: hex2otf.c:1853
void initBuffers(size_t count)
Initialize an array of buffer pointers to all zeroes.
Definition: hex2otf.c:152
void fillCmapTable(Font *font)
Fill a "cmap" font table.
Definition: hex2otf.c:2109
void fillGposTable(Font *font)
Fill a "GPOS" font table.
Definition: hex2otf.c:2241
void sortGlyphs(Font *font)
Sort the glyphs in a font by Unicode code point.
Definition: hex2otf.c:1119
void fillNameTable(Font *font, NameStrings nameStrings)
Fill a "name" font table.
Definition: hex2otf.c:2366
LocaFormat
Index to Location ("loca") offset information.
Definition: hex2otf.c:658
void fillHmtxTable(Font *font)
Fill an "hmtx" font table.
Definition: hex2otf.c:2087
void fillBlankOutline(Font *font)
Create a dummy blank outline in a font table.
Definition: hex2otf.c:1697
void fillOS2Table(Font *font)
Fill an "OS/2" font table.
Definition: hex2otf.c:1986
Options parseOptions(char *const argv[const])
Parse command line options.
Definition: hex2otf.c:2500
void cleanBuffers()
Free all allocated buffer pointers.
Definition: hex2otf.c:170
void readGlyphs(Font *font, const char *fileName)
Read glyph definitions from a Unifont .hex format file.
Definition: hex2otf.c:966
void positionGlyphs(Font *font, const char *fileName, pixels_t *xMin)
Position a glyph within a 16-by-16 pixel bounding box.
Definition: hex2otf.c:1061
void fillBitmap(Font *font)
Fill OpenType bitmap data and location tables.
Definition: hex2otf.c:1728
void fillMaxpTable(Font *font, bool isCFF, uint_fast16_t maxPoints, uint_fast16_t maxContours)
Fill a "maxp" font table.
Definition: hex2otf.c:1954
Data structure to hold information for one font.
Definition: hex2otf.c:629
Data structure to hold options for OpenType font output.
Definition: hex2otf.c:2454
Here is the call graph for this function:

◆ matchToken()

const char * matchToken ( const char *  operand,
const char *  key,
char  delimiter 
)

Match a command line option with its key for enabling.

Parameters
[in]operandA pointer to the specified operand.
[in]keyPointer to the option structure.
[in]delimeterThe delimiter to end searching.
Returns
Pointer to the first character of the desired option.

Definition at line 2470 of file hex2otf.c.

2471{
2472 while (*key)
2473 if (*operand++ != *key++)
2474 return NULL;
2475 if (!*operand || *operand++ == delimiter)
2476 return operand;
2477 return NULL;
2478}
Here is the caller graph for this function:

◆ newBuffer()

Buffer * newBuffer ( size_t  initialCapacity)

Create a new buffer.

This function creates a new buffer array of type Buffer, with an initial size of initialCapacity elements.

Parameters
[in]initialCapacityThe initial number of elements in the buffer.

Definition at line 188 of file hex2otf.c.

189{
190 assert (initialCapacity > 0);
191 Buffer *buf = NULL;
192 size_t sentinel = nextBufferIndex;
193 do
194 {
196 nextBufferIndex = 0;
197 if (allBuffers[nextBufferIndex].capacity == 0)
198 {
199 buf = &allBuffers[nextBufferIndex++];
200 break;
201 }
202 } while (++nextBufferIndex != sentinel);
203 if (!buf) // no existing buffer available
204 {
205 size_t newSize = sizeof (Buffer) * bufferCount * 2;
206 void *extended = realloc (allBuffers, newSize);
207 if (!extended)
208 fail ("Failed to create new buffers.");
209 allBuffers = extended;
210 memset (allBuffers + bufferCount, 0, sizeof (Buffer) * bufferCount);
211 buf = &allBuffers[bufferCount];
213 bufferCount *= 2;
214 }
215 buf->begin = malloc (initialCapacity);
216 if (!buf->begin)
217 fail ("Failed to allocate %zu bytes of memory.", initialCapacity);
218 buf->capacity = initialCapacity;
219 buf->next = buf->begin;
220 buf->end = buf->begin + initialCapacity;
221 return buf;
222}
struct Buffer Buffer
Generic data structure for a linked list of buffer elements.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ organizeTables()

void organizeTables ( Font font,
bool  isCFF 
)

Sort tables according to OpenType recommendations.

The various tables in a font are sorted in an order recommended for TrueType font files.

Parameters
[in,out]fontThe font in which to sort tables.
[in]isCFFTrue iff Compact Font Format (CFF) is being used.

Definition at line 711 of file hex2otf.c.

712{
713 const char *const cffOrder[] = {"head","hhea","maxp","OS/2","name",
714 "cmap","post","CFF ",NULL};
715 const char *const truetypeOrder[] = {"head","hhea","maxp","OS/2",
716 "hmtx","LTSH","VDMX","hdmx","cmap","fpgm","prep","cvt ","loca",
717 "glyf","kern","name","post","gasp","PCLT","DSIG",NULL};
718 const char *const *const order = isCFF ? cffOrder : truetypeOrder;
719 Table *unordered = getBufferHead (font->tables);
720 const Table *const tablesEnd = getBufferTail (font->tables);
721 for (const char *const *p = order; *p; p++)
722 {
723 uint_fast32_t tag = tagAsU32 (*p);
724 for (Table *t = unordered; t < tablesEnd; t++)
725 {
726 if (t->tag != tag)
727 continue;
728 if (t != unordered)
729 {
730 Table temp = *unordered;
731 *unordered = *t;
732 *t = temp;
733 }
734 unordered++;
735 break;
736 }
737 }
738}
Here is the caller graph for this function:

◆ parseOptions()

Options parseOptions ( char *const  argv[const ])

Parse command line options.

Option         Data Type      Description
------         ---------      -----------
truetype       bool           Generate TrueType outlines
blankOutline   bool           Generate blank outlines
bitmap         bool           Generate embedded bitmap
gpos           bool           Generate a dummy GPOS table
gsub           bool           Generate a dummy GSUB table
cff            int            Generate CFF 1 or CFF 2 outlines
hex            const char *   Name of Unifont .hex file
pos            const char *   Name of Unifont combining data file
out            const char *   Name of output font file
nameStrings    NameStrings    Array of TrueType font Name IDs
Parameters
[in]argvPointer to array of command line options.
Returns
Data structure to hold requested command line options.

Definition at line 2500 of file hex2otf.c.

2501{
2502 Options opt = {0}; // all options default to 0, false and NULL
2503 const char *format = NULL;
2504 struct StringArg
2505 {
2506 const char *const key;
2507 const char **const value;
2508 } strArgs[] =
2509 {
2510 {"hex", &opt.hex},
2511 {"pos", &opt.pos},
2512 {"out", &opt.out},
2513 {"format", &format},
2514 {NULL, NULL} // sentinel
2515 };
2516 for (char *const *argp = argv + 1; *argp; argp++)
2517 {
2518 const char *const arg = *argp;
2519 struct StringArg *p;
2520 const char *value = NULL;
2521 if (strcmp (arg, "--help") == 0)
2522 printHelp ();
2523 if (strcmp (arg, "--version") == 0)
2524 printVersion ();
2525 for (p = strArgs; p->key; p++)
2526 if ((value = matchToken (arg, p->key, '=')))
2527 break;
2528 if (p->key)
2529 {
2530 if (!*value)
2531 fail ("Empty argument: '%s'.", p->key);
2532 if (*p->value)
2533 fail ("Duplicate argument: '%s'.", p->key);
2534 *p->value = value;
2535 }
2536 else // shall be a name string
2537 {
2538 char *endptr;
2539 unsigned long id = strtoul (arg, &endptr, 10);
2540 if (endptr == arg || id >= MAX_NAME_IDS || *endptr != '=')
2541 fail ("Invalid argument: '%s'.", arg);
2542 endptr++; // skip '='
2543 if (opt.nameStrings[id])
2544 fail ("Duplicate name ID: %lu.", id);
2545 opt.nameStrings[id] = endptr;
2546 }
2547 }
2548 if (!opt.hex)
2549 fail ("Hex file is not specified.");
2550 if (opt.pos && opt.pos[0] == '\0')
2551 opt.pos = NULL; // Position file is optional. Empty path means none.
2552 if (!opt.out)
2553 fail ("Output file is not specified.");
2554 if (!format)
2555 fail ("Format is not specified.");
2556 for (const NamePair *p = defaultNames; p->str; p++)
2557 if (!opt.nameStrings[p->id])
2558 opt.nameStrings[p->id] = p->str;
2559 bool cff = false, cff2 = false;
2560 struct Symbol
2561 {
2562 const char *const key;
2563 bool *const found;
2564 } symbols[] =
2565 {
2566 {"cff", &cff},
2567 {"cff2", &cff2},
2568 {"truetype", &opt.truetype},
2569 {"blank", &opt.blankOutline},
2570 {"bitmap", &opt.bitmap},
2571 {"gpos", &opt.gpos},
2572 {"gsub", &opt.gsub},
2573 {NULL, NULL} // sentinel
2574 };
2575 while (*format)
2576 {
2577 const struct Symbol *p;
2578 const char *next = NULL;
2579 for (p = symbols; p->key; p++)
2580 if ((next = matchToken (format, p->key, ',')))
2581 break;
2582 if (!p->key)
2583 fail ("Invalid format.");
2584 *p->found = true;
2585 format = next;
2586 }
2587 if (cff + cff2 + opt.truetype + opt.blankOutline > 1)
2588 fail ("At most one outline format can be accepted.");
2589 if (!(cff || cff2 || opt.truetype || opt.bitmap))
2590 fail ("Invalid format.");
2591 opt.cff = cff + cff2 * 2;
2592 return opt;
2593}
void printHelp()
Print help message to stdout and then exit.
Definition: hex2otf.c:2426
void printVersion()
Print program version string on stdout.
Definition: hex2otf.c:2407
const char * matchToken(const char *operand, const char *key, char delimiter)
Match a command line option with its key for enabling.
Definition: hex2otf.c:2470
const NamePair defaultNames[]
Allocate array of NameID codes with default values.
Definition: hex2otf.h:93
Data structure for a font ID number and name character string.
Definition: hex2otf.h:78
Here is the call graph for this function:
Here is the caller graph for this function:

◆ positionGlyphs()

void positionGlyphs ( Font font,
const char *  fileName,
pixels_t xMin 
)

Position a glyph within a 16-by-16 pixel bounding box.

Position a glyph within the 16-by-16 pixel drawing area and note whether or not the glyph is a combining character.

N.B.: Glyphs must be sorted by code point before calling this function.

Parameters
[in,out]fontFont data structure pointer to store glyphs.
[in]fileNameName of glyph file to read.
[in]xMinMinimum x-axis value (for left side bearing).

Definition at line 1061 of file hex2otf.c.

1062{
1063 *xMin = 0;
1064 FILE *file = fopen (fileName, "r");
1065 if (!file)
1066 fail ("Failed to open file '%s'.", fileName);
1067 Glyph *glyphs = getBufferHead (font->glyphs);
1068 const Glyph *const endGlyph = glyphs + font->glyphCount;
1069 Glyph *nextGlyph = &glyphs[1]; // predict and avoid search
1070 for (;;)
1071 {
1072 uint_fast32_t codePoint;
1073 if (readCodePoint (&codePoint, fileName, file))
1074 break;
1075 Glyph *glyph = nextGlyph;
1076 if (glyph == endGlyph || glyph->codePoint != codePoint)
1077 {
1078 // Prediction failed. Search.
1079 const Glyph key = { .codePoint = codePoint };
1080 glyph = bsearch (&key, glyphs + 1, font->glyphCount - 1,
1081 sizeof key, byCodePoint);
1082 if (!glyph)
1083 fail ("Glyph "PRI_CP" is positioned but not defined.",
1084 codePoint);
1085 }
1086 nextGlyph = glyph + 1;
1087 char s[8];
1088 if (!fgets (s, sizeof s, file))
1089 fail ("%s: Read error.", fileName);
1090 char *end;
1091 const long value = strtol (s, &end, 10);
1092 if (*end != '\n' && *end != '\0')
1093 fail ("Position of glyph "PRI_CP" is invalid.", codePoint);
1094 // Currently no glyph is moved to the right,
1095 // so positive position is considered out of range.
1096 // If this limit is to be lifted,
1097 // 'xMax' of bounding box in 'head' table shall also be updated.
1098 if (value < -GLYPH_MAX_WIDTH || value > 0)
1099 fail ("Position of glyph "PRI_CP" is out of range.", codePoint);
1100 glyph->combining = true;
1101 glyph->pos = value;
1102 glyph->lsb = value; // updated during outline generation
1103 if (value < *xMin)
1104 *xMin = value;
1105 }
1106 fclose (file);
1107}
int byCodePoint(const void *a, const void *b)
Compare two Unicode code points to determine which is greater.
Definition: hex2otf.c:1040
bool readCodePoint(uint_fast32_t *codePoint, const char *fileName, FILE *file)
Read up to 6 hexadecimal digits and a colon from file.
Definition: hex2otf.c:919
#define PRI_CP
Format string to print Unicode code point.
Definition: hex2otf.c:58
pixels_t lsb
left side bearing (x position of leftmost contour point)
Definition: hex2otf.c:622
Here is the call graph for this function:
Here is the caller graph for this function:

◆ prepareOffsets()

void prepareOffsets ( size_t *  sizes)

Prepare 32-bit glyph offsets in a font table.

Parameters
[in]sizesArray of glyph sizes, for offset calculations.

Definition at line 1275 of file hex2otf.c.

1276{
1277 size_t *p = sizes;
1278 for (size_t *i = sizes + 1; *i; i++)
1279 *i += *p++;
1280 if (*p > 2147483647U) // offset not representable
1281 fail ("CFF table is too large.");
1282}
Here is the call graph for this function:

◆ prepareStringIndex()

Buffer * prepareStringIndex ( const NameStrings  names)

Prepare a font name string index.

Parameters
[in]namesList of name strings.
Returns
Pointer to a Buffer struct containing the string names.

Get the number of elements in array char *strings[].

Definition at line 1291 of file hex2otf.c.

1292{
1293 Buffer *buf = newBuffer (256);
1294 assert (names[6]);
1295 const char *strings[] = {"Adobe", "Identity", names[6]};
1296 /// Get the number of elements in array char *strings[].
1297 #define stringCount (sizeof strings / sizeof *strings)
1298 static_assert (stringCount <= U16MAX, "too many strings");
1299 size_t offset = 1;
1300 size_t lengths[stringCount];
1301 for (size_t i = 0; i < stringCount; i++)
1302 {
1303 assert (strings[i]);
1304 lengths[i] = strlen (strings[i]);
1305 offset += lengths[i];
1306 }
1307 int offsetSize = 1 + (offset > 0xff)
1308 + (offset > 0xffff)
1309 + (offset > 0xffffff);
1310 cacheU16 (buf, stringCount); // count
1311 cacheU8 (buf, offsetSize); // offSize
1312 cacheU (buf, offset = 1, offsetSize); // offset[0]
1313 for (size_t i = 0; i < stringCount; i++)
1314 cacheU (buf, offset += lengths[i], offsetSize); // offset[i + 1]
1315 for (size_t i = 0; i < stringCount; i++)
1316 cacheBytes (buf, strings[i], lengths[i]);
1317 #undef stringCount
1318 return buf;
1319}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ printHelp()

void printHelp ( )

Print help message to stdout and then exit.

Print help message if invoked with the "--help" option, and then exit successfully.

Definition at line 2426 of file hex2otf.c.

2426 {
2427 printf ("Synopsis: hex2otf <options>:\n\n");
2428 printf (" hex=<filename> Specify Unifont .hex input file.\n");
2429 printf (" pos=<filename> Specify combining file. (Optional)\n");
2430 printf (" out=<filename> Specify output font file.\n");
2431 printf (" format=<f1>,<f2>,... Specify font format(s); values:\n");
2432 printf (" cff\n");
2433 printf (" cff2\n");
2434 printf (" truetype\n");
2435 printf (" blank\n");
2436 printf (" bitmap\n");
2437 printf (" gpos\n");
2438 printf (" gsub\n");
2439 printf ("\nExample:\n\n");
2440 printf (" hex2otf hex=Myfont.hex out=Myfont.otf format=cff\n\n");
2441 printf ("For more information, consult the hex2otf(1) man page.\n\n");
2442
2443 exit (EXIT_SUCCESS);
2444}
Here is the caller graph for this function:

◆ printVersion()

void printVersion ( )

Print program version string on stdout.

Print program version if invoked with the "--version" option, and then exit successfully.

Definition at line 2407 of file hex2otf.c.

2407 {
2408 printf ("hex2otf (GNU Unifont) %s\n", VERSION);
2409 printf ("Copyright \u00A9 2022 \u4F55\u5FD7\u7FD4 (He Zhixiang)\n");
2410 printf ("License GPLv2+: GNU GPL version 2 or later\n");
2411 printf ("<https://gnu.org/licenses/gpl.html>\n");
2412 printf ("This is free software: you are free to change and\n");
2413 printf ("redistribute it. There is NO WARRANTY, to the extent\n");
2414 printf ("permitted by law.\n");
2415
2416 exit (EXIT_SUCCESS);
2417}
#define VERSION
Program version, for "--version" option.
Definition: hex2otf.c:51
Here is the caller graph for this function:

◆ readCodePoint()

bool readCodePoint ( uint_fast32_t *  codePoint,
const char *  fileName,
FILE *  file 
)

Read up to 6 hexadecimal digits and a colon from file.

This function reads up to 6 hexadecimal digits followed by a colon from a file.

If the end of the file is reached, the function returns true. The file name is provided to include in an error message if the end of file was reached unexpectedly.

Parameters
[out]codePointThe Unicode code point.
[in]fileNameThe name of the input file.
[in]filePointer to the input file stream.
Returns
true if at end of file, false otherwise.

Definition at line 919 of file hex2otf.c.

920{
921 *codePoint = 0;
922 uint_fast8_t digitCount = 0;
923 for (;;)
924 {
925 int c = getc (file);
926 if (isxdigit (c) && ++digitCount <= 6)
927 {
928 *codePoint = (*codePoint << 4) | nibbleValue (c);
929 continue;
930 }
931 if (c == ':' && digitCount > 0)
932 return false;
933 if (c == EOF)
934 {
935 if (digitCount == 0)
936 return true;
937 if (feof (file))
938 fail ("%s: Unexpected end of file.", fileName);
939 else
940 fail ("%s: Read error.", fileName);
941 }
942 fail ("%s: Unexpected character: %#.2x.", fileName, (unsigned)c);
943 }
944}

◆ readGlyphs()

void readGlyphs ( Font font,
const char *  fileName 
)

Read glyph definitions from a Unifont .hex format file.

This function reads in the glyph bitmaps contained in a Unifont .hex format file. These input files contain one glyph bitmap per line. Each line is of the form

<hexadecimal code point> ':' <hexadecimal bitmap sequence>

The code point field typically consists of 4 hexadecimal digits for a code point in Unicode Plane 0, and 6 hexadecimal digits for code points above Plane 0. The hexadecimal bitmap sequence is 32 hexadecimal digits long for a glyph that is 8 pixels wide by 16 pixels high, and 64 hexadecimal digits long for a glyph that is 16 pixels wide by 16 pixels high.

Parameters
[in,out]fontThe font data structure to update with new glyphs.
[in]fileNameThe name of the Unifont .hex format input file.

Definition at line 966 of file hex2otf.c.

967{
968 FILE *file = fopen (fileName, "r");
969 if (!file)
970 fail ("Failed to open file '%s'.", fileName);
971 uint_fast32_t glyphCount = 1; // for glyph 0
972 uint_fast8_t maxByteCount = 0;
973 { // Hard code the .notdef glyph.
974 const byte bitmap[] = "\0\0\0~fZZzvv~vv~\0\0"; // same as U+FFFD
975 const size_t byteCount = sizeof bitmap - 1;
976 assert (byteCount <= GLYPH_MAX_BYTE_COUNT);
977 assert (byteCount % GLYPH_HEIGHT == 0);
978 Glyph *notdef = getBufferSlot (font->glyphs, sizeof (Glyph));
979 memcpy (notdef->bitmap, bitmap, byteCount);
980 notdef->byteCount = maxByteCount = byteCount;
981 notdef->combining = false;
982 notdef->pos = 0;
983 notdef->lsb = 0;
984 }
985 for (;;)
986 {
987 uint_fast32_t codePoint;
988 if (readCodePoint (&codePoint, fileName, file))
989 break;
990 if (++glyphCount > MAX_GLYPHS)
991 fail ("OpenType does not support more than %lu glyphs.",
992 MAX_GLYPHS);
993 Glyph *glyph = getBufferSlot (font->glyphs, sizeof (Glyph));
994 glyph->codePoint = codePoint;
995 glyph->byteCount = 0;
996 glyph->combining = false;
997 glyph->pos = 0;
998 glyph->lsb = 0;
999 for (byte *p = glyph->bitmap;; p++)
1000 {
1001 int h, l;
1002 if (isxdigit (h = getc (file)) && isxdigit (l = getc (file)))
1003 {
1004 if (++glyph->byteCount > GLYPH_MAX_BYTE_COUNT)
1005 fail ("Hex stream of "PRI_CP" is too long.", codePoint);
1006 *p = nibbleValue (h) << 4 | nibbleValue (l);
1007 }
1008 else if (h == '\n' || (h == EOF && feof (file)))
1009 break;
1010 else if (ferror (file))
1011 fail ("%s: Read error.", fileName);
1012 else
1013 fail ("Hex stream of "PRI_CP" is invalid.", codePoint);
1014 }
1015 if (glyph->byteCount % GLYPH_HEIGHT != 0)
1016 fail ("Hex length of "PRI_CP" is indivisible by glyph height %d.",
1017 codePoint, GLYPH_HEIGHT);
1018 if (glyph->byteCount > maxByteCount)
1019 maxByteCount = glyph->byteCount;
1020 }
1021 if (glyphCount == 1)
1022 fail ("No glyph is specified.");
1023 font->glyphCount = glyphCount;
1024 font->maxWidth = PW (maxByteCount);
1025 fclose (file);
1026}
#define GLYPH_MAX_BYTE_COUNT
Number of bytes to represent one bitmap glyph as a binary array.
Definition: hex2otf.c:73
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sortGlyphs()

void sortGlyphs ( Font font)

Sort the glyphs in a font by Unicode code point.

This function reads in an array of glyphs and sorts them by Unicode code point. If a duplicate code point is encountered, that will result in a fatal error with an error message to stderr.

Parameters
[in,out]fontPointer to a Font structure with glyphs to sort.

Definition at line 1119 of file hex2otf.c.

1120{
1121 Glyph *glyphs = getBufferHead (font->glyphs);
1122 const Glyph *const glyphsEnd = getBufferTail (font->glyphs);
1123 glyphs++; // glyph 0 does not need sorting
1124 qsort (glyphs, glyphsEnd - glyphs, sizeof *glyphs, byCodePoint);
1125 for (const Glyph *glyph = glyphs; glyph < glyphsEnd - 1; glyph++)
1126 {
1127 if (glyph[0].codePoint == glyph[1].codePoint)
1128 fail ("Duplicate code point: "PRI_CP".", glyph[0].codePoint);
1129 assert (glyph[0].codePoint < glyph[1].codePoint);
1130 }
1131}
Here is the caller graph for this function:

◆ writeBytes()

void writeBytes ( const byte  bytes[],
size_t  count,
FILE *  file 
)

Write an array of bytes to an output file.

Parameters
[in]bytesAn array of unsigned bytes to write.
[in]fileThe file pointer for writing, of type FILE *.

Definition at line 538 of file hex2otf.c.

539{
540 if (fwrite (bytes, count, 1, file) != 1 && count != 0)
541 fail ("Failed to write %zu bytes to output file.", count);
542}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ writeFont()

void writeFont ( Font font,
bool  isCFF,
const char *  fileName 
)

Write OpenType font to output file.

This function writes the constructed OpenType font to the output file named "filename".

Parameters
[in]fontPointer to the font, of type Font *.
[in]isCFFBoolean indicating whether the font has CFF data.
[in]filenameThe name of the font file to create.

Add a byte shifted by 24, 16, 8, or 0 bits.

Definition at line 786 of file hex2otf.c.

787{
788 FILE *file = fopen (fileName, "wb");
789 if (!file)
790 fail ("Failed to open file '%s'.", fileName);
791 const Table *const tables = getBufferHead (font->tables);
792 const Table *const tablesEnd = getBufferTail (font->tables);
793 size_t tableCount = tablesEnd - tables;
794 assert (0 < tableCount && tableCount <= U16MAX);
795 size_t offset = 12 + 16 * tableCount;
796 uint_fast32_t totalChecksum = 0;
797 Buffer *tableRecords =
798 newBuffer (sizeof (struct TableRecord) * tableCount);
799 for (size_t i = 0; i < tableCount; i++)
800 {
801 struct TableRecord *record =
802 getBufferSlot (tableRecords, sizeof *record);
803 record->tag = tables[i].tag;
804 size_t length = countBufferedBytes (tables[i].content);
805 #if SIZE_MAX > U32MAX
806 if (offset > U32MAX)
807 fail ("Table offset exceeded 4 GiB.");
808 if (length > U32MAX)
809 fail ("Table size exceeded 4 GiB.");
810 #endif
811 record->length = length;
812 record->checksum = 0;
813 const byte *p = getBufferHead (tables[i].content);
814 const byte *const end = getBufferTail (tables[i].content);
815
816 /// Add a byte shifted by 24, 16, 8, or 0 bits.
817 #define addByte(shift) \
818 if (p == end) \
819 break; \
820 record->checksum += (uint_fast32_t)*p++ << (shift);
821
822 for (;;)
823 {
824 addByte (24)
825 addByte (16)
826 addByte (8)
827 addByte (0)
828 }
829 #undef addByte
830 cacheZeros (tables[i].content, (~length + 1U) & 3U);
831 record->offset = offset;
832 offset += countBufferedBytes (tables[i].content);
833 totalChecksum += record->checksum;
834 }
835 struct TableRecord *records = getBufferHead (tableRecords);
836 qsort (records, tableCount, sizeof *records, byTableTag);
837 // Offset Table
838 uint_fast32_t sfntVersion = isCFF ? 0x4f54544f : 0x00010000;
839 writeU32 (sfntVersion, file); // sfntVersion
840 totalChecksum += sfntVersion;
841 uint_fast16_t entrySelector = 0;
842 for (size_t k = tableCount; k != 1; k >>= 1)
843 entrySelector++;
844 uint_fast16_t searchRange = 1 << (entrySelector + 4);
845 uint_fast16_t rangeShift = (tableCount - (1 << entrySelector)) << 4;
846 writeU16 (tableCount, file); // numTables
847 writeU16 (searchRange, file); // searchRange
848 writeU16 (entrySelector, file); // entrySelector
849 writeU16 (rangeShift, file); // rangeShift
850 totalChecksum += (uint_fast32_t)tableCount << 16;
851 totalChecksum += searchRange;
852 totalChecksum += (uint_fast32_t)entrySelector << 16;
853 totalChecksum += rangeShift;
854 // Table Records (always sorted by table tags)
855 for (size_t i = 0; i < tableCount; i++)
856 {
857 // Table Record
858 writeU32 (records[i].tag, file); // tableTag
859 writeU32 (records[i].checksum, file); // checkSum
860 writeU32 (records[i].offset, file); // offset
861 writeU32 (records[i].length, file); // length
862 totalChecksum += records[i].tag;
863 totalChecksum += records[i].checksum;
864 totalChecksum += records[i].offset;
865 totalChecksum += records[i].length;
866 }
867 freeBuffer (tableRecords);
868 for (const Table *table = tables; table < tablesEnd; table++)
869 {
870 if (table->tag == 0x68656164) // 'head' table
871 {
872 byte *begin = getBufferHead (table->content);
873 byte *end = getBufferTail (table->content);
874 writeBytes (begin, 8, file);
875 writeU32 (0xb1b0afbaU - totalChecksum, file); // checksumAdjustment
876 writeBytes (begin + 12, end - (begin + 12), file);
877 continue;
878 }
879 writeBuffer (table->content, file);
880 }
881 fclose (file);
882}
void writeU16(uint_fast16_t value, FILE *file)
Write an unsigned 16-bit value to an output file.
Definition: hex2otf.c:554
void writeU32(uint_fast32_t value, FILE *file)
Write an unsigned 32-bit value to an output file.
Definition: hex2otf.c:574
void writeBytes(const byte bytes[], size_t count, FILE *file)
Write an array of bytes to an output file.
Definition: hex2otf.c:538
int byTableTag(const void *a, const void *b)
Compare tables by 4-byte unsigned table tag value.
Definition: hex2otf.c:767
Here is the call graph for this function:
Here is the caller graph for this function:

◆ writeU16()

void writeU16 ( uint_fast16_t  value,
FILE *  file 
)

Write an unsigned 16-bit value to an output file.

This function writes a 16-bit unsigned value in big-endian order to an output file specified with a file pointer.

Parameters
[in]valueThe 16-bit value to write.
[in]fileThe file pointer for writing, of type FILE *.

Definition at line 554 of file hex2otf.c.

555{
556 byte bytes[] =
557 {
558 (value >> 8) & 0xff,
559 (value ) & 0xff,
560 };
561 writeBytes (bytes, sizeof bytes, file);
562}
Here is the call graph for this function:

◆ writeU32()

void writeU32 ( uint_fast32_t  value,
FILE *  file 
)

Write an unsigned 32-bit value to an output file.

This function writes a 32-bit unsigned value in big-endian order to an output file specified with a file pointer.

Parameters
[in]valueThe 32-bit value to write.
[in]fileThe file pointer for writing, of type FILE *.

Definition at line 574 of file hex2otf.c.

575{
576 byte bytes[] =
577 {
578 (value >> 24) & 0xff,
579 (value >> 16) & 0xff,
580 (value >> 8) & 0xff,
581 (value ) & 0xff,
582 };
583 writeBytes (bytes, sizeof bytes, file);
584}
Here is the call graph for this function:

Variable Documentation

◆ allBuffers

Buffer* allBuffers

Initial allocation of empty array of buffer pointers.

Definition at line 139 of file hex2otf.c.

◆ bufferCount

size_t bufferCount

Number of buffers in a Buffer * array.

Definition at line 140 of file hex2otf.c.

◆ nextBufferIndex

size_t nextBufferIndex

Index number to tail element of Buffer * array.

Definition at line 141 of file hex2otf.c.