Subversion Repositories Kolibri OS

Rev

Rev 1897 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1897 serge 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 
34
 *	Adrian Johnson 
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"
3959 Serge 45
 
46
#include "cairo-array-private.h"
1897 serge 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;
3959 Serge 97
    cairo_bool_t is_pdf;
1897 serge 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
{
3959 Serge 127
    if (status == CAIRO_STATUS_SUCCESS ||
128
	status == (int)CAIRO_INT_STATUS_UNSUPPORTED)
1897 serge 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,
3959 Serge 138
			     cairo_bool_t is_pdf,
1897 serge 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
 
3959 Serge 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
 
1897 serge 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
 
3959 Serge 217
    font->is_pdf = is_pdf;
1897 serge 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);
3959 Serge 274
    free (font->base.font_name);
1897 serge 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);
3959 Serge 290
    free (font->base.font_name);
1897 serge 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
 
3959 Serge 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
 
1897 serge 425
static cairo_status_t
426
cairo_truetype_font_write_cmap_table (cairo_truetype_font_t *font,
427
				      unsigned long          tag)
428
{
3959 Serge 429
    int i;
430
    unsigned int j;
431
    int range_offset;
432
    int num_ranges;
433
    int entry_selector;
434
    int length;
1897 serge 435
 
3959 Serge 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
 
1897 serge 448
    cairo_truetype_font_write_be16 (font, 0);  /* Table version */
3959 Serge 449
    cairo_truetype_font_write_be16 (font, 1);  /* Num tables */
1897 serge 450
 
451
    cairo_truetype_font_write_be16 (font, 3);  /* Platform */
3959 Serge 452
    cairo_truetype_font_write_be16 (font, 1);  /* Encoding */
453
    cairo_truetype_font_write_be32 (font, 12); /* Offset to start of table */
1897 serge 454
 
3959 Serge 455
    /* Output a format 4 encoding table for the winansi encoding */
1897 serge 456
 
457
    cairo_truetype_font_write_be16 (font, 4);  /* Format */
3959 Serge 458
    cairo_truetype_font_write_be16 (font, length); /* Length */
1897 serge 459
    cairo_truetype_font_write_be16 (font, 0);  /* Version */
3959 Serge 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
 
1897 serge 468
    cairo_truetype_font_write_be16 (font, 0);       /* reserved */
469
 
3959 Serge 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[] */
1897 serge 473
 
3959 Serge 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[] */
1897 serge 477
 
3959 Serge 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
 
1897 serge 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
    entry[0] = cpu_to_be32 ((uint32_t)tag);
930
    entry[1] = cpu_to_be32 (cairo_truetype_font_calculate_checksum (font, start, end));
931
    entry[2] = cpu_to_be32 ((uint32_t)start);
932
    entry[3] = cpu_to_be32 ((uint32_t)(end - start));
933
}
934
 
935
static cairo_status_t
936
cairo_truetype_font_generate (cairo_truetype_font_t  *font,
937
			      const char            **data,
938
			      unsigned long          *length,
939
			      const unsigned long   **string_offsets,
940
			      unsigned long          *num_strings)
941
{
942
    cairo_status_t status;
943
    unsigned long start, end, next;
944
    uint32_t checksum, *checksum_location;
945
    int i;
946
 
947
    if (font->status)
948
	return font->status;
949
 
950
    status = cairo_truetype_font_write_offset_table (font);
951
    if (unlikely (status))
952
	goto FAIL;
953
 
954
    status = cairo_truetype_font_align_output (font, &start);
955
    if (unlikely (status))
956
	goto FAIL;
957
 
958
    end = 0;
959
    for (i = 0; i < font->num_tables; i++) {
960
	status = font->truetype_tables[i].write (font, font->truetype_tables[i].tag);
961
	if (unlikely (status))
962
	    goto FAIL;
963
 
964
	end = _cairo_array_num_elements (&font->output);
965
	status = cairo_truetype_font_align_output (font, &next);
966
	if (unlikely (status))
967
	    goto FAIL;
968
 
969
	cairo_truetype_font_update_entry (font, font->truetype_tables[i].pos,
970
                                          font->truetype_tables[i].tag, start, end);
971
        status = cairo_truetype_font_check_boundary (font, next);
972
	if (unlikely (status))
973
	    goto FAIL;
974
 
975
	start = next;
976
    }
977
 
978
    checksum =
979
	0xb1b0afba - cairo_truetype_font_calculate_checksum (font, 0, end);
980
    checksum_location = _cairo_array_index (&font->output, font->checksum_index);
981
    *checksum_location = cpu_to_be32 (checksum);
982
 
983
    *data = _cairo_array_index (&font->output, 0);
984
    *length = _cairo_array_num_elements (&font->output);
985
    *num_strings = _cairo_array_num_elements (&font->string_offsets);
986
    if (*num_strings != 0)
987
	*string_offsets = _cairo_array_index (&font->string_offsets, 0);
988
    else
989
	*string_offsets = NULL;
990
 
991
 FAIL:
992
    return _cairo_truetype_font_set_error (font, status);
993
}
994
 
