1
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2
/* cairo - a vector graphics library with display and print output
3
 *
4
 * Copyright © 2004 Red Hat, Inc
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it either under the terms of the GNU Lesser General Public
8
 * License version 2.1 as published by the Free Software Foundation
9
 * (the "LGPL") or, at your option, under the terms of the Mozilla
10
 * Public License Version 1.1 (the "MPL"). If you do not alter this
11
 * notice, a recipient may use your version of this file under either
12
 * the MPL or the LGPL.
13
 *
14
 * You should have received a copy of the LGPL along with this library
15
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
17
 * You should have received a copy of the MPL along with this library
18
 * in the file COPYING-MPL-1.1
19
 *
20
 * The contents of this file are subject to the Mozilla Public License
21
 * Version 1.1 (the "License"); you may not use this file except in
22
 * compliance with the License. You may obtain a copy of the License at
23
 * http://www.mozilla.org/MPL/
24
 *
25
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27
 * the specific language governing rights and limitations.
28
 *
29
 * The Original Code is the cairo graphics library.
30
 *
31
 * The Initial Developer of the Original Code is Red Hat, Inc.
32
 *
33
 * Contributor(s):
34
 *	Kristian Høgsberg <krh@redhat.com>
35
 *	Adrian Johnson <ajohnson@redneon.com>
36
 */
37

            
38
/*
39
 * Useful links:
40
 * http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6.html
41
 * http://www.microsoft.com/typography/specs/default.htm
42
 */
43

            
44
#define _DEFAULT_SOURCE /* for snprintf(), strdup() */
45
#include "cairoint.h"
46

            
47
#include "cairo-array-private.h"
48
#include "cairo-error-private.h"
49

            
50
#if CAIRO_HAS_FONT_SUBSET
51

            
52
#include "cairo-scaled-font-subsets-private.h"
53
#include "cairo-truetype-subset-private.h"
54

            
55

            
56
typedef struct subset_glyph subset_glyph_t;
57
struct subset_glyph {
58
    int parent_index;
59
    unsigned long location;
60
};
61

            
62
typedef struct _cairo_truetype_font cairo_truetype_font_t;
63

            
64
typedef struct table table_t;
65
struct table {
66
    unsigned long tag;
67
    cairo_status_t (*write) (cairo_truetype_font_t *font, unsigned long tag);
68
    int pos; /* position in the font directory */
69
};
70

            
71
struct _cairo_truetype_font {
72

            
73
    cairo_scaled_font_subset_t *scaled_font_subset;
74

            
75
    table_t truetype_tables[10];
76
    int num_tables;
77

            
78
    struct {
79
	char *font_name;
80
	char *ps_name;
81
	int num_glyphs_in_face; /* glyphs in font */
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; /* array size: num_glyphs_in_face + 2 */
88
    const cairo_scaled_font_backend_t *backend;
89
    unsigned int num_glyphs; /* glyphs used */
90
    int *widths; /* array size: num_glyphs_in_face  + 1 */
91
    int checksum_index;
92
    cairo_array_t output;
93
    cairo_array_t string_offsets;
94
    unsigned long last_offset;
95
    unsigned long last_boundary;
96
    int *parent_to_subset; /* array size: num_glyphs_in_face + 1 */
97
    cairo_status_t status;
98
    cairo_bool_t is_pdf;
99
};
100

            
101
/*
102
 * Test that the structs we define for TrueType tables have the
103
 * correct size, ie. they are not padded.
104
 */
105
#define check(T, S) COMPILE_TIME_ASSERT (sizeof (T) == (S))
106
check (tt_head_t,	54);
107
check (tt_hhea_t,	36);
108
check (tt_maxp_t,	32);
109
check (tt_name_record_t, 12);
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_bool_t is_synthetic;
143
    cairo_truetype_font_t *font;
144
    const cairo_scaled_font_backend_t *backend;
145
    tt_head_t head;
146
    tt_hhea_t hhea;
147
    tt_maxp_t maxp;
148
    unsigned long size;
149

            
150
    backend = scaled_font_subset->scaled_font->backend;
151
    if (!backend->load_truetype_table)
152
	return CAIRO_INT_STATUS_UNSUPPORTED;
153

            
154
    /* FIXME: We should either support subsetting vertical fonts, or fail on
155
     * vertical.  Currently font_options_t doesn't have vertical flag, but
156
     * it should be added in the future.  For now, the freetype backend
157
     * returns UNSUPPORTED in load_truetype_table if the font is vertical.
158
     *
159
     *  if (cairo_font_options_get_vertical_layout (scaled_font_subset->scaled_font))
160
     *   return CAIRO_INT_STATUS_UNSUPPORTED;
161
     */
162

            
163
    /* We need to use a fallback font if this font differs from the glyf outlines. */
164
    if (backend->is_synthetic) {
165
	status = backend->is_synthetic (scaled_font_subset->scaled_font, &is_synthetic);
166
	if (unlikely (status))
167
	    return status;
168

            
169
	if (is_synthetic)
170
	    return CAIRO_INT_STATUS_UNSUPPORTED;
171
    }
172

            
173
    size = sizeof (tt_head_t);
174
    status = backend->load_truetype_table (scaled_font_subset->scaled_font,
175
                                          TT_TAG_head, 0,
176
					  (unsigned char *) &head,
177
                                          &size);
178
    if (unlikely (status))
179
	return status;
180

            
181
    size = sizeof (tt_maxp_t);
182
    status = backend->load_truetype_table (scaled_font_subset->scaled_font,
183
                                           TT_TAG_maxp, 0,
184
					   (unsigned char *) &maxp,
185
					   &size);
186
    if (unlikely (status))
187
	return status;
188

            
189
    size = sizeof (tt_hhea_t);
190
    status = backend->load_truetype_table (scaled_font_subset->scaled_font,
191
                                           TT_TAG_hhea, 0,
192
					   (unsigned char *) &hhea,
193
					   &size);
194
    if (unlikely (status))
195
	return status;
196

            
197
    font = _cairo_calloc (sizeof (cairo_truetype_font_t));
198
    if (unlikely (font == NULL))
199
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
200

            
201
    font->backend = backend;
202
    font->base.num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs);
203
    font->scaled_font_subset = scaled_font_subset;
204

            
205
    font->last_offset = 0;
206
    font->last_boundary = 0;
207
    _cairo_array_init (&font->output, sizeof (char));
208
    status = _cairo_array_grow_by (&font->output, 4096);
209
    if (unlikely (status))
210
	goto fail1;
211

            
212
    /* Add 2: +1 case font does not contain .notdef, and +1 because an extra
213
     * entry is required to contain the end location of the last glyph.
214
     */
215
    font->glyphs = _cairo_calloc_ab (font->base.num_glyphs_in_face + 2, sizeof (subset_glyph_t));
216
    if (unlikely (font->glyphs == NULL)) {
217
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
218
	goto fail1;
219
    }
220

            
221
    /* Add 1 in case font does not contain .notdef */
222
    font->parent_to_subset = _cairo_calloc_ab (font->base.num_glyphs_in_face + 1, sizeof (int));
223
    if (unlikely (font->parent_to_subset == NULL)) {
224
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
225
	goto fail2;
226
    }
227

            
228
    font->is_pdf = is_pdf;
229
    font->num_glyphs = 0;
230
    font->base.x_min = (int16_t) be16_to_cpu (head.x_min);
