+ l ++;
+ }
+
+ /* pad to four-byte boundary */
+ while ((s ++) % 4 != 0)
+ lily_cookie_fprintf (out, "00");
+
+ lily_cookie_fprintf (out, "\n"
+ " 00\n"
+ " >");
+}
+
+static void
+print_body (void *out, FT_Face face)
+{
+ FT_UInt idx = 0;
+ FT_ULong head_length = 0, loca_length = 0;
+ FT_ULong tag, length;
+ vector<FT_ULong> lengths, tags;
+
+ /*
+ we must build our own TTF header -- the original font
+ might be a TTC where tables are not contiguous, or the font
+ contains tables which aren't indexed at all
+ */
+ while (FT_Sfnt_Table_Info (face, idx, &tag, &length)
+ != FT_Err_Table_Missing)
+ {
+ lengths.push_back (length);
+ tags.push_back (tag);
+ if (tag == head_tag)
+ head_length = length;
+ else if (tag == loca_tag)
+ loca_length = length;
+ idx ++;
+ }
+
+ FT_ULong hlength = 12 + 16 * idx;
+
+ unsigned char *hbuf = new unsigned char[hlength];
+ unsigned char *p;
+
+ hbuf[0] = 0x00; /* version */
+ hbuf[1] = 0x01;
+ hbuf[2] = 0x00;
+ hbuf[3] = 0x00;
+ hbuf[4] = (idx & 0xFF00) >> 8; /* numTables */
+ hbuf[5] = idx & 0x00FF;
+
+ FT_UInt searchRange, entrySelector, rangeShift;
+ FT_UInt i, j;
+ for (i = 1, j = 2; j <= idx; i++, j <<= 1)
+ ;
+ entrySelector = i - 1;
+ searchRange = 0x10 << entrySelector;
+ rangeShift = (idx << 4) - searchRange;
+
+ hbuf[6] = (searchRange & 0xFF00) >> 8;
+ hbuf[7] = searchRange & 0x00FF;
+ hbuf[8] = (entrySelector & 0xFF00) >> 8;
+ hbuf[9] = entrySelector & 0x00FF;
+ hbuf[10] = (rangeShift & 0xFF00) >> 8;
+ hbuf[11] = rangeShift & 0x00FF;
+
+ p = &hbuf[12];
+
+ FT_ULong checksum, font_checksum = 0;
+
+ FT_ULong offset = hlength; /* first table offset */
+
+ for (FT_UInt i = 0; i < idx; i++)
+ {
+ /* here, the buffer length must be a multiple of 4 */
+ FT_ULong len = (lengths[i] + 3) & ~3;
+ unsigned char *buf = new unsigned char[len];
+
+ buf[len - 1] = 0x00; /* assure padding with zeros */
+ buf[len - 2] = 0x00;
+ buf[len - 3] = 0x00;
+
+ FT_Error error = FT_Load_Sfnt_Table (face, tags[i], 0, buf, NULL);
+ if (error)
+ programming_error ("FT_Load_Sfnt_Table (): error.");
+
+ if (tag == head_tag)
+ {
+ /*
+ first pass of computing the font checksum
+ needs checkSumAdjustment = 0
+ */
+ buf[8] = 0x00;
+ buf[9] = 0x00;
+ buf[10] = 0x00;
+ buf[11] = 0x00;
+ }
+
+ checksum = 0;
+ unsigned char *endq = buf + len;
+ for (unsigned char *q = buf; q < endq; q += 4)
+ checksum += (q[0] << 24) | (q[1] << 16) | (q[2] << 8) | q[3];
+ font_checksum += checksum;
+
+ delete[] buf;
+
+ *(p++) = (tags[i] & 0xFF000000UL) >> 24;
+ *(p++) = (tags[i] & 0x00FF0000UL) >> 16;
+ *(p++) = (tags[i] & 0x0000FF00UL) >> 8;
+ *(p++) = tags[i] & 0x000000FFUL;
+
+ *(p++) = (checksum & 0xFF000000UL) >> 24;
+ *(p++) = (checksum & 0x00FF0000UL) >> 16;
+ *(p++) = (checksum & 0x0000FF00UL) >> 8;
+ *(p++) = checksum & 0x000000FFUL;
+
+ *(p++) = (offset & 0xFF000000UL) >> 24;
+ *(p++) = (offset & 0x00FF0000UL) >> 16;
+ *(p++) = (offset & 0x0000FF00UL) >> 8;
+ *(p++) = offset & 0x000000FFUL;
+
+ *(p++) = (lengths[i] & 0xFF000000UL) >> 24;
+ *(p++) = (lengths[i] & 0x00FF0000UL) >> 16;
+ *(p++) = (lengths[i] & 0x0000FF00UL) >> 8;
+ *(p++) = lengths[i] & 0x000000FFUL;
+
+ /* offset must be a multiple of 4 */
+ offset += (lengths[i] + 3) & ~3;
+ }
+
+ /* add checksum of TTF header */
+ checksum = 0;
+ for (unsigned char *q = hbuf; q < p; q += 4)
+ checksum += (q[0] << 24) | (q[1] << 16) | (q[2] << 8) | q[3];
+ font_checksum += checksum;
+ font_checksum = 0xB1B0AFBAUL - font_checksum;
+
+ /*
+ see Adobe technical note 5012.Type42_Spec.pdf for details how
+ the /sfnts array must be constructed
+ */