995
static cairo_status_t
996
cairo_truetype_font_use_glyph (cairo_truetype_font_t	    *font,
997
	                       unsigned short		     glyph,
998
			       unsigned short		    *out)
999
{
1000
    if (glyph >= font->num_glyphs_in_face)
1001
	return CAIRO_INT_STATUS_UNSUPPORTED;
1002
 
1003
    if (font->parent_to_subset[glyph] == 0) {
1004
	font->parent_to_subset[glyph] = font->base.num_glyphs;
1005
	font->glyphs[font->base.num_glyphs].parent_index = glyph;
1006
	font->base.num_glyphs++;
1007
    }
1008
 
1009
    *out = font->parent_to_subset[glyph];
1010
    return CAIRO_STATUS_SUCCESS;
1011
}
1012
 
1013
static void
1014
cairo_truetype_font_add_truetype_table (cairo_truetype_font_t *font,
1015
           unsigned long tag,
1016
           cairo_status_t (*write) (cairo_truetype_font_t *font, unsigned long tag),
1017
           int pos)
1018
{
1019
    font->truetype_tables[font->num_tables].tag = tag;
1020
    font->truetype_tables[font->num_tables].write = write;
1021
    font->truetype_tables[font->num_tables].pos = pos;
1022
    font->num_tables++;
1023
}
1024
 
1025
/* cairo_truetype_font_create_truetype_table_list() builds the list of
1026
 * truetype tables to be embedded in the subsetted font. Each call to
1027
 * cairo_truetype_font_add_truetype_table() adds a table, the callback
1028
 * for generating the table, and the position in the table directory
1029
 * to the truetype_tables array.
1030
 *
1031
 * As we write out the glyf table we remap composite glyphs.
1032
 * Remapping composite glyphs will reference the sub glyphs the
1033
 * composite glyph is made up of. The "glyf" table callback needs to
1034
 * be called first so we have all the glyphs in the subset before
1035
 * going further.
1036
 *
1037
 * The order in which tables are added to the truetype_table array
1038
 * using cairo_truetype_font_add_truetype_table() specifies the order
1039
 * in which the callback functions will be called.
1040
 *
1041
 * The tables in the table directory must be listed in alphabetical
1042
 * order.  The "cvt", "fpgm", and "prep" are optional tables. They
1043
 * will only be embedded in the subset if they exist in the source
3959 Serge 1044
 * font. "cmap" is only embedded for latin fonts. The pos parameter of
1045
 * cairo_truetype_font_add_truetype_table() specifies the position of
1046
 * the table in the table directory.
1897 serge 1047
 */
1048
static void
1049
cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t *font)
1050
{
1051
    cairo_bool_t has_cvt = FALSE;
1052
    cairo_bool_t has_fpgm = FALSE;
1053
    cairo_bool_t has_prep = FALSE;
1054
    unsigned long size;
1055
    int pos;
1056
 
1057
    size = 0;
1058
    if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
1059
                                      TT_TAG_cvt, 0, NULL,
3959 Serge 1060
                                      &size) == CAIRO_INT_STATUS_SUCCESS)
1897 serge 1061
        has_cvt = TRUE;
1062
 
1063
    size = 0;
1064
    if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
1065
                                      TT_TAG_fpgm, 0, NULL,