231
    font->base.y_min = (int16_t) be16_to_cpu (head.y_min);
232
    font->base.x_max = (int16_t) be16_to_cpu (head.x_max);
233
    font->base.y_max = (int16_t) be16_to_cpu (head.y_max);
234
    font->base.ascent = (int16_t) be16_to_cpu (hhea.ascender);
235
    font->base.descent = (int16_t) be16_to_cpu (hhea.descender);
236
    font->base.units_per_em = (int16_t) be16_to_cpu (head.units_per_em);
237
    if (font->base.units_per_em == 0)
238
        font->base.units_per_em = 2048;
239

            
240
    font->base.ps_name = NULL;
241
    font->base.font_name = NULL;
242
    status = _cairo_truetype_read_font_name (scaled_font_subset->scaled_font,
243
					     &font->base.ps_name,
244
					     &font->base.font_name);
245
    if (_cairo_status_is_error (status))
246
	goto fail3;
247

            
248
    /* If the PS name is not found, create a CairoFont-x-y name. */
249
    if (font->base.ps_name == NULL) {
250
        font->base.ps_name = _cairo_malloc (30);
251
        if (unlikely (font->base.ps_name == NULL)) {
252
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
253
            goto fail3;
254
	}
255

            
256
        snprintf(font->base.ps_name, 30, "CairoFont-%u-%u",
257
                 scaled_font_subset->font_id,
258
                 scaled_font_subset->subset_id);
259
    }
260

            
261
    /* Add 1 in case font does not contain .notdef */
262
    font->widths = _cairo_calloc_ab (font->base.num_glyphs_in_face + 1, sizeof (int));
263
    if (unlikely (font->widths == NULL)) {
264
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
265
	goto fail4;
266
    }
267

            
268
    _cairo_array_init (&font->string_offsets, sizeof (unsigned long));
269
    status = _cairo_array_grow_by (&font->string_offsets, 10);
270
    if (unlikely (status))
271
	goto fail5;
272

            
273
    font->status = CAIRO_STATUS_SUCCESS;
274

            
275
    *font_return = font;
276

            
277
    return CAIRO_STATUS_SUCCESS;
278

            
279
 fail5:
280
    _cairo_array_fini (&font->string_offsets);
281
    free (font->widths);
282
 fail4:
283
    free (font->base.ps_name);
284
 fail3:
285
    free (font->parent_to_subset);
286
    free (font->base.font_name);
287
 fail2:
288
    free (font->glyphs);
289
 fail1:
290
    _cairo_array_fini (&font->output);
291
    free (font);
292

            
293
    return status;
294
}
295

            
296
static void
297
cairo_truetype_font_destroy (cairo_truetype_font_t *font)
298
{
299
    _cairo_array_fini (&font->string_offsets);
300
    free (font->widths);
301
    free (font->base.ps_name);
302
    free (font->base.font_name);
303
    free (font->parent_to_subset);
304
    free (font->glyphs);
305
    _cairo_array_fini (&font->output);
306
    free (font);
307
}
308

            
309
static cairo_status_t
310
cairo_truetype_font_allocate_write_buffer (cairo_truetype_font_t  *font,
311
					   size_t		   length,
312
					   unsigned char	 **buffer)
313
{
314
    cairo_status_t status;
315

            
316
    if (font->status)
317
	return font->status;
318

            
319
    status = _cairo_array_allocate (&font->output, length, (void **) buffer);
320
    if (unlikely (status))
321
	return _cairo_truetype_font_set_error (font, status);
322

            
323
    return CAIRO_STATUS_SUCCESS;
324
}
325

            
326
static void
327
cairo_truetype_font_write (cairo_truetype_font_t *font,
328
			   const void            *data,
329
			   size_t                 length)
330
{
331
    cairo_status_t status;
332

            
333
    if (font->status)
334
	return;
335

            
336
    status = _cairo_array_append_multiple (&font->output, data, length);
337
    if (unlikely (status))
338
	status = _cairo_truetype_font_set_error (font, status);
339
}
340

            
341
static void
342
cairo_truetype_font_write_be16 (cairo_truetype_font_t *font,
343
				uint16_t               value)
344
{
345
    uint16_t be16_value;
346

            
347
    if (font->status)
348
	return;
349

            
350
    be16_value = cpu_to_be16 (value);
351
    cairo_truetype_font_write (font, &be16_value, sizeof be16_value);
352
}
353

            
354
static void
355
cairo_truetype_font_write_be32 (cairo_truetype_font_t *font,
356
				uint32_t               value)
357
{
358
    uint32_t be32_value;
359

            
360
    if (font->status)
361
	return;
362

            
363
    be32_value = cpu_to_be32 (value);
364
    cairo_truetype_font_write (font, &be32_value, sizeof be32_value);
365
}
366

            
367
static cairo_status_t
368
cairo_truetype_font_align_output (cairo_truetype_font_t	    *font,
369
	                          unsigned long		    *aligned)
370
{
371
    int length, pad;
372
    unsigned char *padding;
373

            
374
    length = _cairo_array_num_elements (&font->output);
375
    *aligned = (length + 3) & ~3;
376
    pad = *aligned - length;
377

            
378
    if (pad) {
379
	cairo_status_t status;
380

            
381
	status = cairo_truetype_font_allocate_write_buffer (font, pad,
382
		                                            &padding);
383
	if (unlikely (status))
384
	    return status;
385

            
386
	memset (padding, 0, pad);
387
    }
388

            
389
    return CAIRO_STATUS_SUCCESS;
390
}
391

            
392
static cairo_status_t
393
cairo_truetype_font_check_boundary (cairo_truetype_font_t *font,
394
				    unsigned long          boundary)
395
{
396
    cairo_status_t status;
397

            
398
    if (font->status)
399
	return font->status;
400

            
401
    if (boundary - font->last_offset > SFNT_STRING_MAX_LENGTH)
402
    {
403
        status = _cairo_array_append (&font->string_offsets,
404
				      &font->last_boundary);
405
	if (unlikely (status))
406
	    return _cairo_truetype_font_set_error (font, status);
407

            
408
        font->last_offset = font->last_boundary;
409
    }
410
    font->last_boundary = boundary;
411

            
412
    return CAIRO_STATUS_SUCCESS;
413
}
414

            
415
typedef struct _cmap_unicode_range {
416
    unsigned int start;
417
    unsigned int end;
418
} cmap_unicode_range_t;
419

            
420
static cmap_unicode_range_t winansi_unicode_ranges[] = {
421
    { 0x0020, 0x007f },
422
    { 0x00a0, 0x00ff },
423
    { 0x0152, 0x0153 },
424
    { 0x0160, 0x0161 },
425
    { 0x0178, 0x0178 },
426
    { 0x017d, 0x017e },
427
    { 0x0192, 0x0192 },
428
    { 0x02c6, 0x02c6 },
429
    { 0x02dc, 0x02dc },
430
    { 0x2013, 0x2026 },
431
    { 0x2030, 0x2030 },
432
    { 0x2039, 0x203a },
433
    { 0x20ac, 0x20ac },
434
    { 0x2122, 0x2122 },
435
};
436

            
437
static cairo_status_t
438
cairo_truetype_font_write_cmap_table (cairo_truetype_font_t *font,
439
				      unsigned long          tag)
