GNU Unifont  15.0.05
Pan-Unicode font with complete Unicode Plane 0 coverage and partial coverage of higher planes
hex2otf.c
Go to the documentation of this file.
1 /**
2  @file hex2otf.c
3 
4  @brief hex2otf - Convert GNU Unifont .hex file to OpenType font
5 
6  This program reads a Unifont .hex format file and a file containing
7  combining mark offset information, and produces an OpenType font file.
8 
9  @copyright Copyright © 2022 何志翔 (He Zhixiang)
10 
11  @author 何志翔 (He Zhixiang)
12 */
13 
14 /*
15  LICENSE:
16 
17  This program is free software; you can redistribute it and/or
18  modify it under the terms of the GNU General Public License
19  as published by the Free Software Foundation; either version 2
20  of the License, or (at your option) any later version.
21 
22  This program is distributed in the hope that it will be useful,
23  but WITHOUT ANY WARRANTY; without even the implied warranty of
24  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  GNU General Public License for more details.
26 
27  You should have received a copy of the GNU General Public License
28  along with this program; if not, write to the Free Software
29  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30  02110-1301, USA.
31 
32  NOTE: It is a violation of the license terms of this software
33  to delete or override license and copyright information contained
34  in the hex2otf.h file if creating a font derived from Unifont glyphs.
35  Fonts derived from Unifont can add names to the copyright notice
36  for creators of new or modified glyphs.
37 */
38 
39 #include <assert.h>
40 #include <ctype.h>
41 #include <inttypes.h>
42 #include <stdarg.h>
43 #include <stdbool.h>
44 #include <stddef.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 
49 #include "hex2otf.h"
50 
51 #define VERSION "1.0.1" ///< Program version, for "--version" option.
52 
53 // This program assumes the execution character set is compatible with ASCII.
54 
55 #define U16MAX 0xffff ///< Maximum UTF-16 code point value.
56 #define U32MAX 0xffffffff ///< Maximum UTF-32 code point value.
57 
58 #define PRI_CP "U+%.4"PRIXFAST32 ///< Format string to print Unicode code point.
59 
60 #ifndef static_assert
61 #define static_assert(a, b) (assert(a)) ///< If "a" is true, return string "b".
62 #endif
63 
64 // Set or clear a particular bit.
65 #define BX(shift, x) ((uintmax_t)(!!(x)) << (shift)) ///< Truncate & shift word.
66 #define B0(shift) BX((shift), 0) ///< Clear a given bit in a word.
67 #define B1(shift) BX((shift), 1) ///< Set a given bit in a word.
68 
69 #define GLYPH_MAX_WIDTH 16 ///< Maximum glyph width, in pixels.
70 #define GLYPH_HEIGHT 16 ///< Maximum glyph height, in pixels.
71 
72 /// Number of bytes to represent one bitmap glyph as a binary array.
73 #define GLYPH_MAX_BYTE_COUNT (GLYPH_HEIGHT * GLYPH_MAX_WIDTH / 8)
74 
75 /// Count of pixels below baseline.
76 #define DESCENDER 2
77 
78 /// Count of pixels above baseline.
79 #define ASCENDER (GLYPH_HEIGHT - DESCENDER)
80 
81 /// Font units per em.
82 #define FUPEM 64
83 
84 /// An OpenType font has at most 65536 glyphs.
85 #define MAX_GLYPHS 65536
86 
87 /// Name IDs 0-255 are used for standard names.
88 #define MAX_NAME_IDS 256
89 
90 /// Convert pixels to font units.
91 #define FU(x) ((x) * FUPEM / GLYPH_HEIGHT)
92 
93 /// Convert glyph byte count to pixel width.
94 #define PW(x) ((x) / (GLYPH_HEIGHT / 8))
95 
96 /// Definition of "byte" type as an unsigned char.
97 typedef unsigned char byte;
98 
99 /// This type must be able to represent max(GLYPH_MAX_WIDTH, GLYPH_HEIGHT).
100 typedef int_least8_t pixels_t;
101 
102 /**
103  @brief Print an error message on stderr, then exit.
104 
105  This function prints the provided error string and optional
106  following arguments to stderr, and then exits with a status
107  of EXIT_FAILURE.
108 
109  @param[in] reason The output string to describe the error.
110  @param[in] ... Optional following arguments to output.
111 */
112 void
113 fail (const char *reason, ...)
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 }
123 
124 /**
125  @brief Generic data structure for a linked list of buffer elements.
126 
127  A buffer can act as a vector (when filled with 'store*' functions),
128  or a temporary output area (when filled with 'cache*' functions).
129  The 'store*' functions use native endian.
130  The 'cache*' functions use big endian or other formats in OpenType.
131  Beware of memory alignment.
132 */
133 typedef struct Buffer
134 {
135  size_t capacity; // = 0 iff this buffer is free
136  byte *begin, *next, *end;
138 
139 Buffer *allBuffers; ///< Initial allocation of empty array of buffer pointers.
140 size_t bufferCount; ///< Number of buffers in a Buffer * array.
141 size_t nextBufferIndex; ///< Index number to tail element of Buffer * array.
142 
143 /**
144  @brief Initialize an array of buffer pointers to all zeroes.
145 
146  This function initializes the "allBuffers" array of buffer
147  pointers to all zeroes.
148 
149  @param[in] count The number of buffer array pointers to allocate.
150 */
151 void
152 initBuffers (size_t count)
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 }
162 
163 /**
164  @brief Free all allocated buffer pointers.
165 
166  This function frees all buffer pointers previously allocated
167  in the initBuffers function.
168 */
169 void
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 }
178 
179 /**
180  @brief Create a new buffer.
181 
182  This function creates a new buffer array of type Buffer,
183  with an initial size of initialCapacity elements.
184 
185  @param[in] initialCapacity The initial number of elements in the buffer.
186 */
187 Buffer *
188 newBuffer (size_t initialCapacity)
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 }
223 
224 /**
225  @brief Ensure that the buffer has at least the specified minimum size.
226 
227  This function takes a buffer array of type Buffer and the
228  necessary minimum number of elements as inputs, and attempts
229  to increase the size of the buffer if it must be larger.
230 
231  If the buffer is too small and cannot be resized, the program
232  will terminate with an error message and an exit status of
233  EXIT_FAILURE.
234 
235  @param[in,out] buf The buffer to check.
236  @param[in] needed The required minimum number of elements in the buffer.
237 */
238 void
239 ensureBuffer (Buffer *buf, size_t needed)
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 }
258 
259 /**
260  @brief Count the number of elements in a buffer.
261 
262  @param[in] buf The buffer to be examined.
263  @return The number of elements in the buffer.
264 */
265 static inline size_t
266 countBufferedBytes (const Buffer *buf)
267 {
268  return buf->next - buf->begin;
269 }
270 
271 /**
272  @brief Get the start of the buffer array.
273 
274  @param[in] buf The buffer to be examined.
275  @return A pointer of type Buffer * to the start of the buffer.
276 */
277 static inline void *
278 getBufferHead (const Buffer *buf)
279 {
280  return buf->begin;
281 }
282 
283 /**
284  @brief Get the end of the buffer array.
285 
286  @param[in] buf The buffer to be examined.
287  @return A pointer of type Buffer * to the end of the buffer.
288 */
289 static inline void *
290 getBufferTail (const Buffer *buf)
291 {
292  return buf->next;
293 }
294 
295 /**
296  @brief Add a slot to the end of a buffer.
297 
298  This function ensures that the buffer can grow by one slot,
299  and then returns a pointer to the new slot within the buffer.
300 
301  @param[in] buf The pointer to an array of type Buffer *.
302  @param[in] slotSize The new slot number.
303  @return A pointer to the new slot within the buffer.
304 */
305 static inline void *
306 getBufferSlot (Buffer *buf, size_t slotSize)
307 {
308  ensureBuffer (buf, slotSize);
309  void *slot = buf->next;
310  buf->next += slotSize;
311  return slot;
312 }
313 
314 /**
315  @brief Reset a buffer pointer to the buffer's beginning.
316 
317  This function resets an array of type Buffer * to point
318  its tail to the start of the array.
319 
320  @param[in] buf The pointer to an array of type Buffer *.
321 */
322 static inline void
323 resetBuffer (Buffer *buf)
324 {
325  buf->next = buf->begin;
326 }
327 
328 /**
329  @brief Free the memory previously allocated for a buffer.
330 
331  This function frees the memory allocated to an array
332  of type Buffer *.
333 
334  @param[in] buf The pointer to an array of type Buffer *.
335 */
336 void
338 {
339  free (buf->begin);
340  buf->capacity = 0;
341 }
342 
343 /**
344  @brief Temporary define to look up an element in an array of given type.
345 
346  This defintion is used to create lookup functions to return
347  a given element in unsigned arrays of size 8, 16, and 32 bytes,
348  and in an array of pixels.
349 */
350 #define defineStore(name, type) \
351 void name (Buffer *buf, type value) \
352 { \
353  type *slot = getBufferSlot (buf, sizeof value); \
354  *slot = value; \
355 }
356 defineStore (storeU8, uint_least8_t)
357 defineStore (storeU16, uint_least16_t)
358 defineStore (storeU32, uint_least32_t)
359 defineStore (storePixels, pixels_t)
360 #undef defineStore
361 
362 /**
363  @brief Cache bytes in a big-endian format.
364 
365  This function adds from 1, 2, 3, or 4 bytes to the end of
366  a byte array in big-endian order. The buffer is updated
367  to account for the newly-added bytes.
368 
369  @param[in,out] buf The array of bytes to which to append new bytes.
370  @param[in] value The bytes to add, passed as a 32-bit unsigned word.
371  @param[in] bytes The number of bytes to append to the buffer.
372 */
373 void
374 cacheU (Buffer *buf, uint_fast32_t value, int bytes)
375 {
376  assert (1 <= bytes && bytes <= 4);
377  ensureBuffer (buf, bytes);
378  switch (bytes)
379  {
380  case 4: *buf->next++ = value >> 24 & 0xff; // fall through
381  case 3: *buf->next++ = value >> 16 & 0xff; // fall through
382  case 2: *buf->next++ = value >> 8 & 0xff; // fall through
383  case 1: *buf->next++ = value & 0xff;
384  }
385 }
386 
387 /**
388  @brief Append one unsigned byte to the end of a byte array.
389 
390  This function adds one byte to the end of a byte array.
391  The buffer is updated to account for the newly-added byte.
392 
393  @param[in,out] buf The array of bytes to which to append a new byte.
394  @param[in] value The 8-bit unsigned value to append to the buf array.
395 */
396 void
397 cacheU8 (Buffer *buf, uint_fast8_t value)
398 {
399  storeU8 (buf, value & 0xff);
400 }
401 
402 /**
403  @brief Append two unsigned bytes to the end of a byte array.
404 
405  This function adds two bytes to the end of a byte array.
406  The buffer is updated to account for the newly-added bytes.
407 
408  @param[in,out] buf The array of bytes to which to append two new bytes.
409  @param[in] value The 16-bit unsigned value to append to the buf array.
410 */
411 void
412 cacheU16 (Buffer *buf, uint_fast16_t value)
413 {
414  cacheU (buf, value, 2);
415 }
416 
417 /**
418  @brief Append four unsigned bytes to the end of a byte array.
419 
420  This function adds four bytes to the end of a byte array.
421  The buffer is updated to account for the newly-added bytes.
422 
423  @param[in,out] buf The array of bytes to which to append four new bytes.
424  @param[in] value The 32-bit unsigned value to append to the buf array.
425 */
426 void
427 cacheU32 (Buffer *buf, uint_fast32_t value)
428 {
429  cacheU (buf, value, 4);
430 }
431 
432 /**
433  @brief Cache charstring number encoding in a CFF buffer.
434 
435  This function caches two's complement 8-, 16-, and 32-bit
436  words as per Adobe's Type 2 Charstring encoding for operands.
437  These operands are used in Compact Font Format data structures.
438 
439  Byte values can have offsets, for which this function
440  compensates, optionally followed by additional bytes:
441 
442  Byte Range Offset Bytes Adjusted Range
443  ---------- ------ ----- --------------
444  0 to 11 0 1 0 to 11 (operators)
445  12 0 2 Next byte is 8-bit op code
446  13 to 18 0 1 13 to 18 (operators)
447  19 to 20 0 2+ hintmask and cntrmask operators
448  21 to 27 0 1 21 to 27 (operators)
449  28 0 3 16-bit 2's complement number
450  29 to 31 0 1 29 to 31 (operators)
451  32 to 246 -139 1 -107 to +107
452  247 to 250 +108 2 +108 to +1131
453  251 to 254 -108 2 -108 to -1131
454  255 0 5 16-bit integer and 16-bit fraction
455 
456  @param[in,out] buf The buffer to which the operand value is appended.
457  @param[in] value The operand value.
458 */
459 void
460 cacheCFFOperand (Buffer *buf, int_fast32_t value)
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 }
483 
484 /**
485  @brief Append 1 to 4 bytes of zeroes to a buffer, for padding.
486 
487  @param[in,out] buf The buffer to which the operand value is appended.
488  @param[in] count The number of bytes containing zeroes to append.
489 */
490 void
491 cacheZeros (Buffer *buf, size_t count)
492 {
493  ensureBuffer (buf, count);
494  memset (buf->next, 0, count);
495  buf->next += count;
496 }
497 
498 /**
499  @brief Append a string of bytes to a buffer.
500 
501  This function appends an array of 1 to 4 bytes to the end of
502  a buffer.
503 
504  @param[in,out] buf The buffer to which the bytes are appended.
505  @param[in] src The array of bytes to append to the buffer.
506  @param[in] count The number of bytes containing zeroes to append.
507 */
508 void
509 cacheBytes (Buffer *restrict buf, const void *restrict src, size_t count)
510 {
511  ensureBuffer (buf, count);
512  memcpy (buf->next, src, count);
513  buf->next += count;
514 }
515 
516 /**
517  @brief Append bytes of a table to a byte buffer.
518 
519  @param[in,out] bufDest The buffer to which the new bytes are appended.
520  @param[in] bufSrc The bytes to append to the buffer array.
521 */
522 void
523 cacheBuffer (Buffer *restrict bufDest, const Buffer *restrict bufSrc)
524 {
525  size_t length = countBufferedBytes (bufSrc);
526  ensureBuffer (bufDest, length);
527  memcpy (bufDest->next, bufSrc->begin, length);
528  bufDest->next += length;
529 }
530 
531 /**
532  @brief Write an array of bytes to an output file.
533 
534  @param[in] bytes An array of unsigned bytes to write.
535  @param[in] file The file pointer for writing, of type FILE *.
536 */
537 void
538 writeBytes (const byte bytes[], size_t count, FILE *file)
539 {
540  if (fwrite (bytes, count, 1, file) != 1 && count != 0)
541  fail ("Failed to write %zu bytes to output file.", count);
542 }
543 
544 /**
545  @brief Write an unsigned 16-bit value to an output file.
546 
547  This function writes a 16-bit unsigned value in big-endian order
548  to an output file specified with a file pointer.
549 
550  @param[in] value The 16-bit value to write.
551  @param[in] file The file pointer for writing, of type FILE *.
552 */
553 void
554 writeU16 (uint_fast16_t value, FILE *file)
555 {
556  byte bytes[] =
557  {
558  (value >> 8) & 0xff,
559  (value ) & 0xff,
560  };
561  writeBytes (bytes, sizeof bytes, file);
562 }
563 
564 /**
565  @brief Write an unsigned 32-bit value to an output file.
566 
567  This function writes a 32-bit unsigned value in big-endian order
568  to an output file specified with a file pointer.
569 
570  @param[in] value The 32-bit value to write.
571  @param[in] file The file pointer for writing, of type FILE *.
572 */
573 void
574 writeU32 (uint_fast32_t value, FILE *file)
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 }
585 
586 /**
587  @brief Write an entire buffer array of bytes to an output file.
588 
589  This function determines the size of a buffer of bytes and
590  writes that number of bytes to an output file specified with
591  a file pointer. The number of bytes is determined from the
592  length information stored as part of the Buffer * data structure.
593 
594  @param[in] buf An array containing unsigned bytes to write.
595  @param[in] file The file pointer for writing, of type FILE *.
596 */
597 static inline void
598 writeBuffer (const Buffer *buf, FILE *file)
599 {
600  writeBytes (getBufferHead (buf), countBufferedBytes (buf), file);
601 }
602 
603 /// Array of OpenType names indexed directly by Name IDs.
604 typedef const char *NameStrings[MAX_NAME_IDS];
605 
606 /**
607  @brief Data structure to hold data for one bitmap glyph.
608 
609  This data structure holds data to represent one Unifont bitmap
610  glyph: Unicode code point, number of bytes in its bitmap array,
611  whether or not it is a combining character, and an offset from
612  the glyph origin to the start of the bitmap.
613 */
614 typedef struct Glyph
615 {
616  uint_least32_t codePoint; ///< undefined for glyph 0
617  byte bitmap[GLYPH_MAX_BYTE_COUNT]; ///< hexadecimal bitmap character array
618  uint_least8_t byteCount; ///< length of bitmap data
619  bool combining; ///< whether this is a combining glyph
620  pixels_t pos; ///< number of pixels the glyph should be moved to the right
621  ///< (negative number means moving to the left)
622  pixels_t lsb; ///< left side bearing (x position of leftmost contour point)
624 
625 /**
626  @brief Data structure to hold information for one font.
627 */
628 typedef struct Font
629 {
630  Buffer *tables;
631  Buffer *glyphs;
632  uint_fast32_t glyphCount;
633  pixels_t maxWidth;
635 
636 /**
637  @brief Data structure for an OpenType table.
638 
639  This data structure contains a table tag and a pointer to the
640  start of the buffer that holds data for this OpenType table.
641 
642  For information on the OpenType tables and their structure, see
643  https://docs.microsoft.com/en-us/typography/opentype/spec/otff#font-tables.
644 */
645 typedef struct Table
646 {
647  uint_fast32_t tag;
648  Buffer *content;
650 
651 /**
652  @brief Index to Location ("loca") offset information.
653 
654  This enumerated type encodes the type of offset to locations
655  in a table. It denotes Offset16 (16-bit) and Offset32 (32-bit)
656  offset types.
657 */
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 };
662 
663 /**
664  @brief Convert a 4-byte array to the machine's native 32-bit endian order.
665 
666  This function takes an array of 4 bytes in big-endian order and
667  converts it to a 32-bit word in the endian order of the native machine.
668 
669  @param[in] tag The array of 4 bytes in big-endian order.
670  @return The 32-bit unsigned word in a machine's native endian order.
671 */
672 static inline uint_fast32_t tagAsU32 (const char tag[static 4])
673 {
674  uint_fast32_t r = 0;
675  r |= (tag[0] & 0xff) << 24;
676  r |= (tag[1] & 0xff) << 16;
677  r |= (tag[2] & 0xff) << 8;
678  r |= (tag[3] & 0xff);
679  return r;
680 }
681 
682 /**
683  @brief Add a TrueType or OpenType table to the font.
684 
685  This function adds a TrueType or OpenType table to a font.
686  The 4-byte table tag is passed as an unsigned 32-bit integer
687  in big-endian format.
688 
689  @param[in,out] font The font to which a font table will be added.
690  @param[in] tag The 4-byte table name.
691  @param[in] content The table bytes to add, of type Buffer *.
692 */
693 void
694 addTable (Font *font, const char tag[static 4], Buffer *content)
695 {
696  Table *table = getBufferSlot (font->tables, sizeof (Table));
697  table->tag = tagAsU32 (tag);
698  table->content = content;
699 }
700 
701 /**
702  @brief Sort tables according to OpenType recommendations.
703 
704  The various tables in a font are sorted in an order recommended
705  for TrueType font files.
706 
707  @param[in,out] font The font in which to sort tables.
708  @param[in] isCFF True iff Compact Font Format (CFF) is being used.
709 */
710 void
711 organizeTables (Font *font, bool isCFF)
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 }
739 
740 /**
741  @brief Data structure for data associated with one OpenType table.
742 
743  This data structure contains an OpenType table's tag, start within
744  an OpenType font file, length in bytes, and checksum at the end of
745  the table.
746 */
748 {
749  uint_least32_t tag, offset, length, checksum;
750 };
751 
752 /**
753  @brief Compare tables by 4-byte unsigned table tag value.
754 
755  This function takes two pointers to a TableRecord data structure
756  and extracts the four-byte tag structure element for each. The
757  two 32-bit numbers are then compared. If the first tag is greater
758  than the first, then gt = 1 and lt = 0, and so 1 - 0 = 1 is
759  returned. If the first is less than the second, then gt = 0 and
760  lt = 1, and so 0 - 1 = -1 is returned.
761 
762  @param[in] a Pointer to the first TableRecord structure.
763  @param[in] b Pointer to the second TableRecord structure.
764  @return 1 if the tag in "a" is greater, -1 if less, 0 if equal.
765 */
766 int
767 byTableTag (const void *a, const void *b)
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 }
774 
775 /**
776  @brief Write OpenType font to output file.
777 
778  This function writes the constructed OpenType font to the
779  output file named "filename".
780 
781  @param[in] font Pointer to the font, of type Font *.
782  @param[in] isCFF Boolean indicating whether the font has CFF data.
783  @param[in] filename The name of the font file to create.
784 */
785 void
786 writeFont (Font *font, bool isCFF, const char *fileName)
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 }
883 
884 /**
885  @brief Convert a hexadecimal digit character to a 4-bit number.
886 
887  This function takes a character that contains one hexadecimal digit
888  and returns the 4-bit value (as an unsigned 8-bit value) corresponding
889  to the hexadecimal digit.
890 
891  @param[in] nibble The character containing one hexadecimal digit.
892  @return The hexadecimal digit value, 0 through 15, inclusive.
893 */
894 static inline byte
895 nibbleValue (char nibble)
896 {
897  if (isdigit (nibble))
898  return nibble - '0';
899  nibble = toupper (nibble);
900  return nibble - 'A' + 10;
901 }
902 
903 /**
904  @brief Read up to 6 hexadecimal digits and a colon from file.
905 
906  This function reads up to 6 hexadecimal digits followed by
907  a colon from a file.
908 
909  If the end of the file is reached, the function returns true.
910  The file name is provided to include in an error message if
911  the end of file was reached unexpectedly.
912 
913  @param[out] codePoint The Unicode code point.
914  @param[in] fileName The name of the input file.
915  @param[in] file Pointer to the input file stream.
916  @return true if at end of file, false otherwise.
917 */
918 bool
919 readCodePoint (uint_fast32_t *codePoint, const char *fileName, FILE *file)
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 }
945 
946 /**
947  @brief Read glyph definitions from a Unifont .hex format file.
948 
949  This function reads in the glyph bitmaps contained in a Unifont
950  .hex format file. These input files contain one glyph bitmap
951  per line. Each line is of the form
952 
953  <hexadecimal code point> ':' <hexadecimal bitmap sequence>
954 
955  The code point field typically consists of 4 hexadecimal digits
956  for a code point in Unicode Plane 0, and 6 hexadecimal digits for
957  code points above Plane 0. The hexadecimal bitmap sequence is
958  32 hexadecimal digits long for a glyph that is 8 pixels wide by
959  16 pixels high, and 64 hexadecimal digits long for a glyph that
960  is 16 pixels wide by 16 pixels high.
961 
962  @param[in,out] font The font data structure to update with new glyphs.
963  @param[in] fileName The name of the Unifont .hex format input file.
964 */
965 void
966 readGlyphs (Font *font, const char *fileName)
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 }
1027 
1028 /**
1029  @brief Compare two Unicode code points to determine which is greater.
1030 
1031  This function compares the Unicode code points contained within
1032  two Glyph data structures. The function returns 1 if the first
1033  code point is greater, and -1 if the second is greater.
1034 
1035  @param[in] a A Glyph data structure containing the first code point.
1036  @param[in] b A Glyph data structure containing the second code point.
1037  @return 1 if the code point a is greater, -1 if less, 0 if equal.
1038 */
1039 int
1040 byCodePoint (const void *a, const void *b)
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 }
1047 
1048 /**
1049  @brief Position a glyph within a 16-by-16 pixel bounding box.
1050 
1051  Position a glyph within the 16-by-16 pixel drawing area and
1052  note whether or not the glyph is a combining character.
1053 
1054  N.B.: Glyphs must be sorted by code point before calling this function.
1055 
1056  @param[in,out] font Font data structure pointer to store glyphs.
1057  @param[in] fileName Name of glyph file to read.
1058  @param[in] xMin Minimum x-axis value (for left side bearing).
1059 */
1060 void
1061 positionGlyphs (Font *font, const char *fileName, pixels_t *xMin)
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 }
1108 
1109 /**
1110  @brief Sort the glyphs in a font by Unicode code point.
1111 
1112  This function reads in an array of glyphs and sorts them
1113  by Unicode code point. If a duplicate code point is encountered,
1114  that will result in a fatal error with an error message to stderr.
1115 
1116  @param[in,out] font Pointer to a Font structure with glyphs to sort.
1117 */
1118 void
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 }
1132 
1133 /**
1134  @brief Specify the current contour drawing operation.
1135 */
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 };
1140 
1141 /**
1142  @brief Fill to the left side (CFF) or right side (TrueType) of a contour.
1143 */
1144 enum FillSide {
1145  FILL_LEFT, ///< Draw outline counter-clockwise (CFF, PostScript).
1146  FILL_RIGHT ///< Draw outline clockwise (TrueType).
1147 };
1148 
1149 /**
1150  @brief Build a glyph outline.
1151 
1152  This function builds a glyph outline from a Unifont glyph bitmap.
1153 
1154  @param[out] result The resulting glyph outline.
1155  @param[in] bitmap A bitmap array.
1156  @param[in] byteCount the number of bytes in the input bitmap array.
1157  @param[in] fillSide Enumerated indicator to fill left or right side.
1158 */
1159 void
1160 buildOutline (Buffer *result, const byte bitmap[], const size_t byteCount,
1161  const enum FillSide fillSide)
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 }
1268 
1269 /**
1270  @brief Prepare 32-bit glyph offsets in a font table.
1271 
1272  @param[in] sizes Array of glyph sizes, for offset calculations.
1273 */
1274 void
1275 prepareOffsets (size_t *sizes)
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 }
1283 
1284 /**
1285  @brief Prepare a font name string index.
1286 
1287  @param[in] names List of name strings.
1288  @return Pointer to a Buffer struct containing the string names.
1289 */
1290 Buffer *
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 }
1320 
1321 /**
1322  @brief Add a CFF table to a font.
1323 
1324  @param[in,out] font Pointer to a Font struct to contain the CFF table.
1325  @param[in] version Version of CFF table, with value 1 or 2.
1326  @param[in] names List of NameStrings.
1327 */
1328 void
1329 fillCFF (Font *font, int version, const NameStrings names)
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 }
1588 
1589 /**
1590  @brief Add a TrueType table to a font.
1591 
1592  @param[in,out] font Pointer to a Font struct to contain the TrueType table.
1593  @param[in] format The TrueType "loca" table format, Offset16 or Offset32.
1594  @param[in] names List of NameStrings.
1595 */
1596 void
1597 fillTrueType (Font *font, enum LocaFormat *format,
1598  uint_fast16_t *maxPoints, uint_fast16_t *maxContours)
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 }
1690 
1691 /**
1692  @brief Create a dummy blank outline in a font table.
1693 
1694  @param[in,out] font Pointer to a Font struct to insert a blank outline.
1695 */
1696 void
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 }
1715 
1716 /**
1717  @brief Fill OpenType bitmap data and location tables.
1718 
1719  This function fills an Embedded Bitmap Data (EBDT) Table
1720  and an Embedded Bitmap Location (EBLC) Table with glyph
1721  bitmap information. These tables enable embedding bitmaps
1722  in OpenType fonts. No Embedded Bitmap Scaling (EBSC) table
1723  is used for the bitmap glyphs, only EBDT and EBLC.
1724 
1725  @param[in,out] font Pointer to a Font struct in which to add bitmaps.
1726 */
1727 void
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 }
1841 
1842 /**
1843  @brief Fill a "head" font table.
1844 
1845  The "head" table contains font header information common to the
1846  whole font.
1847 
1848  @param[in,out] font The Font struct to which to add the table.
1849  @param[in] locaFormat The "loca" offset index location table.
1850  @param[in] xMin The minimum x-coordinate for a glyph.
1851 */
1852 void
1853 fillHeadTable (Font *font, enum LocaFormat locaFormat, pixels_t xMin)
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 }
1907 
1908 /**
1909  @brief Fill a "hhea" font table.
1910 
1911  The "hhea" table contains horizontal header information,
1912  for example left and right side bearings.
1913 
1914  @param[in,out] font The Font struct to which to add the table.
1915  @param[in] xMin The minimum x-coordinate for a glyph.
1916 */
1917 void
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 }
1941 
1942 /**
1943  @brief Fill a "maxp" font table.
1944 
1945  The "maxp" table contains maximum profile information,
1946  such as the memory required to contain the font.
1947 
1948  @param[in,out] font The Font struct to which to add the table.
1949  @param[in] isCFF true if a CFF font is included, false otherwise.
1950  @param[in] maxPoints Maximum points in a non-composite glyph.
1951  @param[in] maxContours Maximum contours in a non-composite glyph.
1952 */
1953 void
1954 fillMaxpTable (Font *font, bool isCFF, uint_fast16_t maxPoints,
1955  uint_fast16_t maxContours)
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 }
1977 
1978 /**
1979  @brief Fill an "OS/2" font table.
1980 
1981  The "OS/2" table contains OS/2 and Windows font metrics information.
1982 
1983  @param[in,out] font The Font struct to which to add the table.
1984 */
1985 void
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 }
2078 
2079 /**
2080  @brief Fill an "hmtx" font table.
2081 
2082  The "hmtx" table contains horizontal metrics information.
2083 
2084  @param[in,out] font The Font struct to which to add the table.
2085 */
2086 void
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 }
2100 
2101 /**
2102  @brief Fill a "cmap" font table.
2103 
2104  The "cmap" table contains character to glyph index mapping information.
2105 
2106  @param[in,out] font The Font struct to which to add the table.
2107 */
2108 void
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 }
2209 
2210 /**
2211  @brief Fill a "post" font table.
2212 
2213  The "post" table contains information for PostScript printers.
2214 
2215  @param[in,out] font The Font struct to which to add the table.
2216 */
2217 void
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 }
2232 
2233 /**
2234  @brief Fill a "GPOS" font table.
2235 
2236  The "GPOS" table contains information for glyph positioning.
2237 
2238  @param[in,out] font The Font struct to which to add the table.
2239 */
2240 void
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 }
2260 
2261 /**
2262  @brief Fill a "GSUB" font table.
2263 
2264  The "GSUB" table contains information for glyph substitution.
2265 
2266  @param[in,out] font The Font struct to which to add the table.
2267 */
2268 void
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 }
2305 
2306 /**
2307  @brief Cache a string as a big-ending UTF-16 surrogate pair.
2308 
2309  This function encodes a UTF-8 string as a big-endian UTF-16
2310  surrogate pair.
2311 
2312  @param[in,out] buf Pointer to a Buffer struct to update.
2313  @param[in] str The character array to encode.
2314 */
2315 void
2316 cacheStringAsUTF16BE (Buffer *buf, const char *str)
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 }
2356 
2357 /**
2358  @brief Fill a "name" font table.
2359 
2360  The "name" table contains name information, for example for Name IDs.
2361 
2362  @param[in,out] font The Font struct to which to add the table.
2363  @param[in] names List of NameStrings.
2364 */
2365 void
2366 fillNameTable (Font *font, NameStrings nameStrings)
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 }
2399 
2400 /**
2401  @brief Print program version string on stdout.
2402 
2403  Print program version if invoked with the "--version" option,
2404  and then exit successfully.
2405 */
2406 void
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 }
2418 
2419 /**
2420  @brief Print help message to stdout and then exit.
2421 
2422  Print help message if invoked with the "--help" option,
2423  and then exit successfully.
2424 */
2425 void
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 }
2445 
2446 /**
2447  @brief Data structure to hold options for OpenType font output.
2448 
2449  This data structure holds the status of options that can be
2450  specified as command line arguments for creating the output
2451  OpenType font file.
2452 */
2453 typedef struct Options
2454 {
2455  bool truetype, blankOutline, bitmap, gpos, gsub;
2456  int cff; // 0 = no CFF outline; 1 = use 'CFF' table; 2 = use 'CFF2' table
2457  const char *hex, *pos, *out; // file names
2458  NameStrings nameStrings; // indexed directly by Name IDs
2460 
2461 /**
2462  @brief Match a command line option with its key for enabling.
2463 
2464  @param[in] operand A pointer to the specified operand.
2465  @param[in] key Pointer to the option structure.
2466  @param[in] delimeter The delimiter to end searching.
2467  @return Pointer to the first character of the desired option.
2468 */
2469 const char *
2470 matchToken (const char *operand, const char *key, char delimiter)
2471 {
2472  while (*key)
2473  if (*operand++ != *key++)
2474  return NULL;
2475  if (!*operand || *operand++ == delimiter)
2476  return operand;
2477  return NULL;
2478 }
2479 
2480 /**
2481  @brief Parse command line options.
2482 
2483  Option Data Type Description
2484  ------ --------- -----------
2485  truetype bool Generate TrueType outlines
2486  blankOutline bool Generate blank outlines
2487  bitmap bool Generate embedded bitmap
2488  gpos bool Generate a dummy GPOS table
2489  gsub bool Generate a dummy GSUB table
2490  cff int Generate CFF 1 or CFF 2 outlines
2491  hex const char * Name of Unifont .hex file
2492  pos const char * Name of Unifont combining data file
2493  out const char * Name of output font file
2494  nameStrings NameStrings Array of TrueType font Name IDs
2495 
2496  @param[in] argv Pointer to array of command line options.
2497  @return Data structure to hold requested command line options.
2498 */
2499 Options
2500 parseOptions (char *const argv[const])
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 }
2594 
2595 /**
2596  @brief The main function.
2597 
2598  @param[in] argc The number of command-line arguments.
2599  @param[in] argv The array of command-line arguments.
2600  @return EXIT_FAILURE upon fatal error, EXIT_SUCCESS otherwise.
2601 */
2602 int
2603 main (int argc, char *argv[])
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 }
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
Options
struct Options Options
Data structure to hold options for OpenType font output.
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
Glyph
struct Glyph Glyph
Data structure to hold data for one bitmap glyph.
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
defineStore
#define defineStore(name, type)
Temporary define to look up an element in an array of given type.
Definition: hex2otf.c:350
Font
struct Font Font
Data structure to hold information for one font.
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
hex2otf.h
hex2otf.h - Header file for hex2otf.c
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
byte
unsigned char byte
Definition of "byte" type as an unsigned char.
Definition: hex2otf.c:97
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
Table
struct Table Table
Data structure for an OpenType table.
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
NameStrings
const char * NameStrings[MAX_NAME_IDS]
Array of OpenType names indexed directly by Name IDs.
Definition: hex2otf.c:604
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
FillSide
FillSide
Fill to the left side (CFF) or right side (TrueType) of a contour.
Definition: hex2otf.c:1144
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.
main
int main(int argc, char *argv[])
The main function.
Definition: hex2otf.c:2603
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