3959 Serge 1066
                                      &size) == CAIRO_INT_STATUS_SUCCESS)
1897 serge 1067
        has_fpgm = TRUE;
1068
 
1069
    size = 0;
1070
    if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
1071
                                      TT_TAG_prep, 0, NULL,
3959 Serge 1072
                                      &size) == CAIRO_INT_STATUS_SUCCESS)
1897 serge 1073
        has_prep = TRUE;
1074
 
1075
    font->num_tables = 0;
3959 Serge 1076
    pos = 0;
1077
    if (font->is_pdf && font->scaled_font_subset->is_latin)
1078
	pos++;
1897 serge 1079
    if (has_cvt)
1080
        pos++;
1081
    if (has_fpgm)
1082
        pos++;
1083
    cairo_truetype_font_add_truetype_table (font, TT_TAG_glyf, cairo_truetype_font_write_glyf_table, pos);
1084
 
1085
    pos = 0;
3959 Serge 1086
    if (font->is_pdf && font->scaled_font_subset->is_latin)
1087
	cairo_truetype_font_add_truetype_table (font, TT_TAG_cmap, cairo_truetype_font_write_cmap_table, pos++);
1897 serge 1088
    if (has_cvt)
1089
        cairo_truetype_font_add_truetype_table (font, TT_TAG_cvt, cairo_truetype_font_write_generic_table, pos++);
1090
    if (has_fpgm)
1091
        cairo_truetype_font_add_truetype_table (font, TT_TAG_fpgm, cairo_truetype_font_write_generic_table, pos++);
1092
    pos++;
1093
    cairo_truetype_font_add_truetype_table (font, TT_TAG_head, cairo_truetype_font_write_head_table, pos++);
1094
    cairo_truetype_font_add_truetype_table (font, TT_TAG_hhea, cairo_truetype_font_write_hhea_table, pos++);
1095
    cairo_truetype_font_add_truetype_table (font, TT_TAG_hmtx, cairo_truetype_font_write_hmtx_table, pos++);
1096
    cairo_truetype_font_add_truetype_table (font, TT_TAG_loca, cairo_truetype_font_write_loca_table, pos++);
1097
    cairo_truetype_font_add_truetype_table (font, TT_TAG_maxp, cairo_truetype_font_write_maxp_table, pos++);
1098
    if (has_prep)
1099
        cairo_truetype_font_add_truetype_table (font, TT_TAG_prep, cairo_truetype_font_write_generic_table, pos);
1100
}
1101
 
3959 Serge 1102
static cairo_status_t
1103
cairo_truetype_subset_init_internal (cairo_truetype_subset_t     *truetype_subset,
1104
				      cairo_scaled_font_subset_t *font_subset,
1105
				      cairo_bool_t                is_pdf)
1897 serge 1106
{
1107
    cairo_truetype_font_t *font = NULL;
1108
    cairo_status_t status;
1109
    const char *data = NULL; /* squelch bogus compiler warning */
1110
    unsigned long length = 0; /* squelch bogus compiler warning */
1111
    unsigned long offsets_length;
1112
    unsigned int i;
1113
    const unsigned long *string_offsets = NULL;
1114
    unsigned long num_strings = 0;
1115
 
3959 Serge 1116
    status = _cairo_truetype_font_create (font_subset, is_pdf, &font);
1897 serge 1117
    if (unlikely (status))
1118
	return status;
1119
 
1120
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
1121
	unsigned short parent_glyph = font->scaled_font_subset->glyphs[i];
1122
	status = cairo_truetype_font_use_glyph (font, parent_glyph, &parent_glyph);
1123
	if (unlikely (status))
1124
	    goto fail1;
1125
    }
1126
 
1127
    cairo_truetype_font_create_truetype_table_list (font);
1128
    status = cairo_truetype_font_generate (font, &data, &length,
1129
                                           &string_offsets, &num_strings);
1130
    if (unlikely (status))
1131
	goto fail1;
1132
 
1133
    truetype_subset->ps_name = strdup (font->base.ps_name);
1134
    if (unlikely (truetype_subset->ps_name == NULL)) {
1135
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1136
	goto fail1;
1137
    }
1138
 