440
{
441
    int i;
442
    unsigned int j;
443
    int range_offset;
444
    int num_ranges;
445
    int entry_selector;
446
    int length;
447

            
448
    num_ranges = ARRAY_LENGTH (winansi_unicode_ranges);
449

            
450
    length = 16 + (num_ranges + 1)*8;
451
    for (i = 0; i < num_ranges; i++)
452
	length += (winansi_unicode_ranges[i].end - winansi_unicode_ranges[i].start + 1)*2;
453

            
454
    entry_selector = 0;
455
    while ((1 << entry_selector) <= (num_ranges + 1))
456
	entry_selector++;
457

            
458
    entry_selector--;
459

            
460
    cairo_truetype_font_write_be16 (font, 0);  /* Table version */
461
    cairo_truetype_font_write_be16 (font, 1);  /* Num tables */
462

            
463
    cairo_truetype_font_write_be16 (font, 3);  /* Platform */
464
    cairo_truetype_font_write_be16 (font, 1);  /* Encoding */
465
    cairo_truetype_font_write_be32 (font, 12); /* Offset to start of table */
466

            
467
    /* Output a format 4 encoding table for the winansi encoding */
468

            
469
    cairo_truetype_font_write_be16 (font, 4);  /* Format */
470
    cairo_truetype_font_write_be16 (font, length); /* Length */
471
    cairo_truetype_font_write_be16 (font, 0);  /* Version */
472
    cairo_truetype_font_write_be16 (font, num_ranges*2 + 2);  /* 2*segcount */
473
    cairo_truetype_font_write_be16 (font, (1 << (entry_selector + 1)));  /* searchrange */
474
    cairo_truetype_font_write_be16 (font, entry_selector);  /* entry selector */
475
    cairo_truetype_font_write_be16 (font, num_ranges*2 + 2 - (1 << (entry_selector + 1)));  /* rangeshift */
476
    for (i = 0; i < num_ranges; i++)
477
	cairo_truetype_font_write_be16 (font, winansi_unicode_ranges[i].end); /* end count[] */
478
    cairo_truetype_font_write_be16 (font, 0xffff);  /* end count[] */
479

            
480
    cairo_truetype_font_write_be16 (font, 0);       /* reserved */
481

            
482
    for (i = 0; i < num_ranges; i++)
483
	cairo_truetype_font_write_be16 (font, winansi_unicode_ranges[i].start);  /* startCode[] */
484
    cairo_truetype_font_write_be16 (font, 0xffff);  /* startCode[] */
485

            
486
    for (i = 0; i < num_ranges; i++)
487
	cairo_truetype_font_write_be16 (font, 0x0000);  /* delta[] */
488
    cairo_truetype_font_write_be16 (font, 1);       /* delta[] */
489

            
490
    range_offset = num_ranges*2 + 2;
491
    for (i = 0; i < num_ranges; i++) {
492
	cairo_truetype_font_write_be16 (font, range_offset);       /* rangeOffset[] */
493
	range_offset += (winansi_unicode_ranges[i].end - winansi_unicode_ranges[i].start + 1)*2 - 2;
494
    }
495
    cairo_truetype_font_write_be16 (font, 0);       /* rangeOffset[] */
496

            
497
    for (i = 0; i < num_ranges; i++) {
498
	for (j = winansi_unicode_ranges[i].start; j < winansi_unicode_ranges[i].end + 1; j++) {
499
	    int ch = _cairo_unicode_to_winansi (j);
500
	    int glyph;
501

            
502
	    if (ch > 0)
503
		glyph = font->scaled_font_subset->latin_to_subset_glyph_index[ch];
504
	    else
505
		glyph = 0;
506
	    cairo_truetype_font_write_be16 (font, glyph);
507
	}
508
    }
509

            
510
    return font->status;
511
}
512

            
513
static cairo_status_t
514
cairo_truetype_font_write_generic_table (cairo_truetype_font_t *font,
515
					 unsigned long          tag)
516
{
517
    cairo_status_t status;
518
    unsigned char *buffer;
519
    unsigned long size;
520

            
521
    if (font->status)
522
	return font->status;
523

            
524
    size = 0;
525
    status = font->backend->load_truetype_table(font->scaled_font_subset->scaled_font,
526
					        tag, 0, NULL, &size);
527
    if (unlikely (status))
528
        return _cairo_truetype_font_set_error (font, status);
529

            
530
    status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
531
    if (unlikely (status))
532
	return _cairo_truetype_font_set_error (font, status);
533

            
534
    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
535
						 tag, 0, buffer, &size);
536
    if (unlikely (status))
537
	return _cairo_truetype_font_set_error (font, status);
538

            
539
    return CAIRO_STATUS_SUCCESS;
540
}
541

            
542
static cairo_status_t
543
cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t	*font,
544
					   unsigned char		*buffer,
545
					   unsigned long		 size)
546
{
547
    tt_glyph_data_t *glyph_data;
548
    tt_composite_glyph_t *composite_glyph;
549
    int num_args;
550
    int has_more_components;
551
    unsigned short flags;
552
    unsigned short index;
553
    cairo_status_t status;
554
    unsigned char *end = buffer + size;
555

            
556
    if (font->status)
557
	return font->status;
558

            
559
    glyph_data = (tt_glyph_data_t *) buffer;
560
    if ((unsigned char *)(&glyph_data->data) >= end)
561
	return CAIRO_INT_STATUS_UNSUPPORTED;
562

            
563
    if ((int16_t)be16_to_cpu (glyph_data->num_contours) >= 0)
564
        return CAIRO_STATUS_SUCCESS;
565

            
566
    composite_glyph = &glyph_data->glyph;
567
    do {
568
	if ((unsigned char *)(&composite_glyph->args[1]) > end)
569
	    return CAIRO_INT_STATUS_UNSUPPORTED;
570

            
571
	flags = be16_to_cpu (composite_glyph->flags);
572
        has_more_components = flags & TT_MORE_COMPONENTS;
573
        status = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index), &index);
574
	if (unlikely (status))
575
	    return status;
576

            
577
        composite_glyph->index = cpu_to_be16 (index);
578
        num_args = 1;
579
        if (flags & TT_ARG_1_AND_2_ARE_WORDS)
580
            num_args += 1;
581

            
582
	if (flags & TT_WE_HAVE_A_SCALE)
583
            num_args += 1;
584
        else if (flags & TT_WE_HAVE_AN_X_AND_Y_SCALE)
585
            num_args += 2;
586
        else if (flags & TT_WE_HAVE_A_TWO_BY_TWO)
587
            num_args += 4;
588

            
589
	composite_glyph = (tt_composite_glyph_t *) &(composite_glyph->args[num_args]);
590
    } while (has_more_components);
591

            
592
    return CAIRO_STATUS_SUCCESS;
593
}
594

            
595
static cairo_status_t
596
cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
597
				      unsigned long          tag)
598
{
599
    unsigned long start_offset, index, size, next;
600
    tt_head_t header;
601
    unsigned long begin, end;
602
    unsigned char *buffer;
603
    unsigned int i;
604
    union {
605
	unsigned char *bytes;
606
	uint16_t      *short_offsets;
607
	uint32_t      *long_offsets;
608
    } u;
609
    cairo_status_t status;
610

            
611
    if (font->status)
612
	return font->status;
613

            
614
    size = sizeof (tt_head_t);
615
    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
616
						 TT_TAG_head, 0,
617
						 (unsigned char*) &header, &size);
