+static
+void t42_write_table (void *out, FT_Face face, unsigned char const *buffer,
+ size_t s, bool is_glyf,
+ FT_ULong head_length, FT_ULong loca_length)
+{
+ vector<FT_UShort> chunks;
+
+ if (is_glyf)
+ {
+ /* compute chunk sizes */
+ unsigned char *head_buf = new unsigned char[head_length];
+ FT_Error error = FT_Load_Sfnt_Table (face, head_tag, 0, head_buf, NULL);
+ if (error)
+ programming_error ("FT_Load_Sfnt_Table (): error.");
+
+ /* we access the lower byte of indexToLocFormat */
+ bool long_offsets = head_buf[4*4 + 2*2 + 2*8 + 4*2 + 3*2 + 1] == 1;
+
+ delete[] head_buf;
+
+ unsigned char *loca_buf = new unsigned char[loca_length];
+ error = FT_Load_Sfnt_Table (face, loca_tag, 0, loca_buf, NULL);
+ if (error)
+ programming_error ("FT_Load_Sfnt_Table (): error.");
+
+ unsigned char *p = loca_buf;
+ unsigned char *endp = loca_buf + loca_length;
+
+ FT_ULong offset = 0, last_offset = 0, last_chunk = 0;
+ while (p < endp)
+ {
+ if (long_offsets)
+ {
+ offset = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ p += 4;
+ }
+ else
+ {
+ offset = ((p[0] << 8) | p[1]) << 1;
+ p += 2;
+ }
+ if (offset > last_offset + CHUNKSIZE)
+ {
+ if (last_chunk != last_offset)
+ chunks.push_back (last_offset - last_chunk);
+ /*
+ a single glyph with more than 64k data
+ is a pathological case but...
+ */
+ FT_ULong rest = offset - last_offset;
+ while (rest > CHUNKSIZE)
+ {
+ chunks.push_back (CHUNKSIZE);
+ rest -= CHUNKSIZE;
+ }
+ chunks.push_back (rest);
+ last_chunk = offset;
+ }
+ else if (offset > last_chunk + CHUNKSIZE)
+ {
+ chunks.push_back (last_offset - last_chunk);
+ last_chunk = last_offset;
+ }
+
+ last_offset = offset;
+ }
+ chunks.push_back (s - last_chunk);
+
+ delete[] loca_buf;
+ }
+ else if (s > CHUNKSIZE)
+ {
+ FT_ULong rest = s;
+ while (rest > CHUNKSIZE)
+ {
+ chunks.push_back (CHUNKSIZE);
+ rest -= CHUNKSIZE;
+ }
+ chunks.push_back (rest);
+ }
+ else
+ chunks.push_back (CHUNKSIZE);
+
+ lily_cookie_fprintf (out, "\n"
+ " <");
+
+ int l = 0;
+ static char xdigits[] = "0123456789ABCDEF";
+
+ int cur_chunk_idx = 0;
+ for (size_t j = 0; j < s; j++)
+ {
+ if (l >= chunks[cur_chunk_idx])
+ {
+ lily_cookie_fprintf (out, "\n"
+ " 00>\n"
+ " <");
+ l = 0;
+ cur_chunk_idx ++;
+ }
+
+ if (l % 31 == 0)
+ lily_cookie_fprintf (out, "\n"
+ " ");
+
+ /* lily_cookie_fprintf (out,"%02X",(int)buffer[j]) is too slow */
+ lily_cookie_putc (xdigits[(buffer[j] & 0xF0) >> 4], out);
+ lily_cookie_putc (xdigits[buffer[j] & 0x0F], out);
+
+ l ++;
+ }
+
+ /* pad to four-byte boundary */
+ while ((s ++) % 4 != 0)
+ lily_cookie_fprintf (out, "00");
+
+ lily_cookie_fprintf (out, "\n"
+ " 00\n"
+ " >");
+}