1139
    if (font->base.font_name != NULL) {
3959 Serge 1140
	truetype_subset->family_name_utf8 = strdup (font->base.font_name);
1141
	if (unlikely (truetype_subset->family_name_utf8 == NULL)) {
1897 serge 1142
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1143
	    goto fail2;
1144
	}
1145
    } else {
3959 Serge 1146
	truetype_subset->family_name_utf8 = NULL;
1897 serge 1147
    }
1148
 
1149
    /* The widths array returned must contain only widths for the
1150
     * glyphs in font_subset. Any subglyphs appended after
1151
     * font_subset->num_glyphs are omitted. */
1152
    truetype_subset->widths = calloc (sizeof (double),
1153
                                      font->scaled_font_subset->num_glyphs);
1154
    if (unlikely (truetype_subset->widths == NULL)) {
1155
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1156
	goto fail3;
1157
    }
1158
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
1159
	truetype_subset->widths[i] = (double)font->base.widths[i]/font->base.units_per_em;
1160
 
1161
    truetype_subset->x_min = (double)font->base.x_min/font->base.units_per_em;
1162
    truetype_subset->y_min = (double)font->base.y_min/font->base.units_per_em;
1163
    truetype_subset->x_max = (double)font->base.x_max/font->base.units_per_em;
1164
    truetype_subset->y_max = (double)font->base.y_max/font->base.units_per_em;
1165
    truetype_subset->ascent = (double)font->base.ascent/font->base.units_per_em;
1166
    truetype_subset->descent = (double)font->base.descent/font->base.units_per_em;
1167
 
1168
    if (length) {
1169
	truetype_subset->data = malloc (length);
1170
	if (unlikely (truetype_subset->data == NULL)) {
1171
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1172
	    goto fail4;
1173
	}
1174
 
1175
	memcpy (truetype_subset->data, data, length);
1176
    } else
1177
	truetype_subset->data = NULL;
1178
    truetype_subset->data_length = length;
1179
 
1180
    if (num_strings) {
1181
	offsets_length = num_strings * sizeof (unsigned long);
1182
	truetype_subset->string_offsets = malloc (offsets_length);
1183
	if (unlikely (truetype_subset->string_offsets == NULL)) {
1184
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1185
	    goto fail5;
1186
	}
1187
 
1188
	memcpy (truetype_subset->string_offsets, string_offsets, offsets_length);
1189
	truetype_subset->num_string_offsets = num_strings;
1190
    } else {
1191
	truetype_subset->string_offsets = NULL;
1192
	truetype_subset->num_string_offsets = 0;
1193
    }
1194
 
1195
    cairo_truetype_font_destroy (font);
1196
 
1197
    return CAIRO_STATUS_SUCCESS;
1198
 
1199
 fail5:
1200
    free (truetype_subset->data);
1201
 fail4:
1202
    free (truetype_subset->widths);
1203
 fail3:
3959 Serge 1204
    free (truetype_subset->family_name_utf8);
1897 serge 1205
 fail2:
1206
    free (truetype_subset->ps_name);
1207
 fail1:
1208
    cairo_truetype_font_destroy (font);
1209
 
1210
    return status;
1211
}
1212
 
3959 Serge 1213
cairo_status_t
1214
_cairo_truetype_subset_init_ps (cairo_truetype_subset_t    *truetype_subset,
1215
				cairo_scaled_font_subset_t	*font_subset)
1216
{
1217
    return cairo_truetype_subset_init_internal (truetype_subset, font_subset, FALSE);
1218
}
1219
 
1220
cairo_status_t
1221
_cairo_truetype_subset_init_pdf (cairo_truetype_subset_t    *truetype_subset,
1222
				cairo_scaled_font_subset_t	*font_subset)
1223
{
1224
    return cairo_truetype_subset_init_internal (truetype_subset, font_subset, TRUE);
1225
}
1226
 
1897 serge 1227
void
1228
_cairo_truetype_subset_fini (cairo_truetype_subset_t *subset)
1229
{
1230
    free (subset->ps_name);
3959 Serge 1231
    free (subset->family_name_utf8);
1897 serge 1232
    free (subset->widths);
1233
    free (subset->data);
1234
    free (subset->string_offsets);
1235
}
1236
 