618
    if (unlikely (status))
619
	return _cairo_truetype_font_set_error (font, status);
620

            
621
    if (be16_to_cpu (header.index_to_loc_format) == 0)
622
	size = sizeof (int16_t) * (font->base.num_glyphs_in_face + 1);
623
    else
624
	size = sizeof (int32_t) * (font->base.num_glyphs_in_face + 1);
625

            
626
    u.bytes = _cairo_malloc (size);
627
    if (unlikely (u.bytes == NULL))
628
	return _cairo_truetype_font_set_error (font, CAIRO_STATUS_NO_MEMORY);
629

            
630
    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
631
                                                 TT_TAG_loca, 0, u.bytes, &size);
632
    if (unlikely (status)) {
633
	free (u.bytes);
634
	return _cairo_truetype_font_set_error (font, status);
635
    }
636

            
637
    start_offset = _cairo_array_num_elements (&font->output);
638
    for (i = 0; i < font->num_glyphs; i++) {
639
	index = font->glyphs[i].parent_index;
640
	if (be16_to_cpu (header.index_to_loc_format) == 0) {
641
	    begin = be16_to_cpu (u.short_offsets[index]) * 2;
642
	    end = be16_to_cpu (u.short_offsets[index + 1]) * 2;
643
	}
644
	else {
645
	    begin = be32_to_cpu (u.long_offsets[index]);
646
	    end = be32_to_cpu (u.long_offsets[index + 1]);
647
	}
648

            
649
	/* quick sanity check... */
650
	if (end < begin) {
651
	    status = CAIRO_INT_STATUS_UNSUPPORTED;
652
	    goto FAIL;
653
	}
654

            
655
	size = end - begin;
656
        status = cairo_truetype_font_align_output (font, &next);
657
	if (unlikely (status))
658
	    goto FAIL;
659

            
660
        status = cairo_truetype_font_check_boundary (font, next);
661
	if (unlikely (status))
662
	    goto FAIL;
663

            
664
        font->glyphs[i].location = next - start_offset;
665

            
666
	status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
667
	if (unlikely (status))
668
	    goto FAIL;
669

            
670
	if (size > 1) {
671
	    tt_glyph_data_t *glyph_data;
672
	    int num_contours;
673

            
674
	    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
675
							 TT_TAG_glyf, begin, buffer, &size);
676
	    if (unlikely (status))
677
		goto FAIL;
678

            
679
	    glyph_data = (tt_glyph_data_t *) buffer;
680
	    num_contours = (int16_t)be16_to_cpu (glyph_data->num_contours);
681
	    if (num_contours < 0) {
682
		status = cairo_truetype_font_remap_composite_glyph (font, buffer, size);
683
		if (unlikely (status))
684
		    goto FAIL;
685
	    } else if (num_contours == 0) {
686
		/* num_contours == 0 is undefined in the Opentype
687
		 * spec. There are some embedded fonts that have a
688
		 * space glyph with num_contours = 0 that fails on
689
		 * some printers. The spec requires glyphs without
690
		 * contours to have a 0 size glyph entry in the loca
691
		 * table.
692
		 *
693
		 * If num_contours == 0, truncate the glyph to 0 size.
694
		 */
695
		_cairo_array_truncate (&font->output, _cairo_array_num_elements (&font->output) - size);
696
	    }
697
	}
698
    }
699

            
700
    status = cairo_truetype_font_align_output (font, &next);
701
    if (unlikely (status))
702
	goto FAIL;
703

            
704
    font->glyphs[i].location = next - start_offset;
705

            
706
    status = font->status;
707
FAIL:
708
    free (u.bytes);
709

            
710
    return _cairo_truetype_font_set_error (font, status);
711
}
712

            
713
static cairo_status_t
714
cairo_truetype_font_write_head_table (cairo_truetype_font_t *font,
715
                                      unsigned long          tag)
716
{
717
    unsigned char *buffer;
718
    unsigned long size;
719
    cairo_status_t status;
720

            
721
    if (font->status)
722
	return font->status;
723

            
724
    size = 0;
725
    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
726
						 tag, 0, NULL, &size);
727
    if (unlikely (status))
728
	return _cairo_truetype_font_set_error (font, status);
729

            
730
    font->checksum_index = _cairo_array_num_elements (&font->output) + 8;
731
    status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
732
    if (unlikely (status))
733
	return _cairo_truetype_font_set_error (font, status);
734

            
735
    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
736
						 tag, 0, buffer, &size);
737
    if (unlikely (status))
738
	return _cairo_truetype_font_set_error (font, status);
739

            
740
    /* set checkSumAdjustment to 0 for table checksum calculation */
741
    *(uint32_t *)(buffer + 8) = 0;
742

            
743
    return CAIRO_STATUS_SUCCESS;
744
}
745

            
746
static cairo_status_t
747
cairo_truetype_font_write_hhea_table (cairo_truetype_font_t *font, unsigned long tag)
748
{
749
    tt_hhea_t *hhea;
750
    unsigned long size;
751
    cairo_status_t status;
752

            
753
    if (font->status)
754
	return font->status;
755

            
756
    size = sizeof (tt_hhea_t);
757
    status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &hhea);
758
    if (unlikely (status))
759
	return _cairo_truetype_font_set_error (font, status);
760

            
761
    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
762
						 tag, 0, (unsigned char *) hhea, &size);
763
    if (unlikely (status))
764
	return _cairo_truetype_font_set_error (font, status);
765

            
766
    hhea->num_hmetrics = cpu_to_be16 ((uint16_t)(font->num_glyphs));
767

            
768
    return CAIRO_STATUS_SUCCESS;
769
}
770

            
771
static cairo_status_t
772
cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font,
773
				      unsigned long          tag)
774
{
775
    unsigned long size;
776
    unsigned long long_entry_size;
777
    unsigned long short_entry_size;
778
    short *p;
779
    unsigned int i;
780
    tt_hhea_t hhea;
781
    int num_hmetrics;
782
    cairo_status_t status;
783

            
784
    if (font->status)
785
	return font->status;
786

            
787
    size = sizeof (tt_hhea_t);
788
    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
789
						 TT_TAG_hhea, 0,
790
						 (unsigned char*) &hhea, &size);
791
    if (unlikely (status))
792
	return _cairo_truetype_font_set_error (font, status);
793

            
794
    num_hmetrics = be16_to_cpu(hhea.num_hmetrics);
795

            
796
    for (i = 0; i < font->num_glyphs; i++) {
797
        long_entry_size = 2 * sizeof (int16_t);
798
        short_entry_size = sizeof (int16_t);
799
        status = cairo_truetype_font_allocate_write_buffer (font,
800
		                                            long_entry_size,
801
							    (unsigned char **) &p);
802
	if (unlikely (status))
803
	    return _cairo_truetype_font_set_error (font, status);
804

            
805
        if (font->glyphs[i].parent_index < num_hmetrics) {
806
            status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
807
                                                         TT_TAG_hmtx,
808
                                                         font->glyphs[i].parent_index * long_entry_size,
809
                                                         (unsigned char *) p, &long_entry_size);
810
	    if (unlikely (status))
811
		return _cairo_truetype_font_set_error (font, status);
812
        }
813
        else
