tizen 2.3.1 release
[framework/graphics/cairo.git] / src / cairo-truetype-subset.c
1 /* cairo - a vector graphics library with display and print output
2  *
3  * Copyright © 2004 Red Hat, Inc
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it either under the terms of the GNU Lesser General Public
7  * License version 2.1 as published by the Free Software Foundation
8  * (the "LGPL") or, at your option, under the terms of the Mozilla
9  * Public License Version 1.1 (the "MPL"). If you do not alter this
10  * notice, a recipient may use your version of this file under either
11  * the MPL or the LGPL.
12  *
13  * You should have received a copy of the LGPL along with this library
14  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16  * You should have received a copy of the MPL along with this library
17  * in the file COPYING-MPL-1.1
18  *
19  * The contents of this file are subject to the Mozilla Public License
20  * Version 1.1 (the "License"); you may not use this file except in
21  * compliance with the License. You may obtain a copy of the License at
22  * http://www.mozilla.org/MPL/
23  *
24  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26  * the specific language governing rights and limitations.
27  *
28  * The Original Code is the cairo graphics library.
29  *
30  * The Initial Developer of the Original Code is Red Hat, Inc.
31  *
32  * Contributor(s):
33  *      Kristian Høgsberg <krh@redhat.com>
34  *      Adrian Johnson <ajohnson@redneon.com>
35  */
36
37 /*
38  * Useful links:
39  * http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6.html
40  * http://www.microsoft.com/typography/specs/default.htm
41  */
42
43 #define _BSD_SOURCE /* for snprintf(), strdup() */
44 #include "cairoint.h"
45
46 #include "cairo-array-private.h"
47 #include "cairo-error-private.h"
48
49 #if CAIRO_HAS_FONT_SUBSET
50
51 #include "cairo-scaled-font-subsets-private.h"
52 #include "cairo-truetype-subset-private.h"
53
54
55 typedef struct subset_glyph subset_glyph_t;
56 struct subset_glyph {
57     int parent_index;
58     unsigned long location;
59 };
60
61 typedef struct _cairo_truetype_font cairo_truetype_font_t;
62
63 typedef struct table table_t;
64 struct table {
65     unsigned long tag;
66     cairo_status_t (*write) (cairo_truetype_font_t *font, unsigned long tag);
67     int pos; /* position in the font directory */
68 };
69
70 struct _cairo_truetype_font {
71
72     cairo_scaled_font_subset_t *scaled_font_subset;
73
74     table_t truetype_tables[10];
75     int num_tables;
76
77     struct {
78         char *font_name;
79         char *ps_name;
80         unsigned int num_glyphs;
81         int *widths;
82         long x_min, y_min, x_max, y_max;
83         long ascent, descent;
84         int  units_per_em;
85     } base;
86
87     subset_glyph_t *glyphs;
88     const cairo_scaled_font_backend_t *backend;
89     int num_glyphs_in_face;
90     int checksum_index;
91     cairo_array_t output;
92     cairo_array_t string_offsets;
93     unsigned long last_offset;
94     unsigned long last_boundary;
95     int *parent_to_subset;
96     cairo_status_t status;
97     cairo_bool_t is_pdf;
98 };
99
100 /*
101  * Test that the structs we define for TrueType tables have the
102  * correct size, ie. they are not padded.
103  */
104 #define check(T, S) COMPILE_TIME_ASSERT (sizeof (T) == (S))
105 check (tt_head_t,       54);
106 check (tt_hhea_t,       36);
107 check (tt_maxp_t,       32);
108 check (tt_name_record_t, 12);
109 check (tt_name_t,       18);
110 check (tt_name_t,       18);
111 check (tt_composite_glyph_t, 16);
112 check (tt_glyph_data_t, 26);
113 #undef check
114
115 static cairo_status_t
116 cairo_truetype_font_use_glyph (cairo_truetype_font_t        *font,
117                                unsigned short                glyph,
118                                unsigned short               *out);
119
120 #define SFNT_VERSION                    0x00010000
121 #define SFNT_STRING_MAX_LENGTH  65535
122
123 static cairo_status_t
124 _cairo_truetype_font_set_error (cairo_truetype_font_t *font,
125                                 cairo_status_t status)
126 {
127     if (status == CAIRO_STATUS_SUCCESS ||
128         status == (int)CAIRO_INT_STATUS_UNSUPPORTED)
129         return status;
130
131     _cairo_status_set_error (&font->status, status);
132
133     return _cairo_error (status);
134 }
135
136 static cairo_status_t
137 _cairo_truetype_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
138                              cairo_bool_t is_pdf,
139                              cairo_truetype_font_t      **font_return)
140 {
141     cairo_status_t status;
142     cairo_truetype_font_t *font;
143     const cairo_scaled_font_backend_t *backend;
144     tt_head_t head;
145     tt_hhea_t hhea;
146     tt_maxp_t maxp;
147     unsigned long size;
148
149     backend = scaled_font_subset->scaled_font->backend;
150     if (!backend->load_truetype_table)
151         return CAIRO_INT_STATUS_UNSUPPORTED;
152
153     /* FIXME: We should either support subsetting vertical fonts, or fail on
154      * vertical.  Currently font_options_t doesn't have vertical flag, but
155      * it should be added in the future.  For now, the freetype backend
156      * returns UNSUPPORTED in load_truetype_table if the font is vertical.
157      *
158      *  if (cairo_font_options_get_vertical_layout (scaled_font_subset->scaled_font))
159      *   return CAIRO_INT_STATUS_UNSUPPORTED;
160      */
161
162     /* We need to use a fallback font generated from the synthesized outlines. */
163     if (backend->is_synthetic && backend->is_synthetic (scaled_font_subset->scaled_font))
164        return CAIRO_INT_STATUS_UNSUPPORTED;
165
166     size = sizeof (tt_head_t);
167     status = backend->load_truetype_table (scaled_font_subset->scaled_font,
168                                           TT_TAG_head, 0,
169                                           (unsigned char *) &head,
170                                           &size);
171     if (unlikely (status))
172         return status;
173
174     size = sizeof (tt_maxp_t);
175     status = backend->load_truetype_table (scaled_font_subset->scaled_font,
176                                            TT_TAG_maxp, 0,
177                                            (unsigned char *) &maxp,
178                                            &size);
179     if (unlikely (status))
180         return status;
181
182     size = sizeof (tt_hhea_t);
183     status = backend->load_truetype_table (scaled_font_subset->scaled_font,
184                                            TT_TAG_hhea, 0,
185                                            (unsigned char *) &hhea,
186                                            &size);
187     if (unlikely (status))
188         return status;
189
190     font = malloc (sizeof (cairo_truetype_font_t));
191     if (unlikely (font == NULL))
192         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
193
194     font->backend = backend;
195     font->num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs);
196     font->scaled_font_subset = scaled_font_subset;
197
198     font->last_offset = 0;
199     font->last_boundary = 0;
200     _cairo_array_init (&font->output, sizeof (char));
201     status = _cairo_array_grow_by (&font->output, 4096);
202     if (unlikely (status))
203         goto fail1;
204
205     font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (subset_glyph_t));
206     if (unlikely (font->glyphs == NULL)) {
207         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
208         goto fail1;
209     }
210
211     font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int));
212     if (unlikely (font->parent_to_subset == NULL)) {
213         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
214         goto fail2;
215     }
216
217     font->is_pdf = is_pdf;
218     font->base.num_glyphs = 0;
219     font->base.x_min = (int16_t) be16_to_cpu (head.x_min);
220     font->base.y_min = (int16_t) be16_to_cpu (head.y_min);
221     font->base.x_max = (int16_t) be16_to_cpu (head.x_max);
222     font->base.y_max = (int16_t) be16_to_cpu (head.y_max);
223     font->base.ascent = (int16_t) be16_to_cpu (hhea.ascender);
224     font->base.descent = (int16_t) be16_to_cpu (hhea.descender);
225     font->base.units_per_em = (int16_t) be16_to_cpu (head.units_per_em);
226     if (font->base.units_per_em == 0)
227         font->base.units_per_em = 2048;
228
229     font->base.ps_name = NULL;
230     font->base.font_name = NULL;
231     status = _cairo_truetype_read_font_name (scaled_font_subset->scaled_font,
232                                              &font->base.ps_name,
233                                              &font->base.font_name);
234     if (_cairo_status_is_error (status))
235         goto fail3;
236
237     /* If the PS name is not found, create a CairoFont-x-y name. */
238     if (font->base.ps_name == NULL) {
239         font->base.ps_name = malloc (30);
240         if (unlikely (font->base.ps_name == NULL)) {
241             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
242             goto fail3;
243         }
244
245         snprintf(font->base.ps_name, 30, "CairoFont-%u-%u",
246                  scaled_font_subset->font_id,
247                  scaled_font_subset->subset_id);
248     }
249
250     font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int));
251     if (unlikely (font->base.widths == NULL)) {
252         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
253         goto fail4;
254     }
255
256     _cairo_array_init (&font->string_offsets, sizeof (unsigned long));
257     status = _cairo_array_grow_by (&font->string_offsets, 10);
258     if (unlikely (status))
259         goto fail5;
260
261     font->status = CAIRO_STATUS_SUCCESS;
262
263     *font_return = font;
264
265     return CAIRO_STATUS_SUCCESS;
266
267  fail5:
268     _cairo_array_fini (&font->string_offsets);
269     free (font->base.widths);
270  fail4:
271     free (font->base.ps_name);
272  fail3:
273     free (font->parent_to_subset);
274     free (font->base.font_name);
275  fail2:
276     free (font->glyphs);
277  fail1:
278     _cairo_array_fini (&font->output);
279     free (font);
280
281     return status;
282 }
283
284 static void
285 cairo_truetype_font_destroy (cairo_truetype_font_t *font)
286 {
287     _cairo_array_fini (&font->string_offsets);
288     free (font->base.widths);
289     free (font->base.ps_name);
290     free (font->base.font_name);
291     free (font->parent_to_subset);
292     free (font->glyphs);
293     _cairo_array_fini (&font->output);
294     free (font);
295 }
296
297 static cairo_status_t
298 cairo_truetype_font_allocate_write_buffer (cairo_truetype_font_t  *font,
299                                            size_t                  length,
300                                            unsigned char         **buffer)
301 {
302     cairo_status_t status;
303
304     if (font->status)
305         return font->status;
306
307     status = _cairo_array_allocate (&font->output, length, (void **) buffer);
308     if (unlikely (status))
309         return _cairo_truetype_font_set_error (font, status);
310
311     return CAIRO_STATUS_SUCCESS;
312 }
313
314 static void
315 cairo_truetype_font_write (cairo_truetype_font_t *font,
316                            const void            *data,
317                            size_t                 length)
318 {
319     cairo_status_t status;
320
321     if (font->status)
322         return;
323
324     status = _cairo_array_append_multiple (&font->output, data, length);
325     if (unlikely (status))
326         status = _cairo_truetype_font_set_error (font, status);
327 }
328
329 static void
330 cairo_truetype_font_write_be16 (cairo_truetype_font_t *font,
331                                 uint16_t               value)
332 {
333     uint16_t be16_value;
334
335     if (font->status)
336         return;
337
338     be16_value = cpu_to_be16 (value);
339     cairo_truetype_font_write (font, &be16_value, sizeof be16_value);
340 }
341
342 static void
343 cairo_truetype_font_write_be32 (cairo_truetype_font_t *font,
344                                 uint32_t               value)
345 {
346     uint32_t be32_value;
347
348     if (font->status)
349         return;
350
351     be32_value = cpu_to_be32 (value);
352     cairo_truetype_font_write (font, &be32_value, sizeof be32_value);
353 }
354
355 static cairo_status_t
356 cairo_truetype_font_align_output (cairo_truetype_font_t     *font,
357                                   unsigned long             *aligned)
358 {
359     int length, pad;
360     unsigned char *padding;
361
362     length = _cairo_array_num_elements (&font->output);
363     *aligned = (length + 3) & ~3;
364     pad = *aligned - length;
365
366     if (pad) {
367         cairo_status_t status;
368
369         status = cairo_truetype_font_allocate_write_buffer (font, pad,
370                                                             &padding);
371         if (unlikely (status))
372             return status;
373
374         memset (padding, 0, pad);
375     }
376
377     return CAIRO_STATUS_SUCCESS;
378 }
379
380 static cairo_status_t
381 cairo_truetype_font_check_boundary (cairo_truetype_font_t *font,
382                                     unsigned long          boundary)
383 {
384     cairo_status_t status;
385
386     if (font->status)
387         return font->status;
388
389     if (boundary - font->last_offset > SFNT_STRING_MAX_LENGTH)
390     {
391         status = _cairo_array_append (&font->string_offsets,
392                                       &font->last_boundary);
393         if (unlikely (status))
394             return _cairo_truetype_font_set_error (font, status);
395
396         font->last_offset = font->last_boundary;
397     }
398     font->last_boundary = boundary;
399
400     return CAIRO_STATUS_SUCCESS;
401 }
402
403 typedef struct _cmap_unicode_range {
404     unsigned int start;
405     unsigned int end;
406 } cmap_unicode_range_t;
407
408 static cmap_unicode_range_t winansi_unicode_ranges[] = {
409     { 0x0020, 0x007f },
410     { 0x00a0, 0x00ff },
411     { 0x0152, 0x0153 },
412     { 0x0160, 0x0161 },
413     { 0x0178, 0x0178 },
414     { 0x017d, 0x017e },
415     { 0x0192, 0x0192 },
416     { 0x02c6, 0x02c6 },
417     { 0x02dc, 0x02dc },
418     { 0x2013, 0x2026 },
419     { 0x2030, 0x2030 },
420     { 0x2039, 0x203a },
421     { 0x20ac, 0x20ac },
422     { 0x2122, 0x2122 },
423 };
424
425 static cairo_status_t
426 cairo_truetype_font_write_cmap_table (cairo_truetype_font_t *font,
427                                       unsigned long          tag)
428 {
429     int i;
430     unsigned int j;
431     int range_offset;
432     int num_ranges;
433     int entry_selector;
434     int length;
435
436     num_ranges = ARRAY_LENGTH (winansi_unicode_ranges);
437
438     length = 16 + (num_ranges + 1)*8;
439     for (i = 0; i < num_ranges; i++)
440         length += (winansi_unicode_ranges[i].end - winansi_unicode_ranges[i].start + 1)*2;
441
442     entry_selector = 0;
443     while ((1 << entry_selector) <= (num_ranges + 1))
444         entry_selector++;
445
446     entry_selector--;
447
448     cairo_truetype_font_write_be16 (font, 0);  /* Table version */
449     cairo_truetype_font_write_be16 (font, 1);  /* Num tables */
450
451     cairo_truetype_font_write_be16 (font, 3);  /* Platform */
452     cairo_truetype_font_write_be16 (font, 1);  /* Encoding */
453     cairo_truetype_font_write_be32 (font, 12); /* Offset to start of table */
454
455     /* Output a format 4 encoding table for the winansi encoding */
456
457     cairo_truetype_font_write_be16 (font, 4);  /* Format */
458     cairo_truetype_font_write_be16 (font, length); /* Length */
459     cairo_truetype_font_write_be16 (font, 0);  /* Version */
460     cairo_truetype_font_write_be16 (font, num_ranges*2 + 2);  /* 2*segcount */
461     cairo_truetype_font_write_be16 (font, (1 << (entry_selector + 1)));  /* searchrange */
462     cairo_truetype_font_write_be16 (font, entry_selector);  /* entry selector */
463     cairo_truetype_font_write_be16 (font, num_ranges*2 + 2 - (1 << (entry_selector + 1)));  /* rangeshift */
464     for (i = 0; i < num_ranges; i++)
465         cairo_truetype_font_write_be16 (font, winansi_unicode_ranges[i].end); /* end count[] */
466     cairo_truetype_font_write_be16 (font, 0xffff);  /* end count[] */
467
468     cairo_truetype_font_write_be16 (font, 0);       /* reserved */
469
470     for (i = 0; i < num_ranges; i++)
471         cairo_truetype_font_write_be16 (font, winansi_unicode_ranges[i].start);  /* startCode[] */
472     cairo_truetype_font_write_be16 (font, 0xffff);  /* startCode[] */
473
474     for (i = 0; i < num_ranges; i++)
475         cairo_truetype_font_write_be16 (font, 0x0000);  /* delta[] */
476     cairo_truetype_font_write_be16 (font, 1);       /* delta[] */
477
478     range_offset = num_ranges*2 + 2;
479     for (i = 0; i < num_ranges; i++) {
480         cairo_truetype_font_write_be16 (font, range_offset);       /* rangeOffset[] */
481         range_offset += (winansi_unicode_ranges[i].end - winansi_unicode_ranges[i].start + 1)*2 - 2;
482     }
483     cairo_truetype_font_write_be16 (font, 0);       /* rangeOffset[] */
484
485     for (i = 0; i < num_ranges; i++) {
486         for (j = winansi_unicode_ranges[i].start; j < winansi_unicode_ranges[i].end + 1; j++) {
487             int ch = _cairo_unicode_to_winansi (j);
488             int glyph;
489
490             if (ch > 0)
491                 glyph = font->scaled_font_subset->latin_to_subset_glyph_index[ch];
492             else
493                 glyph = 0;
494             cairo_truetype_font_write_be16 (font, glyph);
495         }
496     }
497
498     return font->status;
499 }
500
501 static cairo_status_t
502 cairo_truetype_font_write_generic_table (cairo_truetype_font_t *font,
503                                          unsigned long          tag)
504 {
505     cairo_status_t status;
506     unsigned char *buffer;
507     unsigned long size;
508
509     if (font->status)
510         return font->status;
511
512     size = 0;
513     status = font->backend->load_truetype_table(font->scaled_font_subset->scaled_font,
514                                                 tag, 0, NULL, &size);
515     if (unlikely (status))
516         return _cairo_truetype_font_set_error (font, status);
517
518     status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
519     if (unlikely (status))
520         return _cairo_truetype_font_set_error (font, status);
521
522     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
523                                                  tag, 0, buffer, &size);
524     if (unlikely (status))
525         return _cairo_truetype_font_set_error (font, status);
526
527     return CAIRO_STATUS_SUCCESS;
528 }
529
530 static cairo_status_t
531 cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t        *font,
532                                            unsigned char                *buffer,
533                                            unsigned long                 size)
534 {
535     tt_glyph_data_t *glyph_data;
536     tt_composite_glyph_t *composite_glyph;
537     int num_args;
538     int has_more_components;
539     unsigned short flags;
540     unsigned short index;
541     cairo_status_t status;
542     unsigned char *end = buffer + size;
543
544     if (font->status)
545         return font->status;
546
547     glyph_data = (tt_glyph_data_t *) buffer;
548     if ((unsigned char *)(&glyph_data->data) >= end)
549         return CAIRO_INT_STATUS_UNSUPPORTED;
550
551     if ((int16_t)be16_to_cpu (glyph_data->num_contours) >= 0)
552         return CAIRO_STATUS_SUCCESS;
553
554     composite_glyph = &glyph_data->glyph;
555     do {
556         if ((unsigned char *)(&composite_glyph->args[1]) > end)
557             return CAIRO_INT_STATUS_UNSUPPORTED;
558
559         flags = be16_to_cpu (composite_glyph->flags);
560         has_more_components = flags & TT_MORE_COMPONENTS;
561         status = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index), &index);
562         if (unlikely (status))
563             return status;
564
565         composite_glyph->index = cpu_to_be16 (index);
566         num_args = 1;
567         if (flags & TT_ARG_1_AND_2_ARE_WORDS)
568             num_args += 1;
569
570         if (flags & TT_WE_HAVE_A_SCALE)
571             num_args += 1;
572         else if (flags & TT_WE_HAVE_AN_X_AND_Y_SCALE)
573             num_args += 2;
574         else if (flags & TT_WE_HAVE_A_TWO_BY_TWO)
575             num_args += 4;
576
577         composite_glyph = (tt_composite_glyph_t *) &(composite_glyph->args[num_args]);
578     } while (has_more_components);
579
580     return CAIRO_STATUS_SUCCESS;
581 }
582
583 static cairo_status_t
584 cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
585                                       unsigned long          tag)
586 {
587     unsigned long start_offset, index, size, next;
588     tt_head_t header;
589     unsigned long begin, end;
590     unsigned char *buffer;
591     unsigned int i;
592     union {
593         unsigned char *bytes;
594         uint16_t      *short_offsets;
595         uint32_t      *long_offsets;
596     } u;
597     cairo_status_t status;
598
599     if (font->status)
600         return font->status;
601
602     size = sizeof (tt_head_t);
603     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
604                                                  TT_TAG_head, 0,
605                                                  (unsigned char*) &header, &size);
606     if (unlikely (status))
607         return _cairo_truetype_font_set_error (font, status);
608
609     if (be16_to_cpu (header.index_to_loc_format) == 0)
610         size = sizeof (int16_t) * (font->num_glyphs_in_face + 1);
611     else
612         size = sizeof (int32_t) * (font->num_glyphs_in_face + 1);
613
614     u.bytes = malloc (size);
615     if (unlikely (u.bytes == NULL))
616         return _cairo_truetype_font_set_error (font, CAIRO_STATUS_NO_MEMORY);
617
618     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
619                                                  TT_TAG_loca, 0, u.bytes, &size);
620     if (unlikely (status))
621         return _cairo_truetype_font_set_error (font, status);
622
623     start_offset = _cairo_array_num_elements (&font->output);
624     for (i = 0; i < font->base.num_glyphs; i++) {
625         index = font->glyphs[i].parent_index;
626         if (be16_to_cpu (header.index_to_loc_format) == 0) {
627             begin = be16_to_cpu (u.short_offsets[index]) * 2;
628             end = be16_to_cpu (u.short_offsets[index + 1]) * 2;
629         }
630         else {
631             begin = be32_to_cpu (u.long_offsets[index]);
632             end = be32_to_cpu (u.long_offsets[index + 1]);
633         }
634
635         /* quick sanity check... */
636         if (end < begin) {
637             status = CAIRO_INT_STATUS_UNSUPPORTED;
638             goto FAIL;
639         }
640
641         size = end - begin;
642         status = cairo_truetype_font_align_output (font, &next);
643         if (unlikely (status))
644             goto FAIL;
645
646         status = cairo_truetype_font_check_boundary (font, next);
647         if (unlikely (status))
648             goto FAIL;
649
650         font->glyphs[i].location = next - start_offset;
651
652         status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
653         if (unlikely (status))
654             goto FAIL;
655
656         if (size != 0) {
657             status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
658                                                          TT_TAG_glyf, begin, buffer, &size);
659             if (unlikely (status))
660                 goto FAIL;
661
662             status = cairo_truetype_font_remap_composite_glyph (font, buffer, size);
663             if (unlikely (status))
664                 goto FAIL;
665         }
666     }
667
668     status = cairo_truetype_font_align_output (font, &next);
669     if (unlikely (status))
670         goto FAIL;
671
672     font->glyphs[i].location = next - start_offset;
673
674     status = font->status;
675 FAIL:
676     free (u.bytes);
677
678     return _cairo_truetype_font_set_error (font, status);
679 }
680
681 static cairo_status_t
682 cairo_truetype_font_write_head_table (cairo_truetype_font_t *font,
683                                       unsigned long          tag)
684 {
685     unsigned char *buffer;
686     unsigned long size;
687     cairo_status_t status;
688
689     if (font->status)
690         return font->status;
691
692     size = 0;
693     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
694                                                  tag, 0, NULL, &size);
695     if (unlikely (status))
696         return _cairo_truetype_font_set_error (font, status);
697
698     font->checksum_index = _cairo_array_num_elements (&font->output) + 8;
699     status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
700     if (unlikely (status))
701         return _cairo_truetype_font_set_error (font, status);
702
703     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
704                                                  tag, 0, buffer, &size);
705     if (unlikely (status))
706         return _cairo_truetype_font_set_error (font, status);
707
708     /* set checkSumAdjustment to 0 for table checksum calculation */
709     *(uint32_t *)(buffer + 8) = 0;
710
711     return CAIRO_STATUS_SUCCESS;
712 }
713
714 static cairo_status_t
715 cairo_truetype_font_write_hhea_table (cairo_truetype_font_t *font, unsigned long tag)
716 {
717     tt_hhea_t *hhea;
718     unsigned long size;
719     cairo_status_t status;
720
721     if (font->status)
722         return font->status;
723
724     size = sizeof (tt_hhea_t);
725     status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &hhea);
726     if (unlikely (status))
727         return _cairo_truetype_font_set_error (font, status);
728
729     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
730                                                  tag, 0, (unsigned char *) hhea, &size);
731     if (unlikely (status))
732         return _cairo_truetype_font_set_error (font, status);
733
734     hhea->num_hmetrics = cpu_to_be16 ((uint16_t)(font->base.num_glyphs));
735
736     return CAIRO_STATUS_SUCCESS;
737 }
738
739 static cairo_status_t
740 cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font,
741                                       unsigned long          tag)
742 {
743     unsigned long size;
744     unsigned long long_entry_size;
745     unsigned long short_entry_size;
746     short *p;
747     unsigned int i;
748     tt_hhea_t hhea;
749     int num_hmetrics;
750     cairo_status_t status;
751
752     if (font->status)
753         return font->status;
754
755     size = sizeof (tt_hhea_t);
756     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
757                                                  TT_TAG_hhea, 0,
758                                                  (unsigned char*) &hhea, &size);
759     if (unlikely (status))
760         return _cairo_truetype_font_set_error (font, status);
761
762     num_hmetrics = be16_to_cpu(hhea.num_hmetrics);
763
764     for (i = 0; i < font->base.num_glyphs; i++) {
765         long_entry_size = 2 * sizeof (int16_t);
766         short_entry_size = sizeof (int16_t);
767         status = cairo_truetype_font_allocate_write_buffer (font,
768                                                             long_entry_size,
769                                                             (unsigned char **) &p);
770         if (unlikely (status))
771             return _cairo_truetype_font_set_error (font, status);
772
773         if (font->glyphs[i].parent_index < num_hmetrics) {
774             status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
775                                                          TT_TAG_hmtx,
776                                                          font->glyphs[i].parent_index * long_entry_size,
777                                                          (unsigned char *) p, &long_entry_size);
778             if (unlikely (status))
779                 return _cairo_truetype_font_set_error (font, status);
780         }
781         else
782         {
783             status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
784                                                          TT_TAG_hmtx,
785                                                          (num_hmetrics - 1) * long_entry_size,
786                                                          (unsigned char *) p, &short_entry_size);
787             if (unlikely (status))
788                 return _cairo_truetype_font_set_error (font, status);
789
790             status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
791                                                          TT_TAG_hmtx,
792                                                          num_hmetrics * long_entry_size +
793                                                          (font->glyphs[i].parent_index - num_hmetrics) * short_entry_size,
794                                                          (unsigned char *) (p + 1), &short_entry_size);
795             if (unlikely (status))
796                 return _cairo_truetype_font_set_error (font, status);
797         }
798         font->base.widths[i] = be16_to_cpu (p[0]);
799     }
800
801     return CAIRO_STATUS_SUCCESS;
802 }
803
804 static cairo_status_t
805 cairo_truetype_font_write_loca_table (cairo_truetype_font_t *font,
806                                       unsigned long          tag)
807 {
808     unsigned int i;
809     tt_head_t header;
810     unsigned long size;
811     cairo_status_t status;
812
813     if (font->status)
814         return font->status;
815
816     size = sizeof(tt_head_t);
817     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
818                                                  TT_TAG_head, 0,
819                                                  (unsigned char*) &header, &size);
820     if (unlikely (status))
821         return _cairo_truetype_font_set_error (font, status);
822
823     if (be16_to_cpu (header.index_to_loc_format) == 0)
824     {
825         for (i = 0; i < font->base.num_glyphs + 1; i++)
826             cairo_truetype_font_write_be16 (font, font->glyphs[i].location / 2);
827     } else {
828         for (i = 0; i < font->base.num_glyphs + 1; i++)
829             cairo_truetype_font_write_be32 (font, font->glyphs[i].location);
830     }
831
832     return font->status;
833 }
834
835 static cairo_status_t
836 cairo_truetype_font_write_maxp_table (cairo_truetype_font_t *font,
837                                       unsigned long          tag)
838 {
839     tt_maxp_t *maxp;
840     unsigned long size;
841     cairo_status_t status;
842
843     if (font->status)
844         return font->status;
845
846     size = sizeof (tt_maxp_t);
847     status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
848     if (unlikely (status))
849         return _cairo_truetype_font_set_error (font, status);
850
851     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
852                                                  tag, 0, (unsigned char *) maxp, &size);
853     if (unlikely (status))
854         return _cairo_truetype_font_set_error (font, status);
855
856     maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs);
857
858     return CAIRO_STATUS_SUCCESS;
859 }
860
861 static cairo_status_t
862 cairo_truetype_font_write_offset_table (cairo_truetype_font_t *font)
863 {
864     cairo_status_t status;
865     unsigned char *table_buffer;
866     size_t table_buffer_length;
867     unsigned short search_range, entry_selector, range_shift;
868
869     if (font->status)
870         return font->status;
871
872     search_range = 1;
873     entry_selector = 0;
874     while (search_range * 2 <= font->num_tables) {
875         search_range *= 2;
876         entry_selector++;
877     }
878     search_range *= 16;
879     range_shift = font->num_tables * 16 - search_range;
880
881     cairo_truetype_font_write_be32 (font, SFNT_VERSION);
882     cairo_truetype_font_write_be16 (font, font->num_tables);
883     cairo_truetype_font_write_be16 (font, search_range);
884     cairo_truetype_font_write_be16 (font, entry_selector);
885     cairo_truetype_font_write_be16 (font, range_shift);
886
887     /* Allocate space for the table directory. Each directory entry
888      * will be filled in by cairo_truetype_font_update_entry() after
889      * the table is written. */
890     table_buffer_length = font->num_tables * 16;
891     status = cairo_truetype_font_allocate_write_buffer (font, table_buffer_length,
892                                                       &table_buffer);
893     if (unlikely (status))
894         return _cairo_truetype_font_set_error (font, status);
895
896     return CAIRO_STATUS_SUCCESS;
897 }
898
899 static uint32_t
900 cairo_truetype_font_calculate_checksum (cairo_truetype_font_t *font,
901                                         unsigned long          start,
902                                         unsigned long          end)
903 {
904     uint32_t *padded_end;
905     uint32_t *p;
906     uint32_t checksum;
907     char *data;
908
909     checksum = 0;
910     data = _cairo_array_index (&font->output, 0);
911     p = (uint32_t *) (data + start);
912     padded_end = (uint32_t *) (data + ((end + 3) & ~3));
913     while (p < padded_end)
914         checksum += be32_to_cpu(*p++);
915
916     return checksum;
917 }
918
919 static void
920 cairo_truetype_font_update_entry (cairo_truetype_font_t *font,
921                                   int                    index,
922                                   unsigned long          tag,
923                                   unsigned long          start,
924                                   unsigned long          end)
925 {
926     uint32_t *entry;
927
928     entry = _cairo_array_index (&font->output, 12 + 16 * index);
929     if (entry == NULL)
930         return;
931
932     entry[0] = cpu_to_be32 ((uint32_t)tag);
933     entry[1] = cpu_to_be32 (cairo_truetype_font_calculate_checksum (font, start, end));
934     entry[2] = cpu_to_be32 ((uint32_t)start);
935     entry[3] = cpu_to_be32 ((uint32_t)(end - start));
936 }
937
938 static cairo_status_t
939 cairo_truetype_font_generate (cairo_truetype_font_t  *font,
940                               const char            **data,
941                               unsigned long          *length,
942                               const unsigned long   **string_offsets,
943                               unsigned long          *num_strings)
944 {
945     cairo_status_t status;
946     unsigned long start, end, next;
947     uint32_t checksum, *checksum_location;
948     int i;
949
950     if (font->status)
951         return font->status;
952
953     status = cairo_truetype_font_write_offset_table (font);
954     if (unlikely (status))
955         goto FAIL;
956
957     status = cairo_truetype_font_align_output (font, &start);
958     if (unlikely (status))
959         goto FAIL;
960
961     end = 0;
962     for (i = 0; i < font->num_tables; i++) {
963         status = font->truetype_tables[i].write (font, font->truetype_tables[i].tag);
964         if (unlikely (status))
965             goto FAIL;
966
967         end = _cairo_array_num_elements (&font->output);
968         status = cairo_truetype_font_align_output (font, &next);
969         if (unlikely (status))
970             goto FAIL;
971
972         cairo_truetype_font_update_entry (font, font->truetype_tables[i].pos,
973                                           font->truetype_tables[i].tag, start, end);
974         status = cairo_truetype_font_check_boundary (font, next);
975         if (unlikely (status))
976             goto FAIL;
977
978         start = next;
979     }
980
981     checksum =
982         0xb1b0afba - cairo_truetype_font_calculate_checksum (font, 0, end);
983     checksum_location = _cairo_array_index (&font->output, font->checksum_index);
984     if (checksum_location == NULL) {
985         status = _cairo_error (CAIRO_STATUS_NULL_POINTER);
986         goto FAIL;
987     }
988
989     *checksum_location = cpu_to_be32 (checksum);
990
991     *data = _cairo_array_index (&font->output, 0);
992     *length = _cairo_array_num_elements (&font->output);
993     *num_strings = _cairo_array_num_elements (&font->string_offsets);
994     if (*num_strings != 0)
995         *string_offsets = _cairo_array_index (&font->string_offsets, 0);
996     else
997         *string_offsets = NULL;
998
999  FAIL:
1000     return _cairo_truetype_font_set_error (font, status);
1001 }
1002
1003 static cairo_status_t
1004 cairo_truetype_font_use_glyph (cairo_truetype_font_t        *font,
1005                                unsigned short                glyph,
1006                                unsigned short               *out)
1007 {
1008     if (glyph >= font->num_glyphs_in_face)
1009         return CAIRO_INT_STATUS_UNSUPPORTED;
1010
1011     if (font->parent_to_subset[glyph] == 0) {
1012         font->parent_to_subset[glyph] = font->base.num_glyphs;
1013         font->glyphs[font->base.num_glyphs].parent_index = glyph;
1014         font->base.num_glyphs++;
1015     }
1016
1017     *out = font->parent_to_subset[glyph];
1018     return CAIRO_STATUS_SUCCESS;
1019 }
1020
1021 static void
1022 cairo_truetype_font_add_truetype_table (cairo_truetype_font_t *font,
1023            unsigned long tag,
1024            cairo_status_t (*write) (cairo_truetype_font_t *font, unsigned long tag),
1025            int pos)
1026 {
1027     font->truetype_tables[font->num_tables].tag = tag;
1028     font->truetype_tables[font->num_tables].write = write;
1029     font->truetype_tables[font->num_tables].pos = pos;
1030     font->num_tables++;
1031 }
1032
1033 /* cairo_truetype_font_create_truetype_table_list() builds the list of
1034  * truetype tables to be embedded in the subsetted font. Each call to
1035  * cairo_truetype_font_add_truetype_table() adds a table, the callback
1036  * for generating the table, and the position in the table directory
1037  * to the truetype_tables array.
1038  *
1039  * As we write out the glyf table we remap composite glyphs.
1040  * Remapping composite glyphs will reference the sub glyphs the
1041  * composite glyph is made up of. The "glyf" table callback needs to
1042  * be called first so we have all the glyphs in the subset before
1043  * going further.
1044  *
1045  * The order in which tables are added to the truetype_table array
1046  * using cairo_truetype_font_add_truetype_table() specifies the order
1047  * in which the callback functions will be called.
1048  *
1049  * The tables in the table directory must be listed in alphabetical
1050  * order.  The "cvt", "fpgm", and "prep" are optional tables. They
1051  * will only be embedded in the subset if they exist in the source
1052  * font. "cmap" is only embedded for latin fonts. The pos parameter of
1053  * cairo_truetype_font_add_truetype_table() specifies the position of
1054  * the table in the table directory.
1055  */
1056 static void
1057 cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t *font)
1058 {
1059     cairo_bool_t has_cvt = FALSE;
1060     cairo_bool_t has_fpgm = FALSE;
1061     cairo_bool_t has_prep = FALSE;
1062     unsigned long size;
1063     int pos;
1064
1065     size = 0;
1066     if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
1067                                       TT_TAG_cvt, 0, NULL,
1068                                       &size) == CAIRO_INT_STATUS_SUCCESS)
1069         has_cvt = TRUE;
1070
1071     size = 0;
1072     if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
1073                                       TT_TAG_fpgm, 0, NULL,
1074                                       &size) == CAIRO_INT_STATUS_SUCCESS)
1075         has_fpgm = TRUE;
1076
1077     size = 0;
1078     if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
1079                                       TT_TAG_prep, 0, NULL,
1080                                       &size) == CAIRO_INT_STATUS_SUCCESS)
1081         has_prep = TRUE;
1082
1083     font->num_tables = 0;
1084     pos = 0;
1085     if (font->is_pdf && font->scaled_font_subset->is_latin)
1086         pos++;
1087     if (has_cvt)
1088         pos++;
1089     if (has_fpgm)
1090         pos++;
1091     cairo_truetype_font_add_truetype_table (font, TT_TAG_glyf, cairo_truetype_font_write_glyf_table, pos);
1092
1093     pos = 0;
1094     if (font->is_pdf && font->scaled_font_subset->is_latin)
1095         cairo_truetype_font_add_truetype_table (font, TT_TAG_cmap, cairo_truetype_font_write_cmap_table, pos++);
1096     if (has_cvt)
1097         cairo_truetype_font_add_truetype_table (font, TT_TAG_cvt, cairo_truetype_font_write_generic_table, pos++);
1098     if (has_fpgm)
1099         cairo_truetype_font_add_truetype_table (font, TT_TAG_fpgm, cairo_truetype_font_write_generic_table, pos++);
1100     pos++;
1101     cairo_truetype_font_add_truetype_table (font, TT_TAG_head, cairo_truetype_font_write_head_table, pos++);
1102     cairo_truetype_font_add_truetype_table (font, TT_TAG_hhea, cairo_truetype_font_write_hhea_table, pos++);
1103     cairo_truetype_font_add_truetype_table (font, TT_TAG_hmtx, cairo_truetype_font_write_hmtx_table, pos++);
1104     cairo_truetype_font_add_truetype_table (font, TT_TAG_loca, cairo_truetype_font_write_loca_table, pos++);
1105     cairo_truetype_font_add_truetype_table (font, TT_TAG_maxp, cairo_truetype_font_write_maxp_table, pos++);
1106     if (has_prep)
1107         cairo_truetype_font_add_truetype_table (font, TT_TAG_prep, cairo_truetype_font_write_generic_table, pos);
1108 }
1109
1110 static cairo_status_t
1111 cairo_truetype_subset_init_internal (cairo_truetype_subset_t     *truetype_subset,
1112                                       cairo_scaled_font_subset_t *font_subset,
1113                                       cairo_bool_t                is_pdf)
1114 {
1115     cairo_truetype_font_t *font = NULL;
1116     cairo_status_t status;
1117     const char *data = NULL; /* squelch bogus compiler warning */
1118     unsigned long length = 0; /* squelch bogus compiler warning */
1119     unsigned long offsets_length;
1120     unsigned int i;
1121     const unsigned long *string_offsets = NULL;
1122     unsigned long num_strings = 0;
1123
1124     status = _cairo_truetype_font_create (font_subset, is_pdf, &font);
1125     if (unlikely (status))
1126         return status;
1127
1128     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
1129         unsigned short parent_glyph = font->scaled_font_subset->glyphs[i];
1130         status = cairo_truetype_font_use_glyph (font, parent_glyph, &parent_glyph);
1131         if (unlikely (status))
1132             goto fail1;
1133     }
1134
1135     cairo_truetype_font_create_truetype_table_list (font);
1136     status = cairo_truetype_font_generate (font, &data, &length,
1137                                            &string_offsets, &num_strings);
1138     if (unlikely (status))
1139         goto fail1;
1140
1141     truetype_subset->ps_name = strdup (font->base.ps_name);
1142     if (unlikely (truetype_subset->ps_name == NULL)) {
1143         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1144         goto fail1;
1145     }
1146
1147     if (font->base.font_name != NULL) {
1148         truetype_subset->family_name_utf8 = strdup (font->base.font_name);
1149         if (unlikely (truetype_subset->family_name_utf8 == NULL)) {
1150             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1151             goto fail2;
1152         }
1153     } else {
1154         truetype_subset->family_name_utf8 = NULL;
1155     }
1156
1157     /* The widths array returned must contain only widths for the
1158      * glyphs in font_subset. Any subglyphs appended after
1159      * font_subset->num_glyphs are omitted. */
1160     truetype_subset->widths = calloc (sizeof (double),
1161                                       font->scaled_font_subset->num_glyphs);
1162     if (unlikely (truetype_subset->widths == NULL)) {
1163         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1164         goto fail3;
1165     }
1166     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
1167         truetype_subset->widths[i] = (double)font->base.widths[i]/font->base.units_per_em;
1168
1169     truetype_subset->x_min = (double)font->base.x_min/font->base.units_per_em;
1170     truetype_subset->y_min = (double)font->base.y_min/font->base.units_per_em;
1171     truetype_subset->x_max = (double)font->base.x_max/font->base.units_per_em;
1172     truetype_subset->y_max = (double)font->base.y_max/font->base.units_per_em;
1173     truetype_subset->ascent = (double)font->base.ascent/font->base.units_per_em;
1174     truetype_subset->descent = (double)font->base.descent/font->base.units_per_em;
1175
1176     if (length) {
1177         truetype_subset->data = malloc (length);
1178         if (unlikely (truetype_subset->data == NULL)) {
1179             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1180             goto fail4;
1181         }
1182
1183         memcpy (truetype_subset->data, data, length);
1184     } else
1185         truetype_subset->data = NULL;
1186     truetype_subset->data_length = length;
1187
1188     if (num_strings) {
1189         offsets_length = num_strings * sizeof (unsigned long);
1190         truetype_subset->string_offsets = malloc (offsets_length);
1191         if (unlikely (truetype_subset->string_offsets == NULL)) {
1192             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1193             goto fail5;
1194         }
1195
1196         memcpy (truetype_subset->string_offsets, string_offsets, offsets_length);
1197         truetype_subset->num_string_offsets = num_strings;
1198     } else {
1199         truetype_subset->string_offsets = NULL;
1200         truetype_subset->num_string_offsets = 0;
1201     }
1202
1203     cairo_truetype_font_destroy (font);
1204
1205     return CAIRO_STATUS_SUCCESS;
1206
1207  fail5:
1208     free (truetype_subset->data);
1209  fail4:
1210     free (truetype_subset->widths);
1211  fail3:
1212     free (truetype_subset->family_name_utf8);
1213  fail2:
1214     free (truetype_subset->ps_name);
1215  fail1:
1216     cairo_truetype_font_destroy (font);
1217
1218     return status;
1219 }
1220
1221 cairo_status_t
1222 _cairo_truetype_subset_init_ps (cairo_truetype_subset_t    *truetype_subset,
1223                                 cairo_scaled_font_subset_t      *font_subset)
1224 {
1225     return cairo_truetype_subset_init_internal (truetype_subset, font_subset, FALSE);
1226 }
1227
1228 cairo_status_t
1229 _cairo_truetype_subset_init_pdf (cairo_truetype_subset_t    *truetype_subset,
1230                                 cairo_scaled_font_subset_t      *font_subset)
1231 {
1232     return cairo_truetype_subset_init_internal (truetype_subset, font_subset, TRUE);
1233 }
1234
1235 void
1236 _cairo_truetype_subset_fini (cairo_truetype_subset_t *subset)
1237 {
1238     free (subset->ps_name);
1239     free (subset->family_name_utf8);
1240     free (subset->widths);
1241     free (subset->data);
1242     free (subset->string_offsets);
1243 }
1244
1245 static cairo_int_status_t
1246 _cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font,
1247                               unsigned long        table_offset,
1248                               unsigned long        index,
1249                               uint32_t            *ucs4)
1250 {
1251     cairo_status_t status;
1252     const cairo_scaled_font_backend_t *backend;
1253     tt_segment_map_t *map;
1254     char buf[4];
1255     unsigned int num_segments, i;
1256     unsigned long size;
1257     uint16_t *start_code;
1258     uint16_t *end_code;
1259     uint16_t *delta;
1260     uint16_t *range_offset;
1261     uint16_t  c;
1262
1263     backend = scaled_font->backend;
1264     size = 4;
1265     status = backend->load_truetype_table (scaled_font,
1266                                            TT_TAG_cmap, table_offset,
1267                                            (unsigned char *) &buf,
1268                                            &size);
1269     if (unlikely (status))
1270         return status;
1271
1272     /* All table formats have the same first two words */
1273     map = (tt_segment_map_t *) buf;
1274     if (be16_to_cpu (map->format) != 4)
1275         return CAIRO_INT_STATUS_UNSUPPORTED;
1276
1277     size = be16_to_cpu (map->length);
1278     map = malloc (size);
1279     if (unlikely (map == NULL))
1280         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1281
1282     status = backend->load_truetype_table (scaled_font,
1283                                            TT_TAG_cmap, table_offset,
1284                                            (unsigned char *) map,
1285                                            &size);
1286     if (unlikely (status))
1287         goto fail;
1288
1289     num_segments = be16_to_cpu (map->segCountX2)/2;
1290
1291     /* A Format 4 cmap contains 8 uint16_t numbers and 4 arrays of
1292      * uint16_t each num_segments long. */
1293     if (size < (8 + 4*num_segments)*sizeof(uint16_t))
1294         return CAIRO_INT_STATUS_UNSUPPORTED;
1295
1296     end_code = map->endCount;
1297     start_code = &(end_code[num_segments + 1]);
1298     delta = &(start_code[num_segments]);
1299     range_offset = &(delta[num_segments]);
1300
1301     /* search for glyph in segments with rangeOffset=0 */
1302     for (i = 0; i < num_segments; i++) {
1303         c = index - be16_to_cpu (delta[i]);
1304         if (range_offset[i] == 0 &&
1305             c >= be16_to_cpu (start_code[i]) &&
1306             c <= be16_to_cpu (end_code[i]))
1307         {
1308             *ucs4 = c;
1309             goto found;
1310         }
1311     }
1312
1313     /* search for glyph in segments with rangeOffset=1 */
1314     for (i = 0; i < num_segments; i++) {
1315         if (range_offset[i] != 0) {
1316             uint16_t *glyph_ids = &range_offset[i] + be16_to_cpu (range_offset[i])/2;
1317             int range_size = be16_to_cpu (end_code[i]) - be16_to_cpu (start_code[i]) + 1;
1318             uint16_t g_id_be = cpu_to_be16 (index);
1319             int j;
1320
1321             if (range_size > 0) {
1322                 if ((char*)glyph_ids + 2*range_size > (char*)map + size)
1323                     return CAIRO_INT_STATUS_UNSUPPORTED;
1324
1325                 for (j = 0; j < range_size; j++) {
1326                     if (glyph_ids[j] == g_id_be) {
1327                         *ucs4 = be16_to_cpu (start_code[i]) + j;
1328                         goto found;
1329                     }
1330                 }
1331             }
1332         }
1333     }
1334
1335     /* glyph not found */
1336     *ucs4 = -1;
1337
1338 found:
1339     status = CAIRO_STATUS_SUCCESS;
1340
1341 fail:
1342     free (map);
1343
1344     return status;
1345 }
1346
1347 cairo_int_status_t
1348 _cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font,
1349                                unsigned long        index,
1350                                uint32_t            *ucs4)
1351 {
1352     cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
1353     const cairo_scaled_font_backend_t *backend;
1354     tt_cmap_t *cmap;
1355     char buf[4];
1356     int num_tables, i;
1357     unsigned long size;
1358
1359     backend = scaled_font->backend;
1360     if (!backend->load_truetype_table)
1361         return CAIRO_INT_STATUS_UNSUPPORTED;
1362
1363     size = 4;
1364     status = backend->load_truetype_table (scaled_font,
1365                                            TT_TAG_cmap, 0,
1366                                            (unsigned char *) &buf,
1367                                            &size);
1368     if (unlikely (status))
1369         return status;
1370
1371     cmap = (tt_cmap_t *) buf;
1372     num_tables = be16_to_cpu (cmap->num_tables);
1373     size = 4 + num_tables*sizeof(tt_cmap_index_t);
1374     cmap = _cairo_malloc_ab_plus_c (num_tables, sizeof (tt_cmap_index_t), 4);
1375     if (unlikely (cmap == NULL))
1376         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1377
1378     status = backend->load_truetype_table (scaled_font,
1379                                            TT_TAG_cmap, 0,
1380                                            (unsigned char *) cmap,
1381                                            &size);
1382     if (unlikely (status))
1383         goto cleanup;
1384
1385     /* Find a table with Unicode mapping */
1386     for (i = 0; i < num_tables; i++) {
1387         if (be16_to_cpu (cmap->index[i].platform) == 3 &&
1388             be16_to_cpu (cmap->index[i].encoding) == 1) {
1389             status = _cairo_truetype_reverse_cmap (scaled_font,
1390                                                    be32_to_cpu (cmap->index[i].offset),
1391                                                    index,
1392                                                    ucs4);
1393             if (status != CAIRO_INT_STATUS_UNSUPPORTED)
1394                 break;
1395         }
1396     }
1397
1398 cleanup:
1399     free (cmap);
1400
1401     return status;
1402 }
1403
1404 static cairo_status_t
1405 find_name (tt_name_t *name, int name_id, int platform, int encoding, int language, char **str_out)
1406 {
1407     tt_name_record_t *record;
1408     int i, len;
1409     char *str;
1410     char *p;
1411     cairo_bool_t has_tag;
1412     cairo_status_t status;
1413
1414     str = NULL;
1415     for (i = 0; i < be16_to_cpu (name->num_records); i++) {
1416         record = &(name->records[i]);
1417         if (be16_to_cpu (record->name) == name_id &&
1418             be16_to_cpu (record->platform) == platform &&
1419             be16_to_cpu (record->encoding) == encoding &&
1420             (language == -1 || be16_to_cpu (record->language) == language)) {
1421
1422             str = malloc (be16_to_cpu (record->length) + 1);
1423             if (str == NULL)
1424                 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1425
1426             len = be16_to_cpu (record->length);
1427             memcpy (str,
1428                     ((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset),
1429                     len);
1430             str[be16_to_cpu (record->length)] = 0;
1431             break;
1432         }
1433     }
1434     if (str == NULL) {
1435         *str_out = NULL;
1436         return CAIRO_STATUS_SUCCESS;
1437     }
1438
1439     if (platform == 3) { /* Win platform, unicode encoding */
1440         /* convert to utf8 */
1441         int size = 0;
1442         char *utf8;
1443         uint16_t *u = (uint16_t *) str;
1444         int u_len = len/2;
1445
1446         for (i = 0; i < u_len; i++)
1447             size += _cairo_ucs4_to_utf8 (be16_to_cpu(u[i]), NULL);
1448
1449         utf8 = malloc (size + 1);
1450         if (utf8 == NULL) {
1451             status =_cairo_error (CAIRO_STATUS_NO_MEMORY);
1452             goto fail;
1453         }
1454         p = utf8;
1455         for (i = 0; i < u_len; i++)
1456             p += _cairo_ucs4_to_utf8 (be16_to_cpu(u[i]), p);
1457         *p = 0;
1458         free (str);
1459         str = utf8;
1460     } else if (platform == 1) { /* Mac platform, Mac Roman encoding */
1461         /* Replace characters above 127 with underscores. We could use
1462          * a lookup table to convert to unicode but since most fonts
1463          * include a unicode name this is just a rarely used fallback. */
1464         for (i = 0; i < len; i++) {
1465             if ((unsigned char)str[i] > 127)
1466                 str[i] = '_';
1467         }
1468     }
1469
1470     /* If font name is prefixed with a PDF subset tag, strip it off. */
1471     p = str;
1472     len = strlen (str);
1473     has_tag = FALSE;
1474     if (len > 7 && p[6] == '+') {
1475         has_tag = TRUE;
1476         for (i = 0; i < 6; i++) {
1477             if (p[i] < 'A' || p[i] > 'Z') {
1478                 has_tag = FALSE;
1479                 break;
1480             }
1481         }
1482     }
1483     if (has_tag) {
1484         p = malloc (len - 6);
1485         if (unlikely (p == NULL)) {
1486             status =_cairo_error (CAIRO_STATUS_NO_MEMORY);
1487             goto fail;
1488         }
1489         memcpy (p, str + 7, len - 7);
1490         p[len-7] = 0;
1491         free (str);
1492         str = p;
1493     }
1494
1495     *str_out = str;
1496
1497     return CAIRO_STATUS_SUCCESS;
1498
1499   fail:
1500     free (str);
1501
1502     return status;
1503 }
1504
1505 cairo_int_status_t
1506 _cairo_truetype_read_font_name (cairo_scaled_font_t      *scaled_font,
1507                                 char                    **ps_name_out,
1508                                 char                    **font_name_out)
1509 {
1510     cairo_status_t status;
1511     const cairo_scaled_font_backend_t *backend;
1512     tt_name_t *name;
1513     unsigned long size;
1514     char *ps_name = NULL;
1515     char *family_name = NULL;
1516
1517     backend = scaled_font->backend;
1518     if (!backend->load_truetype_table)
1519         return CAIRO_INT_STATUS_UNSUPPORTED;
1520
1521     size = 0;
1522     status = backend->load_truetype_table (scaled_font,
1523                                            TT_TAG_name, 0,
1524                                            NULL,
1525                                            &size);
1526     if (status)
1527         return status;
1528
1529     name = malloc (size);
1530     if (name == NULL)
1531         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1532
1533     status = backend->load_truetype_table (scaled_font,
1534                                            TT_TAG_name, 0,
1535                                            (unsigned char *) name,
1536                                            &size);
1537     if (status)
1538         goto fail;
1539
1540     /* Find PS Name (name_id = 6). OT spec says PS name must be one of
1541      * the following two encodings */
1542     status = find_name (name, 6, 3, 1, 0x409, &ps_name); /* win, unicode, english-us */
1543     if (unlikely(status))
1544         goto fail;
1545
1546     if (!ps_name) {
1547         status = find_name (name, 6, 1, 0, 0, &ps_name); /* mac, roman, english */
1548         if (unlikely(status))
1549             goto fail;
1550     }
1551
1552     /* Find Family name (name_id = 1) */
1553     status = find_name (name, 1, 3, 1, 0x409, &family_name); /* win, unicode, english-us */
1554     if (unlikely(status))
1555         goto fail;
1556
1557     if (!family_name) {
1558         status = find_name (name, 1, 3, 0, 0x409, &family_name); /* win, symbol, english-us */
1559         if (unlikely(status))
1560             goto fail;
1561     }
1562
1563     if (!family_name) {
1564         status = find_name (name, 1, 1, 0, 0, &family_name); /* mac, roman, english */
1565         if (unlikely(status))
1566             goto fail;
1567     }
1568
1569     if (!family_name) {
1570         status = find_name (name, 1, 3, 1, -1, &family_name); /* win, unicode, any language */
1571         if (unlikely(status))
1572             goto fail;
1573     }
1574
1575     free (name);
1576
1577     /* Ensure PS name is a valid PDF/PS name object. In PDF names are
1578      * treated as UTF8 and non ASCII bytes, ' ', and '#' are encoded
1579      * as '#' followed by 2 hex digits that encode the byte. By also
1580      * encoding the characters in the reserved string we ensure the
1581      * name is also PS compatible. */
1582     if (ps_name) {
1583         static const char *reserved = "()<>[]{}/%#\\";
1584         char buf[128]; /* max name length is 127 bytes */
1585         char *src = ps_name;
1586         char *dst = buf;
1587
1588         while (*src && dst < buf + 127) {
1589             unsigned char c = *src;
1590             if (c < 0x21 || c > 0x7e || strchr (reserved, c)) {
1591                 if (dst + 4 > buf + 127)
1592                     break;
1593
1594                 snprintf (dst, 4, "#%02X", c);
1595                 src++;
1596                 dst += 3;
1597             } else {
1598                 *dst++ = *src++;
1599             }
1600         }
1601         *dst = 0;
1602         free (ps_name);
1603         ps_name = strdup (buf);
1604         if (ps_name == NULL) {
1605             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1606             goto fail;
1607         }
1608     }
1609
1610     *ps_name_out = ps_name;
1611     *font_name_out = family_name;
1612
1613     return CAIRO_STATUS_SUCCESS;
1614
1615 fail:
1616     free (name);
1617     free (ps_name);
1618     free (family_name);
1619     *ps_name_out = NULL;
1620     *font_name_out = NULL;
1621
1622     return status;
1623 }
1624
1625 cairo_int_status_t
1626 _cairo_truetype_get_style (cairo_scaled_font_t           *scaled_font,
1627                            int                           *weight,
1628                            cairo_bool_t                  *bold,
1629                            cairo_bool_t                  *italic)
1630 {
1631     cairo_status_t status;
1632     const cairo_scaled_font_backend_t *backend;
1633     tt_os2_t os2;
1634     unsigned long size;
1635     uint16_t selection;
1636
1637     backend = scaled_font->backend;
1638     if (!backend->load_truetype_table)
1639         return CAIRO_INT_STATUS_UNSUPPORTED;
1640
1641     size = 0;
1642     status = backend->load_truetype_table (scaled_font,
1643                                            TT_TAG_OS2, 0,
1644                                            NULL,
1645                                            &size);
1646     if (status)
1647         return status;
1648
1649     if (size < sizeof(os2))
1650         return CAIRO_INT_STATUS_UNSUPPORTED;
1651
1652     size = sizeof (os2);
1653     status = backend->load_truetype_table (scaled_font,
1654                                            TT_TAG_OS2, 0,
1655                                            (unsigned char *) &os2,
1656                                            &size);
1657     if (status)
1658         return status;
1659
1660     *weight = be16_to_cpu (os2.usWeightClass);
1661     selection = be16_to_cpu (os2.fsSelection);
1662     *bold = (selection & TT_FS_SELECTION_BOLD) ? TRUE : FALSE;
1663     *italic = (selection & TT_FS_SELECTION_ITALIC) ? TRUE : FALSE;
1664
1665     return CAIRO_STATUS_SUCCESS;
1666 }
1667
1668 #endif /* CAIRO_HAS_FONT_SUBSET */