1237
static cairo_int_status_t
1238
_cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font,
1239
			      unsigned long        table_offset,
1240
			      unsigned long        index,
1241
			      uint32_t            *ucs4)
1242
{
1243
    cairo_status_t status;
1244
    const cairo_scaled_font_backend_t *backend;
1245
    tt_segment_map_t *map;
1246
    char buf[4];
1247
    unsigned int num_segments, i;
1248
    unsigned long size;
1249
    uint16_t *start_code;
1250
    uint16_t *end_code;
1251
    uint16_t *delta;
1252
    uint16_t *range_offset;
1253
    uint16_t  c;
1254
 
1255
    backend = scaled_font->backend;
1256
    size = 4;
1257
    status = backend->load_truetype_table (scaled_font,
1258
                                           TT_TAG_cmap, table_offset,
1259
					   (unsigned char *) &buf,
1260
					   &size);
1261
    if (unlikely (status))
1262
	return status;
1263
 
1264
    /* All table formats have the same first two words */
1265
    map = (tt_segment_map_t *) buf;
1266
    if (be16_to_cpu (map->format) != 4)
1267
	return CAIRO_INT_STATUS_UNSUPPORTED;
1268
 
1269
    size = be16_to_cpu (map->length);
1270
    map = malloc (size);
1271
    if (unlikely (map == NULL))
1272
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1273
 
1274
    status = backend->load_truetype_table (scaled_font,
1275
                                           TT_TAG_cmap, table_offset,
1276
                                           (unsigned char *) map,
1277
                                           &size);
1278
    if (unlikely (status))
1279
	goto fail;
1280
 
1281
    num_segments = be16_to_cpu (map->segCountX2)/2;
1282
 
1283
    /* A Format 4 cmap contains 8 uint16_t numbers and 4 arrays of
1284
     * uint16_t each num_segments long. */
1285
    if (size < (8 + 4*num_segments)*sizeof(uint16_t))
1286
	return CAIRO_INT_STATUS_UNSUPPORTED;
1287
 
1288
    end_code = map->endCount;
1289
    start_code = &(end_code[num_segments + 1]);
1290
    delta = &(start_code[num_segments]);
1291
    range_offset = &(delta[num_segments]);
1292
 
1293
    /* search for glyph in segments with rangeOffset=0 */
1294
    for (i = 0; i < num_segments; i++) {
1295
	c = index - be16_to_cpu (delta[i]);
1296
	if (range_offset[i] == 0 &&
1297
	    c >= be16_to_cpu (start_code[i]) &&
1298
	    c <= be16_to_cpu (end_code[i]))
1299
	{
1300
	    *ucs4 = c;
1301
	    goto found;
1302
	}
1303
    }
1304
 
1305
    /* search for glyph in segments with rangeOffset=1 */
1306
    for (i = 0; i < num_segments; i++) {
1307
	if (range_offset[i] != 0) {
1308
	    uint16_t *glyph_ids = &range_offset[i] + be16_to_cpu (range_offset[i])/2;
1309
	    int range_size = be16_to_cpu (end_code[i]) - be16_to_cpu (start_code[i]) + 1;
1310
	    uint16_t g_id_be = cpu_to_be16 (index);
1311
	    int j;
1312
 
1313
	    if (range_size > 0) {
1314
		if ((char*)glyph_ids + 2*range_size > (char*)map + size)
1315
		    return CAIRO_INT_STATUS_UNSUPPORTED;
1316
 
1317
		for (j = 0; j < range_size; j++) {
1318
		    if (glyph_ids[j] == g_id_be) {
1319
			*ucs4 = be16_to_cpu (start_code[i]) + j;
1320
			goto found;
1321
		    }
1322
		}
1323
	    }
1324
	}
1325
    }
1326
 
1327
    /* glyph not found */
1328
    *ucs4 = -1;
1329
 
1330
found:
1331
    status = CAIRO_STATUS_SUCCESS;
1332
 
1333
fail:
1334
    free (map);
1335
 
1336
    return status;
1337
}
1338
 
1339
cairo_int_status_t
1340
_cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font,
1341
                               unsigned long        index,
1342
                               uint32_t            *ucs4)