814
        {
815
            status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
816
                                                         TT_TAG_hmtx,
817
							 (num_hmetrics - 1) * long_entry_size,
818
							 (unsigned char *) p, &short_entry_size);
819
	    if (unlikely (status))
820
		return _cairo_truetype_font_set_error (font, status);
821

            
822
            status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
823
							 TT_TAG_hmtx,
824
							 num_hmetrics * long_entry_size +
825
							 (font->glyphs[i].parent_index - num_hmetrics) * short_entry_size,
826
							 (unsigned char *) (p + 1), &short_entry_size);
827
	    if (unlikely (status))
828
		return _cairo_truetype_font_set_error (font, status);
829
        }
830
        font->widths[i] = be16_to_cpu (p[0]);
831
    }
832

            
833
    return CAIRO_STATUS_SUCCESS;
834
}
835

            
836
static cairo_status_t
837
cairo_truetype_font_write_loca_table (cairo_truetype_font_t *font,
838
				      unsigned long          tag)
839
{
840
    unsigned int i;
841
    tt_head_t header;
842
    unsigned long size;
843
    cairo_status_t status;
844

            
845
    if (font->status)
846
	return font->status;
847

            
848
    size = sizeof(tt_head_t);
849
    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
850
						 TT_TAG_head, 0,
851
						 (unsigned char*) &header, &size);
852
    if (unlikely (status))
853
	return _cairo_truetype_font_set_error (font, status);
854

            
855
    if (be16_to_cpu (header.index_to_loc_format) == 0)
856
    {
857
	for (i = 0; i < font->num_glyphs + 1; i++)
858
	    cairo_truetype_font_write_be16 (font, font->glyphs[i].location / 2);
859
    } else {
860
	for (i = 0; i < font->num_glyphs + 1; i++)
861
	    cairo_truetype_font_write_be32 (font, font->glyphs[i].location);
862
    }
863

            
864
    return font->status;
865
}
866

            
867
static cairo_status_t
868
cairo_truetype_font_write_maxp_table (cairo_truetype_font_t *font,
869
				      unsigned long          tag)
870
{
871
    tt_maxp_t *maxp;
872
    unsigned long size;
873
    cairo_status_t status;
874

            
875
    if (font->status)
876
	return font->status;
877

            
878
    size = sizeof (tt_maxp_t);
879
    status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
880
    if (unlikely (status))
881
	return _cairo_truetype_font_set_error (font, status);
882

            
883
    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
884
						 tag, 0, (unsigned char *) maxp, &size);
885
    if (unlikely (status))
886
	return _cairo_truetype_font_set_error (font, status);
887

            
888
    maxp->num_glyphs = cpu_to_be16 (font->num_glyphs);
889

            
890
    return CAIRO_STATUS_SUCCESS;
891
}
892

            
893
static cairo_status_t
894
cairo_truetype_font_write_offset_table (cairo_truetype_font_t *font)
895
{
896
    cairo_status_t status;
897
    unsigned char *table_buffer;
898
    size_t table_buffer_length;
899
    unsigned short search_range, entry_selector, range_shift;
900

            
901
    if (font->status)
902
	return font->status;
903

            
904
    search_range = 1;
905
    entry_selector = 0;
906
    while (search_range * 2 <= font->num_tables) {
907
	search_range *= 2;
908
	entry_selector++;
909
    }
910
    search_range *= 16;
911
    range_shift = font->num_tables * 16 - search_range;
912

            
913
    cairo_truetype_font_write_be32 (font, SFNT_VERSION);
914
    cairo_truetype_font_write_be16 (font, font->num_tables);
915
    cairo_truetype_font_write_be16 (font, search_range);
916
    cairo_truetype_font_write_be16 (font, entry_selector);
917
    cairo_truetype_font_write_be16 (font, range_shift);
918

            
919
    /* Allocate space for the table directory. Each directory entry
920
     * will be filled in by cairo_truetype_font_update_entry() after
921
     * the table is written. */
922
    table_buffer_length = font->num_tables * 16;
923
    status = cairo_truetype_font_allocate_write_buffer (font, table_buffer_length,
924
						      &table_buffer);
925
    if (unlikely (status))
926
	return _cairo_truetype_font_set_error (font, status);
927

            
928
    return CAIRO_STATUS_SUCCESS;
929
}
930

            
931
static uint32_t
932
cairo_truetype_font_calculate_checksum (cairo_truetype_font_t *font,
933
					unsigned long          start,
934
					unsigned long          end)
935
{
936
    uint32_t *padded_end;
937
    uint32_t *p;
938
    uint32_t checksum;
939
    char *data;
940

            
941
    checksum = 0;
942
    data = _cairo_array_index (&font->output, 0);
943
    p = (uint32_t *) (data + start);
944
    padded_end = (uint32_t *) (data + ((end + 3) & ~3));
945
    while (p < padded_end)
946
	checksum += be32_to_cpu(*p++);
947

            
948
    return checksum;
949
}
950

            
951
static void
952
cairo_truetype_font_update_entry (cairo_truetype_font_t *font,
953
				  int                    index,
954
				  unsigned long          tag,
955
				  unsigned long          start,
956
				  unsigned long          end)
957
{
958
    uint32_t *entry;
959

            
960
    entry = _cairo_array_index (&font->output, 12 + 16 * index);
961
    entry[0] = cpu_to_be32 ((uint32_t)tag);
962
    entry[1] = cpu_to_be32 (cairo_truetype_font_calculate_checksum (font, start, end));
963
    entry[2] = cpu_to_be32 ((uint32_t)start);
964
    entry[3] = cpu_to_be32 ((uint32_t)(end - start));
965
}
966

            
967
static cairo_status_t
968
cairo_truetype_font_generate (cairo_truetype_font_t  *font,
969
			      const char            **data,
970
			      unsigned long          *length,
971
			      const unsigned long   **string_offsets,
972
			      unsigned long          *num_strings)
