GNU Unifont  15.0.04
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.
 
#define U16MAX   0xffff
 Maximum UTF-16 code point value.
 
#define U32MAX   0xffffffff
 Maximum UTF-32 code point value.
 
#define PRI_CP   "U+%.4"PRIXFAST32
 Format string to print Unicode code point.
 
#define static_assert(a, b)   (assert(a))
 If "a" is true, return string "b".
 
#define BX(shift, x)   ((uintmax_t)(!!(x)) << (shift))
 Truncate & shift word.
 
#define B0(shift)   BX((shift), 0)
 Clear a given bit in a word.
 
#define B1(shift)   BX((shift), 1)
 Set a given bit in a word.
 
#define GLYPH_MAX_WIDTH   16
 Maximum glyph width, in pixels.
 
#define GLYPH_HEIGHT   16
 Maximum glyph height, in pixels.
 
#define GLYPH_MAX_BYTE_COUNT   (GLYPH_HEIGHT * GLYPH_MAX_WIDTH / 8)
 Number of bytes to represent one bitmap glyph as a binary array.
 
#define DESCENDER   2
 Count of pixels below baseline.
 
#define ASCENDER   (GLYPH_HEIGHT - DESCENDER)
 Count of pixels above baseline.
 
#define FUPEM   64
 Font units per em.
 
#define MAX_GLYPHS   65536
 An OpenType font has at most 65536 glyphs.
 
#define MAX_NAME_IDS   256
 Name IDs 0-255 are used for standard names.
 
#define FU(x)   ((x) * FUPEM / GLYPH_HEIGHT)
 Convert pixels to font units.
 
#define PW(x)   ((x) / (GLYPH_HEIGHT / 8))
 Convert glyph byte count to pixel width.
 
#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.
 
typedef int_least8_t pixels_t
 This type must be able to represent max(GLYPH_MAX_WIDTH, GLYPH_HEIGHT).
 
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.
 
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.
 
size_t bufferCount
 Number of buffers in a Buffer * array.
 
size_t nextBufferIndex
 Index number to tail element of Buffer * array.
 

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);

◆ defineStore

#define defineStore (   name,
  type 
)
Value:
void name (Buffer *buf, type value) \
{ \
type *slot = getBufferSlot (buf, sizeof value); \
*slot = value; \
}

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.

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.

◆ 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.

◆ 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.

◆ 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 };

◆ 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 };

◆ 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 };

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 }
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 }

◆ 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 }

◆ 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 }

◆ 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 }

◆ 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 }
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 }
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 }
Here is the caller graph for this function:

◆ 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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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:
fillGposTable
void fillGposTable(Font *font)
Fill a "GPOS" font table.
Definition: hex2otf.c:2241
Glyph::combining
bool combining
whether this is a combining glyph
Definition: hex2otf.c:619
readGlyphs
void readGlyphs(Font *font, const char *fileName)
Read glyph definitions from a Unifont .hex format file.
Definition: hex2otf.c:966
BX
#define BX(shift, x)
Truncate & shift word.
Definition: hex2otf.c:65
writeU16
void writeU16(uint_fast16_t value, FILE *file)
Write an unsigned 16-bit value to an output file.
Definition: hex2otf.c:554
fillGsubTable
void fillGsubTable(Font *font)
Fill a "GSUB" font table.
Definition: hex2otf.c:2269
static_assert
#define static_assert(a, b)
If "a" is true, return string "b".
Definition: hex2otf.c:61
MAX_NAME_IDS
#define MAX_NAME_IDS
Name IDs 0-255 are used for standard names.
Definition: hex2otf.c:88
FILL_LEFT
@ FILL_LEFT
Draw outline counter-clockwise (CFF, PostScript).
Definition: hex2otf.c:1145
fillCmapTable
void fillCmapTable(Font *font)
Fill a "cmap" font table.
Definition: hex2otf.c:2109
fillHeadTable
void fillHeadTable(Font *font, enum LocaFormat locaFormat, pixels_t xMin)
Fill a "head" font table.
Definition: hex2otf.c:1853
freeBuffer
void freeBuffer(Buffer *buf)
Free the memory previously allocated for a buffer.
Definition: hex2otf.c:337
fillOS2Table
void fillOS2Table(Font *font)
Fill an "OS/2" font table.
Definition: hex2otf.c:1986
organizeTables
void organizeTables(Font *font, bool isCFF)
Sort tables according to OpenType recommendations.
Definition: hex2otf.c:711
Buffer
Generic data structure for a linked list of buffer elements.
Definition: hex2otf.c:134
PW
#define PW(x)
Convert glyph byte count to pixel width.
Definition: hex2otf.c:94
cacheCFFOperand
void cacheCFFOperand(Buffer *buf, int_fast32_t value)
Cache charstring number encoding in a CFF buffer.
Definition: hex2otf.c:460
byTableTag
int byTableTag(const void *a, const void *b)
Compare tables by 4-byte unsigned table tag value.
Definition: hex2otf.c:767
cleanBuffers
void cleanBuffers()
Free all allocated buffer pointers.
Definition: hex2otf.c:170
VERSION
#define VERSION
Program version, for "--version" option.
Definition: hex2otf.c:51
fillNameTable
void fillNameTable(Font *font, NameStrings nameStrings)
Fill a "name" font table.
Definition: hex2otf.c:2366
GLYPH_MAX_BYTE_COUNT
#define GLYPH_MAX_BYTE_COUNT
Number of bytes to represent one bitmap glyph as a binary array.
Definition: hex2otf.c:73
FUPEM
#define FUPEM
Font units per em.
Definition: hex2otf.c:82
newBuffer
Buffer * newBuffer(size_t initialCapacity)
Create a new buffer.
Definition: hex2otf.c:188
byCodePoint
int byCodePoint(const void *a, const void *b)
Compare two Unicode code points to determine which is greater.
Definition: hex2otf.c:1040
MAX_GLYPHS
#define MAX_GLYPHS
An OpenType font has at most 65536 glyphs.
Definition: hex2otf.c:85
writeBytes
void writeBytes(const byte bytes[], size_t count, FILE *file)
Write an array of bytes to an output file.
Definition: hex2otf.c:538
Glyph::pos
pixels_t pos
Definition: hex2otf.c:620
NamePair
Data structure for a font ID number and name character string.
Definition: hex2otf.h:78
parseOptions
Options parseOptions(char *const argv[const])
Parse command line options.
Definition: hex2otf.c:2500
LOCA_OFFSET32
@ LOCA_OFFSET32
Offset to location is a 32-bit Offset32 value.
Definition: hex2otf.c:660
B0
#define B0(shift)
Clear a given bit in a word.
Definition: hex2otf.c:66
GLYPH_HEIGHT
#define GLYPH_HEIGHT
Maximum glyph height, in pixels.
Definition: hex2otf.c:70
prepareStringIndex
Buffer * prepareStringIndex(const NameStrings names)
Prepare a font name string index.
Definition: hex2otf.c:1291
cacheU32
void cacheU32(Buffer *buf, uint_fast32_t value)
Append four unsigned bytes to the end of a byte array.
Definition: hex2otf.c:427
fillBitmap
void fillBitmap(Font *font)
Fill OpenType bitmap data and location tables.
Definition: hex2otf.c:1728
Glyph::codePoint
uint_least32_t codePoint
undefined for glyph 0
Definition: hex2otf.c:616
addTable
void addTable(Font *font, const char tag[static 4], Buffer *content)
Add a TrueType or OpenType table to the font.
Definition: hex2otf.c:694
Font
Data structure to hold information for one font.
Definition: hex2otf.c:629
Options
Data structure to hold options for OpenType font output.
Definition: hex2otf.c:2454
matchToken
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
positionGlyphs
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
FU
#define FU(x)
Convert pixels to font units.
Definition: hex2otf.c:91
Glyph
Data structure to hold data for one bitmap glyph.
Definition: hex2otf.c:615
sortGlyphs
void sortGlyphs(Font *font)
Sort the glyphs in a font by Unicode code point.
Definition: hex2otf.c:1119
fillTrueType
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
LOCA_OFFSET16
@ LOCA_OFFSET16
Offset to location is a 16-bit Offset16 value.
Definition: hex2otf.c:659
buildOutline
void buildOutline(Buffer *result, const byte bitmap[], const size_t byteCount, const enum FillSide fillSide)
Build a glyph outline.
Definition: hex2otf.c:1160
cacheZeros
void cacheZeros(Buffer *buf, size_t count)
Append 1 to 4 bytes of zeroes to a buffer, for padding.
Definition: hex2otf.c:491
Glyph::byteCount
uint_least8_t byteCount
length of bitmap data
Definition: hex2otf.c:618
prepareOffsets
void prepareOffsets(size_t *sizes)
Prepare 32-bit glyph offsets in a font table.
Definition: hex2otf.c:1275
pixels_t
int_least8_t pixels_t
This type must be able to represent max(GLYPH_MAX_WIDTH, GLYPH_HEIGHT).
Definition: hex2otf.c:100
initBuffers
void initBuffers(size_t count)
Initialize an array of buffer pointers to all zeroes.
Definition: hex2otf.c:152
ASCENDER
#define ASCENDER
Count of pixels above baseline.
Definition: hex2otf.c:79
PRI_CP
#define PRI_CP
Format string to print Unicode code point.
Definition: hex2otf.c:58
nextBufferIndex
size_t nextBufferIndex
Index number to tail element of Buffer * array.
Definition: hex2otf.c:141
allBuffers
Buffer * allBuffers
Initial allocation of empty array of buffer pointers.
Definition: hex2otf.c:139
fillBlankOutline
void fillBlankOutline(Font *font)
Create a dummy blank outline in a font table.
Definition: hex2otf.c:1697
U32MAX
#define U32MAX
Maximum UTF-32 code point value.
Definition: hex2otf.c:56
Glyph::lsb
pixels_t lsb
left side bearing (x position of leftmost contour point)
Definition: hex2otf.c:622
cacheBytes
void cacheBytes(Buffer *restrict buf, const void *restrict src, size_t count)
Append a string of bytes to a buffer.
Definition: hex2otf.c:509
writeU32
void writeU32(uint_fast32_t value, FILE *file)
Write an unsigned 32-bit value to an output file.
Definition: hex2otf.c:574
LocaFormat
LocaFormat
Index to Location ("loca") offset information.
Definition: hex2otf.c:658
printVersion
void printVersion()
Print program version string on stdout.
Definition: hex2otf.c:2407
ensureBuffer
void ensureBuffer(Buffer *buf, size_t needed)
Ensure that the buffer has at least the specified minimum size.
Definition: hex2otf.c:239
fillMaxpTable
void fillMaxpTable(Font *font, bool isCFF, uint_fast16_t maxPoints, uint_fast16_t maxContours)
Fill a "maxp" font table.
Definition: hex2otf.c:1954
TableRecord
Data structure for data associated with one OpenType table.
Definition: hex2otf.c:748
FILL_RIGHT
@ FILL_RIGHT
Draw outline clockwise (TrueType).
Definition: hex2otf.c:1146
B1
#define B1(shift)
Set a given bit in a word.
Definition: hex2otf.c:67
U16MAX
#define U16MAX
Maximum UTF-16 code point value.
Definition: hex2otf.c:55
fail
void fail(const char *reason,...)
Print an error message on stderr, then exit.
Definition: hex2otf.c:113
fillCFF
void fillCFF(Font *font, int version, const NameStrings names)
Add a CFF table to a font.
Definition: hex2otf.c:1329
bufferCount
size_t bufferCount
Number of buffers in a Buffer * array.
Definition: hex2otf.c:140
ContourOp
ContourOp
Specify the current contour drawing operation.
Definition: hex2otf.c:1136
defaultNames
const NamePair defaultNames[]
Allocate array of NameID codes with default values.
Definition: hex2otf.h:93
cacheU16
void cacheU16(Buffer *buf, uint_fast16_t value)
Append two unsigned bytes to the end of a byte array.
Definition: hex2otf.c:412
fillHmtxTable
void fillHmtxTable(Font *font)
Fill an "hmtx" font table.
Definition: hex2otf.c:2087
fillHheaTable
void fillHheaTable(Font *font, pixels_t xMin)
Fill a "hhea" font table.
Definition: hex2otf.c:1918
fillPostTable
void fillPostTable(Font *font)
Fill a "post" font table.
Definition: hex2otf.c:2218
cacheStringAsUTF16BE
void cacheStringAsUTF16BE(Buffer *buf, const char *str)
Cache a string as a big-ending UTF-16 surrogate pair.
Definition: hex2otf.c:2316
cacheBuffer
void cacheBuffer(Buffer *restrict bufDest, const Buffer *restrict bufSrc)
Append bytes of a table to a byte buffer.
Definition: hex2otf.c:523
writeFont
void writeFont(Font *font, bool isCFF, const char *fileName)
Write OpenType font to output file.
Definition: hex2otf.c:786
OP_POINT
@ OP_POINT
Add one more (x,y) point to the contor being drawn.
Definition: hex2otf.c:1138
Glyph::bitmap
byte bitmap[GLYPH_MAX_BYTE_COUNT]
hexadecimal bitmap character array
Definition: hex2otf.c:617
cacheU8
void cacheU8(Buffer *buf, uint_fast8_t value)
Append one unsigned byte to the end of a byte array.
Definition: hex2otf.c:397
GLYPH_MAX_WIDTH
#define GLYPH_MAX_WIDTH
Maximum glyph width, in pixels.
Definition: hex2otf.c:69
OP_CLOSE
@ OP_CLOSE
Close the current contour path that was being drawn.
Definition: hex2otf.c:1137
Buffer
struct Buffer Buffer
Generic data structure for a linked list of buffer elements.
DESCENDER
#define DESCENDER
Count of pixels below baseline.
Definition: hex2otf.c:76
Table
Data structure for an OpenType table.
Definition: hex2otf.c:646
printHelp
void printHelp()
Print help message to stdout and then exit.
Definition: hex2otf.c:2426
readCodePoint
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