1343
{
3959 Serge 1344
    cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
1897 serge 1345
    const cairo_scaled_font_backend_t *backend;
1346
    tt_cmap_t *cmap;
1347
    char buf[4];
1348
    int num_tables, i;
1349
    unsigned long size;
1350
 
1351
    backend = scaled_font->backend;
1352
    if (!backend->load_truetype_table)
1353
	return CAIRO_INT_STATUS_UNSUPPORTED;
1354
 
1355
    size = 4;
1356
    status = backend->load_truetype_table (scaled_font,
1357
                                           TT_TAG_cmap, 0,
1358
					   (unsigned char *) &buf,
1359
					   &size);
1360
    if (unlikely (status))
1361
	return status;
1362
 
1363
    cmap = (tt_cmap_t *) buf;
1364
    num_tables = be16_to_cpu (cmap->num_tables);
1365
    size = 4 + num_tables*sizeof(tt_cmap_index_t);
1366
    cmap = _cairo_malloc_ab_plus_c (num_tables, sizeof (tt_cmap_index_t), 4);
1367
    if (unlikely (cmap == NULL))
1368
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1369
 
1370
    status = backend->load_truetype_table (scaled_font,
1371
	                                   TT_TAG_cmap, 0,
1372
					   (unsigned char *) cmap,
1373
					   &size);
1374
    if (unlikely (status))
1375
        goto cleanup;
1376
 
1377
    /* Find a table with Unicode mapping */
1378
    for (i = 0; i < num_tables; i++) {
1379
        if (be16_to_cpu (cmap->index[i].platform) == 3 &&
1380
            be16_to_cpu (cmap->index[i].encoding) == 1) {
1381
            status = _cairo_truetype_reverse_cmap (scaled_font,
1382
						   be32_to_cpu (cmap->index[i].offset),
1383
						   index,
1384
						   ucs4);
1385
            if (status != CAIRO_INT_STATUS_UNSUPPORTED)
1386
                break;
1387
        }
1388
    }
1389
 
1390
cleanup:
1391
    free (cmap);
1392
 
1393
    return status;
1394
}
1395
 