973
{
974
    cairo_status_t status;
975
    unsigned long start, end, next;
976
    uint32_t checksum, *checksum_location;
977
    int i;
978

            
979
    if (font->status)
980
	return font->status;
981

            
982
    status = cairo_truetype_font_write_offset_table (font);
983
    if (unlikely (status))
984
	goto FAIL;
985

            
986
    status = cairo_truetype_font_align_output (font, &start);
987
    if (unlikely (status))
988
	goto FAIL;
989

            
990
    end = 0;
991
    for (i = 0; i < font->num_tables; i++) {
992
	status = font->truetype_tables[i].write (font, font->truetype_tables[i].tag);
993
	if (unlikely (status))
994
	    goto FAIL;
995

            
996
	end = _cairo_array_num_elements (&font->output);
997
	status = cairo_truetype_font_align_output (font, &next);
998
	if (unlikely (status))
999
	    goto FAIL;
	cairo_truetype_font_update_entry (font, font->truetype_tables[i].pos,
                                          font->truetype_tables[i].tag, start, end);
        status = cairo_truetype_font_check_boundary (font, next);
	if (unlikely (status))
	    goto FAIL;
	start = next;
    }
    checksum =
	0xb1b0afba - cairo_truetype_font_calculate_checksum (font, 0, end);
    checksum_location = _cairo_array_index (&font->output, font->checksum_index);
    *checksum_location = cpu_to_be32 (checksum);
    *data = _cairo_array_index (&font->output, 0);
    *length = _cairo_array_num_elements (&font->output);
    *num_strings = _cairo_array_num_elements (&font->string_offsets);
    if (*num_strings != 0)
	*string_offsets = _cairo_array_index (&font->string_offsets, 0);
    else
	*string_offsets = NULL;
 FAIL:
    return _cairo_truetype_font_set_error (font, status);
}
static cairo_status_t
cairo_truetype_font_use_glyph (cairo_truetype_font_t	    *font,
	                       unsigned short		     glyph,
			       unsigned short		    *out)
{
    if (glyph >= font->base.num_glyphs_in_face)
	return CAIRO_INT_STATUS_UNSUPPORTED;
    if (font->parent_to_subset[glyph] == 0) {
	font->parent_to_subset[glyph] = font->num_glyphs;
	font->glyphs[font->num_glyphs].parent_index = glyph;
	font->num_glyphs++;
    }
    *out = font->parent_to_subset[glyph];
    return CAIRO_STATUS_SUCCESS;
}
static void
cairo_truetype_font_add_truetype_table (cairo_truetype_font_t *font,
           unsigned long tag,
           cairo_status_t (*write) (cairo_truetype_font_t *font, unsigned long tag),
           int pos)
{
    font->truetype_tables[font->num_tables].tag = tag;
    font->truetype_tables[font->num_tables].write = write;
    font->truetype_tables[font->num_tables].pos = pos;
    font->num_tables++;
}
/* cairo_truetype_font_create_truetype_table_list() builds the list of
 * truetype tables to be embedded in the subsetted font. Each call to
 * cairo_truetype_font_add_truetype_table() adds a table, the callback
 * for generating the table, and the position in the table directory
 * to the truetype_tables array.
 *
 * As we write out the glyf table we remap composite glyphs.
 * Remapping composite glyphs will reference the sub glyphs the
 * composite glyph is made up of. The "glyf" table callback needs to
 * be called first so we have all the glyphs in the subset before
 * going further.
 *
 * The order in which tables are added to the truetype_table array
 * using cairo_truetype_font_add_truetype_table() specifies the order
 * in which the callback functions will be called.
 *
 * The tables in the table directory must be listed in alphabetical
 * order.  The "cvt", "fpgm", and "prep" are optional tables. They
 * will only be embedded in the subset if they exist in the source
 * font. "cmap" is only embedded for latin fonts. The pos parameter of
 * cairo_truetype_font_add_truetype_table() specifies the position of
 * the table in the table directory.
 */
static void
cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t *font)
{
    cairo_bool_t has_cvt = FALSE;
    cairo_bool_t has_fpgm = FALSE;
    cairo_bool_t has_prep = FALSE;
    unsigned long size;
    int pos;
    size = 0;
    if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                      TT_TAG_cvt, 0, NULL,
                                      &size) == CAIRO_INT_STATUS_SUCCESS)
        has_cvt = TRUE;
    size = 0;
    if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                      TT_TAG_fpgm, 0, NULL,
                                      &size) == CAIRO_INT_STATUS_SUCCESS)
        has_fpgm = TRUE;
    size = 0;
    if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                      TT_TAG_prep, 0, NULL,
                                      &size) == CAIRO_INT_STATUS_SUCCESS)
        has_prep = TRUE;
    font->num_tables = 0;
    pos = 0;
    if (font->is_pdf && font->scaled_font_subset->is_latin)
	pos++;
    if (has_cvt)
        pos++;
    if (has_fpgm)
        pos++;
    cairo_truetype_font_add_truetype_table (font, TT_TAG_glyf, cairo_truetype_font_write_glyf_table, pos);
    pos = 0;
    if (font->is_pdf && font->scaled_font_subset->is_latin)
	cairo_truetype_font_add_truetype_table (font, TT_TAG_cmap, cairo_truetype_font_write_cmap_table, pos++);
    if (has_cvt)
        cairo_truetype_font_add_truetype_table (font, TT_TAG_cvt, cairo_truetype_font_write_generic_table, pos++);
    if (has_fpgm)
        cairo_truetype_font_add_truetype_table (font, TT_TAG_fpgm, cairo_truetype_font_write_generic_table, pos++);
    pos++;
    cairo_truetype_font_add_truetype_table (font, TT_TAG_head, cairo_truetype_font_write_head_table, pos++);
    cairo_truetype_font_add_truetype_table (font, TT_TAG_hhea, cairo_truetype_font_write_hhea_table, pos++);
    cairo_truetype_font_add_truetype_table (font, TT_TAG_hmtx, cairo_truetype_font_write_hmtx_table, pos++);
    cairo_truetype_font_add_truetype_table (font, TT_TAG_loca, cairo_truetype_font_write_loca_table, pos++);
    cairo_truetype_font_add_truetype_table (font, TT_TAG_maxp, cairo_truetype_font_write_maxp_table, pos++);
    if (has_prep)
        cairo_truetype_font_add_truetype_table (font, TT_TAG_prep, cairo_truetype_font_write_generic_table, pos);
}
static cairo_status_t
cairo_truetype_subset_init_internal (cairo_truetype_subset_t     *truetype_subset,
				      cairo_scaled_font_subset_t *font_subset,
				      cairo_bool_t                is_pdf)
{
    cairo_truetype_font_t *font = NULL;
    cairo_status_t status;
    const char *data = NULL; /* squelch bogus compiler warning */
    unsigned long length = 0; /* squelch bogus compiler warning */
    unsigned long offsets_length;
    unsigned int i;
    const unsigned long *string_offsets = NULL;
    unsigned long num_strings = 0;
    status = _cairo_truetype_font_create (font_subset, is_pdf, &font);
    if (unlikely (status))
	return status;
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
	unsigned short parent_glyph = font->scaled_font_subset->glyphs[i];
	status = cairo_truetype_font_use_glyph (font, parent_glyph, &parent_glyph);
	if (unlikely (status))
	    goto fail1;
    }
    cairo_truetype_font_create_truetype_table_list (font);
    status = cairo_truetype_font_generate (font, &data, &length,
                                           &string_offsets, &num_strings);
    if (unlikely (status))
	goto fail1;
    truetype_subset->ps_name = strdup (font->base.ps_name);
    if (unlikely (truetype_subset->ps_name == NULL)) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto fail1;
    }
    if (font->base.font_name != NULL) {
	truetype_subset->family_name_utf8 = strdup (font->base.font_name);
	if (unlikely (truetype_subset->family_name_utf8 == NULL)) {
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	    goto fail2;
	}
    } else {
	truetype_subset->family_name_utf8 = NULL;
    }
    /* The widths array returned must contain only widths for the
     * glyphs in font_subset. Any subglyphs appended after
     * font_subset->num_glyphs are omitted. */
    truetype_subset->widths = _cairo_calloc_ab (font->scaled_font_subset->num_glyphs,
						sizeof (double));
    if (unlikely (truetype_subset->widths == NULL)) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto fail3;
    }
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
	truetype_subset->widths[i] = (double)font->widths[i]/font->base.units_per_em;
    truetype_subset->x_min = (double)font->base.x_min/font->base.units_per_em;
    truetype_subset->y_min = (double)font->base.y_min/font->base.units_per_em;
    truetype_subset->x_max = (double)font->base.x_max/font->base.units_per_em;
    truetype_subset->y_max = (double)font->base.y_max/font->base.units_per_em;
    truetype_subset->ascent = (double)font->base.ascent/font->base.units_per_em;
    truetype_subset->descent = (double)font->base.descent/font->base.units_per_em;
    if (length) {
	truetype_subset->data = _cairo_malloc (length);
	if (unlikely (truetype_subset->data == NULL)) {
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	    goto fail4;
	}
	memcpy (truetype_subset->data, data, length);
    } else
	truetype_subset->data = NULL;
    truetype_subset->data_length = length;
    if (num_strings) {
	offsets_length = num_strings * sizeof (unsigned long);
	truetype_subset->string_offsets = _cairo_malloc (offsets_length);
	if (unlikely (truetype_subset->string_offsets == NULL)) {
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	    goto fail5;
	}
	memcpy (truetype_subset->string_offsets, string_offsets, offsets_length);
	truetype_subset->num_string_offsets = num_strings;
    } else {
	truetype_subset->string_offsets = NULL;
	truetype_subset->num_string_offsets = 0;
    }
    cairo_truetype_font_destroy (font);
    return CAIRO_STATUS_SUCCESS;
 fail5:
    free (truetype_subset->data);
 fail4:
    free (truetype_subset->widths);
 fail3:
    free (truetype_subset->family_name_utf8);
 fail2:
    free (truetype_subset->ps_name);
 fail1:
    cairo_truetype_font_destroy (font);
    return status;
}
cairo_status_t
_cairo_truetype_subset_init_ps (cairo_truetype_subset_t    *truetype_subset,
				cairo_scaled_font_subset_t	*font_subset)
{
    return cairo_truetype_subset_init_internal (truetype_subset, font_subset, FALSE);
}
cairo_status_t
_cairo_truetype_subset_init_pdf (cairo_truetype_subset_t    *truetype_subset,
				cairo_scaled_font_subset_t	*font_subset)
{
    return cairo_truetype_subset_init_internal (truetype_subset, font_subset, TRUE);
}
void
_cairo_truetype_subset_fini (cairo_truetype_subset_t *subset)
{
    free (subset->ps_name);
    free (subset->family_name_utf8);
    free (subset->widths);
    free (subset->data);
    free (subset->string_offsets);
}
static cairo_int_status_t
_cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font,
			      unsigned long        table_offset,
			      unsigned long        index,
			      uint32_t            *ucs4)
{
    cairo_status_t status;
    const cairo_scaled_font_backend_t *backend;
    tt_segment_map_t *map;
    tt_segment_map_t map_header;
    unsigned int num_segments, i;
    unsigned long size;
    uint16_t *start_code;
    uint16_t *end_code;
    uint16_t *delta;
    uint16_t *range_offset;
    uint16_t  c;
    backend = scaled_font->backend;
    size = 4;  /* enough to read the two header fields we need */
    status = backend->load_truetype_table (scaled_font,
                                           TT_TAG_cmap, table_offset,
					   (unsigned char *) &map_header,
					   &size);
    if (unlikely (status))
	return status;
    /* All table formats have the same first two words */
    if (be16_to_cpu (map_header.format) != 4)
	return CAIRO_INT_STATUS_UNSUPPORTED;
    size = be16_to_cpu (map_header.length);
    /* minimum table size is 24 bytes */
    if (size < 24)
	return CAIRO_INT_STATUS_UNSUPPORTED;
    map = _cairo_malloc (size);
    if (unlikely (map == NULL))
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
    status = backend->load_truetype_table (scaled_font,
                                           TT_TAG_cmap, table_offset,
                                           (unsigned char *) map,
                                           &size);
    if (unlikely (status))
	goto fail;
    num_segments = be16_to_cpu (map->segCountX2)/2;
    /* A Format 4 cmap contains 8 uint16_t numbers and 4 arrays of
     * uint16_t each num_segments long. */
    if (size < (8 + 4*num_segments)*sizeof(uint16_t)) {
        status = CAIRO_INT_STATUS_UNSUPPORTED;
        goto fail;
    }
    end_code = map->endCount;
    start_code = &(end_code[num_segments + 1]);
    delta = &(start_code[num_segments]);
    range_offset = &(delta[num_segments]);
    /* search for glyph in segments with rangeOffset=0 */
    for (i = 0; i < num_segments; i++) {
	uint16_t start = be16_to_cpu (start_code[i]);
	uint16_t end = be16_to_cpu (end_code[i]);
	if (start == 0xffff && end == 0xffff)
	    break;
	c = index - be16_to_cpu (delta[i]);
	if (range_offset[i] == 0 && c >= start && c <= end) {
	    *ucs4 = c;
	    goto found;
	}
    }
    /* search for glyph in segments with rangeOffset=1 */
    for (i = 0; i < num_segments; i++) {
	uint16_t start = be16_to_cpu (start_code[i]);
	uint16_t end = be16_to_cpu (end_code[i]);
	if (start == 0xffff && end == 0xffff)
	    break;
	if (range_offset[i] != 0) {
	    uint16_t *glyph_ids = &range_offset[i] + be16_to_cpu (range_offset[i])/2;
	    int range_size = end - start + 1;
	    uint16_t g_id_be = cpu_to_be16 (index);
	    int j;
	    if (range_size > 0) {
		if ((char*)glyph_ids + 2*range_size > (char*)map + size) {
                    status = CAIRO_INT_STATUS_UNSUPPORTED;
                    goto fail;
                }
		for (j = 0; j < range_size; j++) {
		    if (glyph_ids[j] == g_id_be) {
			*ucs4 = start + j;
			goto found;
		    }
		}
	    }
	}
    }
    /* glyph not found */
    *ucs4 = -1;
found:
    status = CAIRO_STATUS_SUCCESS;
fail:
    free (map);
    return status;
}
cairo_int_status_t
_cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font,
                               unsigned long        index,
                               uint32_t            *ucs4)
{
    cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
    const cairo_scaled_font_backend_t *backend;
    tt_cmap_t *cmap;
    tt_cmap_t cmap_header;
    int num_tables, i;
    unsigned long size;
    backend = scaled_font->backend;
    if (!backend->load_truetype_table)
	return CAIRO_INT_STATUS_UNSUPPORTED;
    size = 4;  /* only read the header fields 'version' and 'num_tables' */
    status = backend->load_truetype_table (scaled_font,
                                           TT_TAG_cmap, 0,
					   (unsigned char *) &cmap_header,
					   &size);
    if (unlikely (status))
	return status;
    num_tables = be16_to_cpu (cmap_header.num_tables);
    size = 4 + num_tables * sizeof (tt_cmap_index_t);
    cmap = _cairo_malloc_ab_plus_c (num_tables, sizeof (tt_cmap_index_t), 4);
    if (unlikely (cmap == NULL))
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
    status = backend->load_truetype_table (scaled_font,
	                                   TT_TAG_cmap, 0,
					   (unsigned char *) cmap,
					   &size);
    if (unlikely (status))
        goto cleanup;
    /* Find a table with Unicode mapping */
    for (i = 0; i < num_tables; i++) {
        if (be16_to_cpu (cmap->index[i].platform) == 3 &&
            be16_to_cpu (cmap->index[i].encoding) == 1) {
            status = _cairo_truetype_reverse_cmap (scaled_font,
						   be32_to_cpu (cmap->index[i].offset),
						   index,
						   ucs4);
            if (status != CAIRO_INT_STATUS_UNSUPPORTED)
                break;
        }
    }
cleanup:
    free (cmap);
    return status;
}
/*
 * Sanity check on font name length as some broken fonts may return very long
 * strings of garbage. 127 is maximum length of a PS name.
 */