3959 Serge 1396
static cairo_status_t
1397
find_name (tt_name_t *name, int name_id, int platform, int encoding, int language, char **str_out)
1398
{
1399
    tt_name_record_t *record;
1400
    int i, len;
1401
    char *str;
1402
    char *p;
1403
    cairo_bool_t has_tag;
1404
    cairo_status_t status;
1405
 
1406
    str = NULL;
1407
    for (i = 0; i < be16_to_cpu (name->num_records); i++) {
1408
        record = &(name->records[i]);
1409
	if (be16_to_cpu (record->name) == name_id &&
1410
	    be16_to_cpu (record->platform) == platform &&
1411
            be16_to_cpu (record->encoding) == encoding &&
1412
	    (language == -1 || be16_to_cpu (record->language) == language)) {
1413
 
1414
	    str = malloc (be16_to_cpu (record->length) + 1);
1415
	    if (str == NULL)
1416
		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1417
 
1418
	    len = be16_to_cpu (record->length);
1419
	    memcpy (str,
1420
		    ((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset),
1421
		    len);
1422
	    str[be16_to_cpu (record->length)] = 0;
1423
	    break;
1424
	}
1425
    }
1426
    if (str == NULL) {
1427
	*str_out = NULL;
1428
	return CAIRO_STATUS_SUCCESS;
1429
    }
1430
 
1431
    if (platform == 3) { /* Win platform, unicode encoding */
1432
	/* convert to utf8 */
1433
	int size = 0;
1434
	char *utf8;
1435
	uint16_t *u = (uint16_t *) str;
1436
	int u_len = len/2;
1437
 
1438
	for (i = 0; i < u_len; i++)
1439
	    size += _cairo_ucs4_to_utf8 (be16_to_cpu(u[i]), NULL);
1440
 
1441
	utf8 = malloc (size + 1);
1442
	if (utf8 == NULL) {
1443
	    status =_cairo_error (CAIRO_STATUS_NO_MEMORY);
1444
	    goto fail;
1445
	}
1446
	p = utf8;
1447
	for (i = 0; i < u_len; i++)
1448
	    p += _cairo_ucs4_to_utf8 (be16_to_cpu(u[i]), p);
1449
	*p = 0;
1450
	free (str);
1451
	str = utf8;
1452
    } else if (platform == 1) { /* Mac platform, Mac Roman encoding */
1453
	/* Replace characters above 127 with underscores. We could use
1454
	 * a lookup table to convert to unicode but since most fonts
1455
	 * include a unicode name this is just a rarely used fallback. */
1456
	for (i = 0; i < len; i++) {
1457
	    if ((unsigned char)str[i] > 127)
1458
		str[i] = '_';
1459
	}
1460
    }
1461
 
1462
    /* If font name is prefixed with a PDF subset tag, strip it off. */
1463
    p = str;
1464
    len = strlen (str);
1465
    has_tag = FALSE;
1466
    if (len > 7 && p[6] == '+') {
1467
	has_tag = TRUE;
1468
	for (i = 0; i < 6; i++) {
1469
	    if (p[i] < 'A' || p[i] > 'Z') {
1470
		has_tag = FALSE;
1471
		break;
1472
	    }
1473
	}
1474
    }
1475
    if (has_tag) {
1476
	p = malloc (len - 6);
1477
	if (unlikely (p == NULL)) {
1478
	    status =_cairo_error (CAIRO_STATUS_NO_MEMORY);
1479
	    goto fail;
1480
	}
1481
	memcpy (p, str + 7, len - 7);
1482
	p[len-7] = 0;
1483
	free (str);
1484
	str = p;
1485
    }
1486
 
1487
    *str_out = str;
1488
 
1489
    return CAIRO_STATUS_SUCCESS;
1490
 
1491
  fail:
1492
    free (str);
1493
 
1494
    return status;
1495
}
1496
 
1897 serge 1497
cairo_int_status_t
1498
_cairo_truetype_read_font_name (cairo_scaled_font_t  	 *scaled_font,
1499
				char 	       		**ps_name_out,
1500
				char 	       		**font_name_out)
1501
{
1502
    cairo_status_t status;
1503
    const cairo_scaled_font_backend_t *backend;
1504
    tt_name_t *name;
1505
    unsigned long size;
1506
    char *ps_name = NULL;
3959 Serge 1507
    char *family_name = NULL;
1897 serge 1508
 
1509
    backend = scaled_font->backend;
1510
    if (!backend->load_truetype_table)
1511
	return CAIRO_INT_STATUS_UNSUPPORTED;
1512
 
1513
    size = 0;
1514
    status = backend->load_truetype_table (scaled_font,
1515
	                                   TT_TAG_name, 0,
1516
					   NULL,
1517
					   &size);
1518
    if (status)
1519
	return status;
1520
 
1521
    name = malloc (size);
1522
    if (name == NULL)
1523
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1524
 
3959 Serge 1525
    status = backend->load_truetype_table (scaled_font,
1897 serge 1526
					   TT_TAG_name, 0,
1527
					   (unsigned char *) name,
1528
					   &size);
1529
    if (status)
1530
	goto fail;
1531
 
3959 Serge 1532
    /* Find PS Name (name_id = 6). OT spec says PS name must be one of
1533
     * the following two encodings */
1534
    status = find_name (name, 6, 3, 1, 0x409, &ps_name); /* win, unicode, english-us */
1535
    if (unlikely(status))
1536
	goto fail;
1897 serge 1537
 
3959 Serge 1538
    if (!ps_name) {
1539
	status = find_name (name, 6, 1, 0, 0, &ps_name); /* mac, roman, english */
1540
	if (unlikely(status))
1541
	    goto fail;
1542
    }
1897 serge 1543
 
3959 Serge 1544
    /* Find Family name (name_id = 1) */
1545
    status = find_name (name, 1, 3, 1, 0x409, &family_name); /* win, unicode, english-us */
1546
    if (unlikely(status))
1547
	goto fail;
1897 serge 1548
 
3959 Serge 1549
    if (!family_name) {
1550
	status = find_name (name, 1, 3, 0, 0x409, &family_name); /* win, symbol, english-us */
1551
	if (unlikely(status))
1552
	    goto fail;
1897 serge 1553
    }
1554
 
3959 Serge 1555
    if (!family_name) {
1556
	status = find_name (name, 1, 1, 0, 0, &family_name); /* mac, roman, english */
1557
	if (unlikely(status))
1558
	    goto fail;
1559
    }
1560
 
1561
    if (!family_name) {
1562
	status = find_name (name, 1, 3, 1, -1, &family_name); /* win, unicode, any language */
1563
	if (unlikely(status))
1564
	    goto fail;
1565
    }
1566
 
1897 serge 1567
    free (name);
1568
 
3959 Serge 1569
    /* Ensure PS name is a valid PDF/PS name object. In PDF names are
1570
     * treated as UTF8 and non ASCII bytes, ' ', and '#' are encoded
1571
     * as '#' followed by 2 hex digits that encode the byte. By also
1572
     * encoding the characters in the reserved string we ensure the
1573
     * name is also PS compatible. */
1897 serge 1574
    if (ps_name) {
3959 Serge 1575
	static const char *reserved = "()<>[]{}/%#\\";
1576
	char buf[128]; /* max name length is 127 bytes */
1577
	char *src = ps_name;
1578
	char *dst = buf;
1579
 
1580
	while (*src && dst < buf + 127) {
1581
	    unsigned char c = *src;
1582
	    if (c < 0x21 || c > 0x7e || strchr (reserved, c)) {
1583
		if (dst + 4 > buf + 127)
1584
		    break;
1585
 
1586
		snprintf (dst, 4, "#%02X", c);
1587
		src++;
1588
		dst += 3;
1589
	    } else {
1590
		*dst++ = *src++;
1591
	    }
1897 serge 1592
	}
3959 Serge 1593
	*dst = 0;
1594
	free (ps_name);
1595
	ps_name = strdup (buf);
1596
	if (ps_name == NULL) {
1597
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1598
	    goto fail;
1599
	}
1897 serge 1600
    }
1601
 
1602
    *ps_name_out = ps_name;
3959 Serge 1603
    *font_name_out = family_name;
1897 serge 1604
 
1605
    return CAIRO_STATUS_SUCCESS;
1606
 
1607
fail:
1608
    free (name);
3959 Serge 1609
    free (ps_name);
1610
    free (family_name);
1897 serge 1611
    *ps_name_out = NULL;
1612
    *font_name_out = NULL;
1613
 
1614
    return status;
1615
}
1616
 
3959 Serge 1617
cairo_int_status_t
1618
_cairo_truetype_get_style (cairo_scaled_font_t  	 *scaled_font,
1619
			   int				 *weight,
1620
			   cairo_bool_t			 *bold,
1621
			   cairo_bool_t			 *italic)
1622
{
1623
    cairo_status_t status;
1624
    const cairo_scaled_font_backend_t *backend;
1625
    tt_os2_t os2;
1626
    unsigned long size;
1627
    uint16_t selection;
1628
 
1629
    backend = scaled_font->backend;
1630
    if (!backend->load_truetype_table)
1631
	return CAIRO_INT_STATUS_UNSUPPORTED;
1632
 
1633
    size = 0;
1634
    status = backend->load_truetype_table (scaled_font,
1635
					   TT_TAG_OS2, 0,
1636
					   NULL,
1637
					   &size);
1638
    if (status)
1639
	return status;
1640
 
1641
    if (size < sizeof(os2))
1642
	return CAIRO_INT_STATUS_UNSUPPORTED;
1643
 
1644
    size = sizeof (os2);
1645
    status = backend->load_truetype_table (scaled_font,
1646
					   TT_TAG_OS2, 0,
1647
					   (unsigned char *) &os2,
1648
					   &size);
1649
    if (status)
1650
	return status;
1651
 
1652
    *weight = be16_to_cpu (os2.usWeightClass);
1653
    selection = be16_to_cpu (os2.fsSelection);
1654
    *bold = (selection & TT_FS_SELECTION_BOLD) ? TRUE : FALSE;
1655
    *italic = (selection & TT_FS_SELECTION_ITALIC) ? TRUE : FALSE;
1656
 
1657
    return CAIRO_STATUS_SUCCESS;
1658
}
1659
 
1897 serge 1660
#endif /* CAIRO_HAS_FONT_SUBSET */