#define MAX_FONT_NAME_LENGTH 127
static cairo_status_t
find_name (tt_name_t *name, unsigned long size, int name_id, int platform, int encoding, int language, char **str_out)
{
    tt_name_record_t *record;
    unsigned int i, len;
    char *str;
    char *p;
    cairo_bool_t has_tag;
    cairo_status_t status;
    str = NULL;
    for (i = 0; i < MIN(be16_to_cpu (name->num_records), size / sizeof(name->records[0])); i++) {
        record = &(name->records[i]);
	if (be16_to_cpu (record->name) == name_id &&
	    be16_to_cpu (record->platform) == platform &&
            be16_to_cpu (record->encoding) == encoding &&
	    (language == -1 || be16_to_cpu (record->language) == language)) {
	    len = be16_to_cpu (record->length);
	    if (platform == 3 && len > MAX_FONT_NAME_LENGTH*2) /* UTF-16 name */
		break;
	    if (len > MAX_FONT_NAME_LENGTH)
		break;
	    uint16_t offset = be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset);
	    if (offset + len > size)
		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
	    str = _cairo_malloc (len + 1);
	    if (str == NULL)
		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
	    memcpy (str,
		    ((char*)name) + offset,
		    len);
	    str[len] = 0;
	    break;
	}
    }
    if (str == NULL) {
	*str_out = NULL;
	return CAIRO_STATUS_SUCCESS;
    }
    if (platform == 3) { /* Win platform, unicode encoding */
	/* convert to utf8 */
	int size = 0;
	char *utf8;
	uint16_t *u = (uint16_t *) str;
	unsigned int u_len = len/2;
	for (i = 0; i < u_len; i++)
	    size += _cairo_ucs4_to_utf8 (be16_to_cpu(u[i]), NULL);
	utf8 = _cairo_malloc (size + 1);
	if (utf8 == NULL) {
	    status =_cairo_error (CAIRO_STATUS_NO_MEMORY);
	    goto fail;
	}
	p = utf8;
	for (i = 0; i < u_len; i++)
	    p += _cairo_ucs4_to_utf8 (be16_to_cpu(u[i]), p);
	*p = 0;
	free (str);
	str = utf8;
    } else if (platform == 1) { /* Mac platform, Mac Roman encoding */
	/* Replace characters above 127 with underscores. We could use
	 * a lookup table to convert to unicode but since most fonts
	 * include a unicode name this is just a rarely used fallback. */
	for (i = 0; i < len; i++) {
	    if ((unsigned char)str[i] > 127)
		str[i] = '_';
	}
    }
    /* If font name is prefixed with a PDF subset tag, strip it off. */
    p = str;
    len = strlen (str);
    has_tag = FALSE;
    if (len > 7 && p[6] == '+') {
	has_tag = TRUE;
	for (i = 0; i < 6; i++) {
	    if (p[i] < 'A' || p[i] > 'Z') {
		has_tag = FALSE;
		break;
	    }
	}
    }
    if (has_tag) {
	p = _cairo_strndup (str + 7, len - 7);
	free (str);
	str = p;
    }
    *str_out = str;
    return CAIRO_STATUS_SUCCESS;
  fail:
    free (str);
    return status;
}
cairo_int_status_t
_cairo_truetype_read_font_name (cairo_scaled_font_t  	 *scaled_font,
				char 	       		**ps_name_out,
				char 	       		**font_name_out)
{
    cairo_status_t status;
    const cairo_scaled_font_backend_t *backend;
    tt_name_t *name;
    unsigned long size;
    char *ps_name = NULL;
    char *family_name = NULL;
    backend = scaled_font->backend;
    if (!backend->load_truetype_table)
	return CAIRO_INT_STATUS_UNSUPPORTED;
    size = 0;
    status = backend->load_truetype_table (scaled_font,
	                                   TT_TAG_name, 0,
					   NULL,
					   &size);
    if (status)
	return status;
    name = _cairo_malloc (size);
    if (name == NULL)
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
    status = backend->load_truetype_table (scaled_font,
					   TT_TAG_name, 0,
					   (unsigned char *) name,
					   &size);
    if (status)
	goto fail;
    /* Find PS Name (name_id = 6). OT spec says PS name must be one of
     * the following two encodings */
    status = find_name (name, size, 6, 3, 1, 0x409, &ps_name); /* win, unicode, english-us */
    if (unlikely(status))
	goto fail;
    if (!ps_name) {
	status = find_name (name, size, 6, 1, 0, 0, &ps_name); /* mac, roman, english */
	if (unlikely(status))
	    goto fail;
    }
    /* Find Family name (name_id = 1) */
    status = find_name (name, size, 1, 3, 1, 0x409, &family_name); /* win, unicode, english-us */
    if (unlikely(status))
	goto fail;
    if (!family_name) {
	status = find_name (name, size, 1, 3, 0, 0x409, &family_name); /* win, symbol, english-us */
	if (unlikely(status))
	    goto fail;
    }
    if (!family_name) {
	status = find_name (name, size, 1, 1, 0, 0, &family_name); /* mac, roman, english */
	if (unlikely(status))
	    goto fail;
    }
    if (!family_name) {
	status = find_name (name, size, 1, 3, 1, -1, &family_name); /* win, unicode, any language */
	if (unlikely(status))
	    goto fail;
    }
    status = _cairo_escape_ps_name (&ps_name);
    if (unlikely(status))
	goto fail;
    free (name);
    *ps_name_out = ps_name;
    *font_name_out = family_name;
    return CAIRO_STATUS_SUCCESS;
fail:
    free (name);
    free (ps_name);
    free (family_name);
    *ps_name_out = NULL;
    *font_name_out = NULL;
    return status;
}
cairo_int_status_t
_cairo_truetype_get_style (cairo_scaled_font_t  	 *scaled_font,
			   int				 *weight,
			   cairo_bool_t			 *bold,
			   cairo_bool_t			 *italic)
{
    cairo_status_t status;
    const cairo_scaled_font_backend_t *backend;
    tt_os2_t os2;
    unsigned long size;
    uint16_t selection;
    backend = scaled_font->backend;
    if (!backend->load_truetype_table)
	return CAIRO_INT_STATUS_UNSUPPORTED;
    size = 0;
    status = backend->load_truetype_table (scaled_font,
					   TT_TAG_OS2, 0,
					   NULL,
					   &size);
    if (status)
	return status;
    if (size < sizeof(os2))
	return CAIRO_INT_STATUS_UNSUPPORTED;
    size = sizeof (os2);
    status = backend->load_truetype_table (scaled_font,
					   TT_TAG_OS2, 0,
					   (unsigned char *) &os2,
					   &size);
    if (status)
	return status;
    *weight = be16_to_cpu (os2.usWeightClass);
    selection = be16_to_cpu (os2.fsSelection);
    *bold = (selection & TT_FS_SELECTION_BOLD) ? TRUE : FALSE;
    *italic = (selection & TT_FS_SELECTION_ITALIC) ? TRUE : FALSE;
    return CAIRO_STATUS_SUCCESS;
}
#endif /* CAIRO_HAS_FONT_SUBSET */