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
3959 Serge 1
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
1897 serge 2
/* cairo - a vector graphics library with display and print output
3
 *
4
 * Copyright © 2006 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 
35
 */
36
 
37
/*
38
 * Useful links:
39
 * http://partners.adobe.com/public/developer/en/font/T1_SPEC.PDF
40
 */
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-type1-private.h"
52
#include "cairo-scaled-font-subsets-private.h"
53
#include "cairo-output-stream-private.h"
54
 
3959 Serge 55
#include 
56
#include 
1897 serge 57
 
3959 Serge 58
#define TYPE1_STACKSIZE 24 /* Defined in Type 1 Font Format */
1897 serge 59
 
60
 
3959 Serge 61
typedef struct {
62
    int subset_index;
63
    double width;
64
    const char *encrypted_charstring;
65
    int encrypted_charstring_length;
66
} glyph_data_t;
1897 serge 67
 
68
typedef struct _cairo_type1_font_subset {
69
    cairo_scaled_font_subset_t *scaled_font_subset;
70
 
71
    struct {
72
	unsigned int font_id;
73
	char *base_font;
74
	unsigned int num_glyphs;
75
	double x_min, y_min, x_max, y_max;
76
	double ascent, descent;
3959 Serge 77
	double units_per_em;
1897 serge 78
 
79
	const char    *data;
80
	unsigned long  header_size;
81
	unsigned long  data_size;
82
	unsigned long  trailer_size;
83
    } base;
84
 
85
    int num_glyphs;
86
 
3959 Serge 87
    /* The glyphs and glyph_names arrays are indexed by the order of
88
     * the Charstrings in the font. This is not necessarily the same
89
     * order as the glyph index. The index_to_glyph_name() font backend
90
     * function is used to map the glyph index to the glyph order in
91
     * the Charstrings. */
92
 
93
    glyph_data_t *glyphs;
94
    char **glyph_names;
95
    cairo_array_t glyphs_array;
96
    cairo_array_t glyph_names_array;
97
 
98
    int num_subrs;
99
    cairo_bool_t subset_subrs;
1897 serge 100
    struct {
3959 Serge 101
	const char *subr_string;
102
	int subr_length;
103
	const char *np;
104
	int np_length;
105
	cairo_bool_t used;
106
    } *subrs;
1897 serge 107
 
3959 Serge 108
    /* Indexed by subset_index this maps to the glyph order in the
109
     * glyph_names and glyphs arrays. Has font->num_golyphs
110
     * elements. */
111
    int *subset_index_to_glyphs;
112
 
1897 serge 113
    cairo_output_stream_t *output;
114
    cairo_array_t contents;
115
 
3959 Serge 116
    const char *rd, *nd, *np;
1897 serge 117
 
3959 Serge 118
    int lenIV;
119
 
1897 serge 120
    char *type1_data;
121
    unsigned int type1_length;
122
    char *type1_end;
123
 
124
    char *header_segment;
125
    int header_segment_size;
126
    char *eexec_segment;
127
    int eexec_segment_size;
128
    cairo_bool_t eexec_segment_is_ascii;
129
 
130
    char *cleartext;
131
    char *cleartext_end;
132
 
133
    int header_size;
134
 
135
    unsigned short eexec_key;
136
    cairo_bool_t hex_encode;
137
    int hex_column;
3959 Serge 138
 
139
    struct {
140
	double stack[TYPE1_STACKSIZE];
141
	int sp;
142
    } build_stack;
143
 
144
    struct {
145
	int stack[TYPE1_STACKSIZE];
146
	int sp;
147
    } ps_stack;
148
 
149
 
1897 serge 150
} cairo_type1_font_subset_t;
151
 
152
 
153
static cairo_status_t
154
_cairo_type1_font_subset_init (cairo_type1_font_subset_t  *font,
3959 Serge 155
			       cairo_scaled_font_subset_t *scaled_font_subset,
1897 serge 156
			       cairo_bool_t                hex_encode)
157
{
158
    memset (font, 0, sizeof (*font));
3959 Serge 159
    font->scaled_font_subset = scaled_font_subset;
1897 serge 160
 
3959 Serge 161
    _cairo_array_init (&font->glyphs_array, sizeof (glyph_data_t));
162
    _cairo_array_init (&font->glyph_names_array, sizeof (char *));
163
    font->subset_index_to_glyphs = NULL;
164
    font->base.num_glyphs = 0;
165
    font->num_subrs = 0;
166
    font->subset_subrs = TRUE;
167
    font->subrs = NULL;
1897 serge 168
 
169
    font->hex_encode = hex_encode;
170
    font->num_glyphs = 0;
171
 
172
    _cairo_array_init (&font->contents, sizeof (char));
173
 
174
    return CAIRO_STATUS_SUCCESS;
175
}
176
 
177
static void
178
cairo_type1_font_subset_use_glyph (cairo_type1_font_subset_t *font, int glyph)
179
{
180
    if (font->glyphs[glyph].subset_index >= 0)
181
	return;
182
 
3959 Serge 183
    font->glyphs[glyph].subset_index = font->num_glyphs;
184
    font->subset_index_to_glyphs[font->num_glyphs] = glyph;
185
    font->num_glyphs++;
1897 serge 186
}
187
 
188
static cairo_bool_t
189
is_ps_delimiter(int c)
190
{
191
    static const char delimiters[] = "()[]{}<>/% \t\r\n";
192
 
193
    return strchr (delimiters, c) != NULL;
194
}
195
 
196
static const char *
197
find_token (const char *buffer, const char *end, const char *token)
198
{
199
    int i, length;
200
    /* FIXME: find substring really must be find_token */
201
 
202
    if (buffer == NULL)
203
	return NULL;
204
 
205
    length = strlen (token);
206
    for (i = 0; buffer + i < end - length + 1; i++)
207
	if (memcmp (buffer + i, token, length) == 0)
208
	    if ((i == 0 || token[0] == '/' || is_ps_delimiter(buffer[i - 1])) &&
209
		(buffer + i == end - length || is_ps_delimiter(buffer[i + length])))
210
		return buffer + i;
211
 
212
    return NULL;
213
}
214
 
215
static cairo_status_t
216
cairo_type1_font_subset_find_segments (cairo_type1_font_subset_t *font)
217
{
218
    unsigned char *p;
219
    const char *eexec_token;
220
    int size, i;
221
 
222
    p = (unsigned char *) font->type1_data;
223
    font->type1_end = font->type1_data + font->type1_length;
224
    if (p[0] == 0x80 && p[1] == 0x01) {
225
	font->header_segment_size =
226
	    p[2] | (p[3] << 8) | (p[4] << 16) | (p[5] << 24);
227
	font->header_segment = (char *) p + 6;
228
 
229
	p += 6 + font->header_segment_size;
230
	font->eexec_segment_size =
231
	    p[2] | (p[3] << 8) | (p[4] << 16) | (p[5] << 24);
232
	font->eexec_segment = (char *) p + 6;
233
	font->eexec_segment_is_ascii = (p[1] == 1);
234
 
235
        p += 6 + font->eexec_segment_size;
236
        while (p < (unsigned char *) (font->type1_end) && p[1] != 0x03) {
237
            size = p[2] | (p[3] << 8) | (p[4] << 16) | (p[5] << 24);
238
            p += 6 + size;
239
        }
240
        font->type1_end = (char *) p;
241
    } else {
242
	eexec_token = find_token ((char *) p, font->type1_end, "eexec");
243
	if (eexec_token == NULL)
244
	    return CAIRO_INT_STATUS_UNSUPPORTED;
245
 
246
	font->header_segment_size = eexec_token - (char *) p + strlen ("eexec\n");
247
	font->header_segment = (char *) p;
248
	font->eexec_segment_size = font->type1_length - font->header_segment_size;
249
	font->eexec_segment = (char *) p + font->header_segment_size;
250
	font->eexec_segment_is_ascii = TRUE;
251
	for (i = 0; i < 4; i++) {
252
	    if (!isxdigit(font->eexec_segment[i]))
253
		font->eexec_segment_is_ascii = FALSE;
254
	}
255
    }
256
 
257
    return CAIRO_STATUS_SUCCESS;
258
}
259
 
260
/* Search for the definition of key and erase it by overwriting with spaces.
261
 * This function is looks for definitions of the form:
262
 *
263
 * /key1 1234 def
264
 * /key2 [12 34 56] def
265
 *
266
 * ie a key defined as an integer or array of integers.
267
 *
268
 */
269
static void
270
cairo_type1_font_erase_dict_key (cairo_type1_font_subset_t *font,
271
				 const char *key)
272
{
273
    const char *start, *p, *segment_end;
274
 
275
    segment_end = font->header_segment + font->header_segment_size;
276
 
277
    start = font->header_segment;
278
    do {
279
	start = find_token (start, segment_end, key);
280
	if (start) {
281
	    p = start + strlen(key);
282
	    /* skip integers or array of integers */
283
	    while (p < segment_end &&
284
		   (_cairo_isspace(*p) ||
285
		    _cairo_isdigit(*p) ||
286
		    *p == '[' ||
287
		    *p == ']'))
288
	    {
289
		p++;
290
	    }
291
 
292
	    if (p + 3 < segment_end && memcmp(p, "def", 3) == 0) {
293
		/* erase definition of the key */
294
		memset((char *) start, ' ', p + 3 - start);
295
	    }
296
	    start += strlen(key);
297
	}
298
    } while (start);
299
}
300
 
301
static cairo_status_t
3959 Serge 302
cairo_type1_font_subset_get_matrix (cairo_type1_font_subset_t *font,
303
				    const char                *name,
304
				    double                    *a,
305
				    double                    *b,
306
				    double                    *c,
307
				    double                    *d)
308
{
309
    const char *start, *end, *segment_end;
310
    int ret, s_max, i, j;
311
    char *s;
312
    struct lconv *locale_data;
313
    const char *decimal_point;
314
    int decimal_point_len;
315
 
316
    locale_data = localeconv ();
317
    decimal_point = locale_data->decimal_point;
318
    decimal_point_len = strlen (decimal_point);
319
 
320
    assert (decimal_point_len != 0);
321
 
322
    segment_end = font->header_segment + font->header_segment_size;
323
    start = find_token (font->header_segment, segment_end, name);
324
    if (start == NULL)
325
	return CAIRO_INT_STATUS_UNSUPPORTED;
326
 
327
    end = find_token (start, segment_end, "def");
328
    if (end == NULL)
329
	return CAIRO_INT_STATUS_UNSUPPORTED;
330
 
331
    s_max = end - start + 5*decimal_point_len + 1;
332
    s = malloc (s_max);
333
    if (unlikely (s == NULL))
334
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
335
 
336
    i = 0;
337
    j = 0;
338
    while (i < end - start && j < s_max - decimal_point_len) {
339
	if (start[i] == '.') {
340
	    strncpy(s + j, decimal_point, decimal_point_len);
341
	    i++;
342
	    j += decimal_point_len;
343
	} else {
344
	    s[j++] = start[i++];
345
	}
346
    }
347
    s[j] = 0;
348
 
349
    start = strpbrk (s, "{[");
350
    if (!start) {
351
	free (s);
352
	return CAIRO_INT_STATUS_UNSUPPORTED;
353
    }
354
 
355
    start++;
356
    ret = 0;
357
    if (*start)
358
	ret = sscanf(start, "%lf %lf %lf %lf", a, b, c, d);
359
 
360
    free (s);
361
 
362
    if (ret != 4)
363
	return CAIRO_INT_STATUS_UNSUPPORTED;
364
 
365
    return CAIRO_STATUS_SUCCESS;
366
}
367
 
368
static cairo_status_t
369
cairo_type1_font_subset_get_bbox (cairo_type1_font_subset_t *font)
370
{
371
    cairo_status_t status;
372
    double x_min, y_min, x_max, y_max;
373
    double xx, yx, xy, yy;
374
 
375
    status = cairo_type1_font_subset_get_matrix (font, "/FontBBox",
376
						 &x_min,
377
						 &y_min,
378
						 &x_max,
379
						 &y_max);
380
    if (unlikely (status))
381
	return status;
382
 
383
    status = cairo_type1_font_subset_get_matrix (font, "/FontMatrix",
384
						 &xx, &yx, &xy, &yy);
385
    if (unlikely (status))
386
	return status;
387
 
388
    if (yy == 0.0)
389
	return CAIRO_INT_STATUS_UNSUPPORTED;
390
 
391
    /* Freetype uses 1/yy to get units per EM */
392
    font->base.units_per_em = 1.0/yy;
393
 
394
    font->base.x_min = x_min / font->base.units_per_em;
395
    font->base.y_min = y_min / font->base.units_per_em;
396
    font->base.x_max = x_max / font->base.units_per_em;
397
    font->base.y_max = y_max / font->base.units_per_em;
398
    font->base.ascent = font->base.y_max;
399
    font->base.descent = font->base.y_min;
400
 
401
    return CAIRO_STATUS_SUCCESS;
402
}
403
 
404
static cairo_status_t
405
cairo_type1_font_subset_get_fontname (cairo_type1_font_subset_t *font)
406
{
407
    const char *start, *end, *segment_end;
408
    char *s;
409
    int i;
410
 
411
    segment_end = font->header_segment + font->header_segment_size;
412
    start = find_token (font->header_segment, segment_end, "/FontName");
413
    if (start == NULL)
414
	return CAIRO_INT_STATUS_UNSUPPORTED;
415
 
416
    start += strlen ("/FontName");
417
 
418
    end = find_token (start, segment_end, "def");
419
    if (end == NULL)
420
	return CAIRO_INT_STATUS_UNSUPPORTED;
421
 
422
    s = malloc (end - start + 1);
423
    if (unlikely (s == NULL))
424
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
425
 
426
    strncpy (s, start, end - start);
427
    s[end - start] = 0;
428
 
429
    start = strchr (s, '/');
430
    if (!start++ || !start) {
431
	free (s);
432
	return CAIRO_INT_STATUS_UNSUPPORTED;
433
    }
434
 
435
    /* If font name is prefixed with a subset tag, strip it off. */
436
    if (strlen(start) > 7 && start[6] == '+') {
437
	for (i = 0; i < 6; i++) {
438
	    if (start[i] < 'A' || start[i] > 'Z')
439
		break;
440
	}
441
	if (i == 6)
442
	    start += 7;
443
    }
444
 
445
    font->base.base_font = strdup (start);
446
    free (s);
447
    if (unlikely (font->base.base_font == NULL))
448
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
449
 
450
    s = font->base.base_font;
451
    while (*s && !is_ps_delimiter(*s))
452
	s++;
453
 
454
    *s = 0;
455
 
456
    return CAIRO_STATUS_SUCCESS;
457
}
458
 
459
static cairo_status_t
1897 serge 460
cairo_type1_font_subset_write_header (cairo_type1_font_subset_t *font,
461
					 const char *name)
462
{
463
    const char *start, *end, *segment_end;
464
    unsigned int i;
465
 
466
    /* FIXME:
467
     * This function assumes that /FontName always appears
468
     * before /Encoding. This appears to always be the case with Type1
469
     * fonts.
470
     *
471
     * The more recently added code for removing the UniqueID and XUID
472
     * keys can not make any assumptions about the position of the
473
     * keys in the dictionary so it is implemented by overwriting the
474
     * key definition with spaces before we start copying the font to
475
     * the output.
476
     *
477
     * This code should be rewritten to not make any assumptions about
478
     * the order of dictionary keys. This will allow UniqueID to be
479
     * stripped out instead of leaving a bunch of spaces in the
480
     * output.
481
     */
482
    cairo_type1_font_erase_dict_key (font, "/UniqueID");
483
    cairo_type1_font_erase_dict_key (font, "/XUID");
484
 
485
    segment_end = font->header_segment + font->header_segment_size;
486
 
487
    /* Type 1 fonts created by Fontforge have some PostScript code at
488
     * the start of the font that skips the font if the printer has a
489
     * cached copy of the font with the same unique id. This breaks
490
     * our subsetted font so we disable it by searching for the
491
     * PostScript operator "known" when used to check for the
492
     * "/UniqueID" dictionary key. We append " pop false " after it to
493
     * pop the result of this check off the stack and replace it with
494
     * "false" to make the PostScript code think "/UniqueID" does not
495
     * exist.
496
     */
497
    end = font->header_segment;
498
    start = find_token (font->header_segment, segment_end, "/UniqueID");
499
    if (start) {
500
	start += 9;
501
	while (start < segment_end && _cairo_isspace (*start))
502
	    start++;
503
	if (start + 5 < segment_end && memcmp(start, "known", 5) == 0) {
504
	    _cairo_output_stream_write (font->output, font->header_segment,
505
					start + 5 - font->header_segment);
506
	    _cairo_output_stream_printf (font->output, " pop false ");
507
	    end = start + 5;
508
	}
509
    }
510
 
511
    start = find_token (end, segment_end, "/FontName");
512
    if (start == NULL)
513
	return CAIRO_INT_STATUS_UNSUPPORTED;
514
 
515
    _cairo_output_stream_write (font->output, end,
516
				start - end);
517
 
518
    _cairo_output_stream_printf (font->output, "/FontName /%s def", name);
519
 
520
    end = find_token (start, segment_end, "def");
521
    if (end == NULL)
522
	return CAIRO_INT_STATUS_UNSUPPORTED;
523
    end += 3;
524
 
525
    start = find_token (end, segment_end, "/Encoding");
526
    if (start == NULL)
527
	return CAIRO_INT_STATUS_UNSUPPORTED;
528
    _cairo_output_stream_write (font->output, end, start - end);
529
 
530
    _cairo_output_stream_printf (font->output,
531
				 "/Encoding 256 array\n"
532
				 "0 1 255 {1 index exch /.notdef put} for\n");
3959 Serge 533
    if (font->scaled_font_subset->is_latin) {
534
	for (i = 1; i < 256; i++) {
535
	    int subset_glyph = font->scaled_font_subset->latin_to_subset_glyph_index[i];
536
 
537
	    if (subset_glyph > 0) {
538
		_cairo_output_stream_printf (font->output,
539
					     "dup %d /%s put\n",
540
					     i,
541
					     _cairo_winansi_to_glyphname (i));
542
	    }
543
	}
544
    } else {
545
	for (i = 0; i < font->base.num_glyphs; i++) {
546
	    if (font->glyphs[i].subset_index <= 0)
547
		continue;
548
	    _cairo_output_stream_printf (font->output,
549
					 "dup %d /%s put\n",
550
					 font->glyphs[i].subset_index,
551
					 font->glyph_names[i]);
552
	}
1897 serge 553
    }
554
    _cairo_output_stream_printf (font->output, "readonly def");
555
 
556
    end = find_token (start, segment_end, "def");
557
    if (end == NULL)
558
	return CAIRO_INT_STATUS_UNSUPPORTED;
559
    end += 3;
560
 
3959 Serge 561
    /* There are some buggy fonts that contain more than one /Encoding */
562
    if (find_token (end, segment_end, "/Encoding"))
563
	return CAIRO_INT_STATUS_UNSUPPORTED;
564
 
1897 serge 565
    _cairo_output_stream_write (font->output, end, segment_end - end);
566
 
567
    return font->output->status;
568
}
569
 
570
static int
571
hex_to_int (int ch)
572
{
573
    if (ch <= '9')
574
	return ch - '0';
575
    else if (ch <= 'F')
576
	return ch - 'A' + 10;
577
    else
578
	return ch - 'a' + 10;
579
}
580
 
581
static cairo_status_t
582
cairo_type1_font_subset_write_encrypted (cairo_type1_font_subset_t *font,
583
					 const char *data, unsigned int length)
584
{
585
    const unsigned char *in, *end;
586
    int c, p;
587
    static const char hex_digits[16] = "0123456789abcdef";
588
    char digits[3];
589
 
590
    in = (const unsigned char *) data;
591
    end = (const unsigned char *) data + length;
592
    while (in < end) {
593
	p = *in++;
594
	c = p ^ (font->eexec_key >> 8);
595
	font->eexec_key = (c + font->eexec_key) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
596
 
597
	if (font->hex_encode) {
598
	    digits[0] = hex_digits[c >> 4];
599
	    digits[1] = hex_digits[c & 0x0f];
600
	    digits[2] = '\n';
601
	    font->hex_column += 2;
602
 
603
	    if (font->hex_column == 78) {
604
		_cairo_output_stream_write (font->output, digits, 3);
605
		font->hex_column = 0;
606
	    } else {
607
		_cairo_output_stream_write (font->output, digits, 2);
608
	    }
609
	} else {
610
	    digits[0] = c;
611
	    _cairo_output_stream_write (font->output, digits, 1);
612
	}
613
    }
614
 
615
    return font->output->status;
616
}
617
 
618
static cairo_status_t
619
cairo_type1_font_subset_decrypt_eexec_segment (cairo_type1_font_subset_t *font)
620
{
621
    unsigned short r = CAIRO_TYPE1_PRIVATE_DICT_KEY;
622
    unsigned char *in, *end;
623
    char *out;
624
    int c, p;
625
    int i;
626
 
627
    in = (unsigned char *) font->eexec_segment;
628
    end = (unsigned char *) in + font->eexec_segment_size;
629
 
3959 Serge 630
    font->cleartext = malloc (font->eexec_segment_size + 1);
1897 serge 631
    if (unlikely (font->cleartext == NULL))
632
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
633
 
634
    out = font->cleartext;
635
    while (in < end) {
636
	if (font->eexec_segment_is_ascii) {
637
	    c = *in++;
638
	    if (_cairo_isspace (c))
639
		continue;
640
	    c = (hex_to_int (c) << 4) | hex_to_int (*in++);
641
	} else {
642
	    c = *in++;
643
	}
644
	p = c ^ (r >> 8);
645
	r = (c + r) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
646
 
647
	*out++ = p;
648
    }
649
    font->cleartext_end = out;
650
 
651
    /* Overwrite random bytes with spaces.
652
     *
653
     * The first 4 bytes of the cleartext are the random bytes
654
     * required by the encryption algorithm. When encrypting the
655
     * cleartext, the first ciphertext byte must not be a white space
656
     * character and the first 4 bytes must not be an ASCII Hex
657
     * character. Some fonts do not check that their randomly chosen
658
     * bytes results in ciphertext that complies with this
659
     * restriction. This may cause problems for some PDF consumers. By
660
     * replacing the random bytes with spaces, the first four bytes of
661
     * ciphertext will always be 0xf9, 0x83, 0xef, 0x00 which complies
662
     * with this restriction. Using spaces also means we don't have to
663
     * skip over the random bytes when parsing the cleartext.
664
     */
665
    for (i = 0; i < 4 && i < font->eexec_segment_size; i++)
666
	font->cleartext[i] = ' ';
667
 
3959 Serge 668
    /* Ensure strtol() can not scan past the end of the cleartext */
669
    font->cleartext[font->eexec_segment_size] = 0;
670
 
1897 serge 671
    return CAIRO_STATUS_SUCCESS;
672
}
673
 
674
static const char *
675
skip_token (const char *p, const char *end)
676
{
677
    while (p < end && _cairo_isspace(*p))
678
	p++;
679
 
680
    while (p < end && !_cairo_isspace(*p))
681
	p++;
682
 
683
    if (p == end)
684
	return NULL;
685
 
686
    return p;
687
}
688
 
689
static void
690
cairo_type1_font_subset_decrypt_charstring (const unsigned char *in, int size, unsigned char *out)
691
{
692
    unsigned short r = CAIRO_TYPE1_CHARSTRING_KEY;
693
    int c, p, i;
694
 
695
    for (i = 0; i < size; i++) {
696
        c = *in++;
697
	p = c ^ (r >> 8);
698
	r = (c + r) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
699
	*out++ = p;
700
    }
701
}
702
 
703
static const unsigned char *
704
cairo_type1_font_subset_decode_integer (const unsigned char *p, int *integer)
705
{
706
    if (*p <= 246) {
707
        *integer = *p++ - 139;
708
    } else if (*p <= 250) {
709
        *integer = (p[0] - 247) * 256 + p[1] + 108;
710
        p += 2;
711
    } else if (*p <= 254) {
712
        *integer = -(p[0] - 251) * 256 - p[1] - 108;
713
        p += 2;
714
    } else {
715
        *integer = (p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4];
716
        p += 5;
717
    }
718
 
719
    return p;
720
}
721
 
722
static cairo_status_t
723
use_standard_encoding_glyph (cairo_type1_font_subset_t *font, int index)
724
{
725
    const char *glyph_name;
3959 Serge 726
    unsigned int i;
1897 serge 727
 
728
    if (index < 0 || index > 255)
729
	return CAIRO_STATUS_SUCCESS;
730
 
3959 Serge 731
    glyph_name = _cairo_ps_standard_encoding_to_glyphname (index);
1897 serge 732
    if (glyph_name == NULL)
733
	return CAIRO_STATUS_SUCCESS;
734
 
3959 Serge 735
    for (i = 0; i < font->base.num_glyphs; i++) {
736
	if (font->glyph_names[i] &&  strcmp (font->glyph_names[i], glyph_name) == 0) {
737
	    cairo_type1_font_subset_use_glyph (font, i);
1897 serge 738
 
3959 Serge 739
	    return CAIRO_STATUS_SUCCESS;
740
	}
741
    }
1897 serge 742
 
3959 Serge 743
    return CAIRO_INT_STATUS_UNSUPPORTED;
1897 serge 744
}
745
 
746
 
3959 Serge 747
#define TYPE1_CHARSTRING_COMMAND_HSTEM		 0x01
748
#define TYPE1_CHARSTRING_COMMAND_VSTEM		 0x03
749
#define TYPE1_CHARSTRING_COMMAND_VMOVETO	 0x04
750
#define TYPE1_CHARSTRING_COMMAND_RLINETO	 0x05
751
#define TYPE1_CHARSTRING_COMMAND_HLINETO	 0x06
752
#define TYPE1_CHARSTRING_COMMAND_VLINETO	 0x07
753
#define TYPE1_CHARSTRING_COMMAND_RRCURVETO	 0x08
754
#define TYPE1_CHARSTRING_COMMAND_CLOSEPATH	 0x09
755
#define TYPE1_CHARSTRING_COMMAND_CALLSUBR	 0x0a
756
#define TYPE1_CHARSTRING_COMMAND_RETURN		 0x0b
757
#define TYPE1_CHARSTRING_COMMAND_ESCAPE		 0x0c
758
#define TYPE1_CHARSTRING_COMMAND_HSBW		 0x0d
759
#define TYPE1_CHARSTRING_COMMAND_ENDCHAR	 0x0e
760
#define TYPE1_CHARSTRING_COMMAND_RMOVETO	 0x15
761
#define TYPE1_CHARSTRING_COMMAND_HMOVETO	 0x16
762
#define TYPE1_CHARSTRING_COMMAND_VHCURVETO	 0x1e
763
#define TYPE1_CHARSTRING_COMMAND_HVCURVETO	 0x1f
764
#define TYPE1_CHARSTRING_COMMAND_DOTSECTION	 0x0c00
765
#define TYPE1_CHARSTRING_COMMAND_VSTEM3		 0x0c01
766
#define TYPE1_CHARSTRING_COMMAND_HSTEM3		 0x0c02
767
#define TYPE1_CHARSTRING_COMMAND_SEAC		 0x0c06
768
#define TYPE1_CHARSTRING_COMMAND_SBW		 0x0c07
769
#define TYPE1_CHARSTRING_COMMAND_DIV		 0x0c0c
770
#define TYPE1_CHARSTRING_COMMAND_CALLOTHERSUBR   0x0c10
771
#define TYPE1_CHARSTRING_COMMAND_POP	         0x0c11
772
#define TYPE1_CHARSTRING_COMMAND_SETCURRENTPOINT 0x0c21
773
 
774
/* Parse the charstring, including recursing into subroutines. Find
775
 * the glyph width, subroutines called, and glyphs required by the
776
 * SEAC operator. */
1897 serge 777
static cairo_status_t
3959 Serge 778
cairo_type1_font_subset_parse_charstring (cairo_type1_font_subset_t *font,
779
					  int                        glyph,
780
					  const char                *encrypted_charstring,
781
					  int                        encrypted_charstring_length)
1897 serge 782
{
783
    cairo_status_t status;
784
    unsigned char *charstring;
785
    const unsigned char *end;
786
    const unsigned char *p;
787
    int command;
788
 
789
    charstring = malloc (encrypted_charstring_length);
790
    if (unlikely (charstring == NULL))
791
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
792
 
793
    cairo_type1_font_subset_decrypt_charstring ((const unsigned char *)
794
						encrypted_charstring,
795
						encrypted_charstring_length,
796
						charstring);
797
    end = charstring + encrypted_charstring_length;
3959 Serge 798
    p = charstring + font->lenIV;
799
    status = CAIRO_STATUS_SUCCESS;
1897 serge 800
    while (p < end) {
801
        if (*p < 32) {
802
	    command = *p++;
3959 Serge 803
	    switch (command) {
804
	    case TYPE1_CHARSTRING_COMMAND_HSTEM:
805
	    case TYPE1_CHARSTRING_COMMAND_VSTEM:
806
	    case TYPE1_CHARSTRING_COMMAND_VMOVETO:
807
	    case TYPE1_CHARSTRING_COMMAND_RLINETO:
808
	    case TYPE1_CHARSTRING_COMMAND_HLINETO:
809
	    case TYPE1_CHARSTRING_COMMAND_VLINETO:
810
	    case TYPE1_CHARSTRING_COMMAND_RRCURVETO:
811
	    case TYPE1_CHARSTRING_COMMAND_CLOSEPATH:
812
	    case TYPE1_CHARSTRING_COMMAND_RMOVETO:
813
	    case TYPE1_CHARSTRING_COMMAND_HMOVETO:
814
	    case TYPE1_CHARSTRING_COMMAND_VHCURVETO:
815
	    case TYPE1_CHARSTRING_COMMAND_HVCURVETO:
816
	    case TYPE1_CHARSTRING_COMMAND_RETURN:
817
	    case TYPE1_CHARSTRING_COMMAND_ENDCHAR:
818
	    default:
819
		/* stack clearing operator */
820
		font->build_stack.sp = 0;
821
		break;
1897 serge 822
 
3959 Serge 823
	    case TYPE1_CHARSTRING_COMMAND_CALLSUBR:
824
		if (font->subset_subrs && font->build_stack.sp > 0) {
825
		    double int_val;
826
		    if (modf(font->build_stack.stack[--font->build_stack.sp], &int_val) == 0.0) {
827
			int subr_num = int_val;
828
			if (subr_num >= 0 && subr_num < font->num_subrs) {
829
			    font->subrs[subr_num].used = TRUE;
830
			    status = cairo_type1_font_subset_parse_charstring (
831
				font,
832
				glyph,
833
				font->subrs[subr_num].subr_string,
834
				font->subrs[subr_num].subr_length);
835
			    break;
836
			}
837
		    }
838
		}
839
		font->subset_subrs = FALSE;
840
		break;
1897 serge 841
 
3959 Serge 842
	    case TYPE1_CHARSTRING_COMMAND_HSBW:
843
		if (font->build_stack.sp < 2) {
844
		    status = CAIRO_INT_STATUS_UNSUPPORTED;
845
		    goto cleanup;
846
		}
1897 serge 847
 
3959 Serge 848
		font->glyphs[glyph].width = font->build_stack.stack[1]/font->base.units_per_em;
849
		font->build_stack.sp = 0;
1897 serge 850
		break;
851
 
3959 Serge 852
	    case TYPE1_CHARSTRING_COMMAND_ESCAPE:
853
		command = command << 8 | *p++;
854
		switch (command) {
855
		case TYPE1_CHARSTRING_COMMAND_DOTSECTION:
856
		case TYPE1_CHARSTRING_COMMAND_VSTEM3:
857
		case TYPE1_CHARSTRING_COMMAND_HSTEM3:
858
		case TYPE1_CHARSTRING_COMMAND_SETCURRENTPOINT:
859
		default:
860
		    /* stack clearing operator */
861
		    font->build_stack.sp = 0;
862
		    break;
863
 
864
		case TYPE1_CHARSTRING_COMMAND_SEAC:
865
		    /* The seac command takes five integer arguments.  The
866
		     * last two are glyph indices into the PS standard
867
		     * encoding give the names of the glyphs that this
868
		     * glyph is composed from.  All we need to do is to
869
		     * make sure those glyphs are present in the subset
870
		     * under their standard names. */
871
		    if (font->build_stack.sp < 5) {
872
			status = CAIRO_INT_STATUS_UNSUPPORTED;
873
			goto cleanup;
874
		    }
875
 
876
		    status = use_standard_encoding_glyph (font, font->build_stack.stack[3]);
877
		    if (unlikely (status))
878
			goto cleanup;
879
 
880
		    status = use_standard_encoding_glyph (font, font->build_stack.stack[4]);
881
		    if (unlikely (status))
882
			goto cleanup;
883
 
884
		    font->build_stack.sp = 0;
885
		    break;
886
 
887
		case TYPE1_CHARSTRING_COMMAND_SBW:
888
		    if (font->build_stack.sp < 4) {
889
			status = CAIRO_INT_STATUS_UNSUPPORTED;
890
			goto cleanup;
891
		    }
892
 
893
		    font->glyphs[glyph].width = font->build_stack.stack[2]/font->base.units_per_em;
894
		    font->build_stack.sp = 0;
895
		    break;
896
 
897
		case TYPE1_CHARSTRING_COMMAND_DIV:
898
		    if (font->build_stack.sp < 2) {
899
			status = CAIRO_INT_STATUS_UNSUPPORTED;
900
			goto cleanup;
901
		    } else {
902
			double num1 = font->build_stack.stack[font->build_stack.sp - 2];
903
			double num2 = font->build_stack.stack[font->build_stack.sp - 1];
904
			font->build_stack.sp--;
905
			if (num2 == 0.0) {
906
			    status = CAIRO_INT_STATUS_UNSUPPORTED;
907
			    goto cleanup;
908
			}
909
			font->build_stack.stack[font->build_stack.sp - 1] = num1/num2;
910
		    }
911
		    break;
912
 
913
		case TYPE1_CHARSTRING_COMMAND_CALLOTHERSUBR:
914
		    if (font->build_stack.sp < 1) {
915
			status = CAIRO_INT_STATUS_UNSUPPORTED;
916
			goto cleanup;
917
		    }
918
 
919
		    font->build_stack.sp--;
920
		    font->ps_stack.sp = 0;
921
		    while (font->build_stack.sp)
922
			font->ps_stack.stack[font->ps_stack.sp++] = font->build_stack.stack[--font->build_stack.sp];
923
 
924
                    break;
925
 
926
		case TYPE1_CHARSTRING_COMMAND_POP:
927
		    if (font->ps_stack.sp < 1) {
928
			status = CAIRO_INT_STATUS_UNSUPPORTED;
929
			goto cleanup;
930
		    }
931
 
932
		    /* T1 spec states that if the interpreter does not
933
		     * support executing the callothersub, the results
934
		     * must be taken from the callothersub arguments. */
935
		    font->build_stack.stack[font->build_stack.sp++] = font->ps_stack.stack[--font->ps_stack.sp];
936
		    break;
937
		}
1897 serge 938
		break;
939
	    }
3959 Serge 940
	} else {
1897 serge 941
            /* integer argument */
3959 Serge 942
	    if (font->build_stack.sp < TYPE1_STACKSIZE) {
943
		int val;
944
		p = cairo_type1_font_subset_decode_integer (p, &val);
945
		font->build_stack.stack[font->build_stack.sp++] = val;
946
	    } else {
947
		status = CAIRO_INT_STATUS_UNSUPPORTED;
948
		goto cleanup;
949
	    }
950
	}
1897 serge 951
    }
952
 
3959 Serge 953
cleanup:
1897 serge 954
    free (charstring);
955
 
3959 Serge 956
    return status;
957
}
958
 
959
static cairo_status_t
960
cairo_type1_font_subset_build_subr_list (cairo_type1_font_subset_t *font,
961
					 int subr_number,
962
					 const char *encrypted_charstring, int encrypted_charstring_length,
963
					 const char *np, int np_length)
964
{
965
 
966
    font->subrs[subr_number].subr_string = encrypted_charstring;
967
    font->subrs[subr_number].subr_length = encrypted_charstring_length;
968
    font->subrs[subr_number].np = np;
969
    font->subrs[subr_number].np_length = np_length;
970
 
1897 serge 971
    return CAIRO_STATUS_SUCCESS;
972
}
973
 
974
static cairo_status_t
3959 Serge 975
write_used_subrs (cairo_type1_font_subset_t *font,
976
		  int subr_number,
977
		  const char *subr_string, int subr_string_length,
978
		  const char *np, int np_length)
979
{
980
    cairo_status_t status;
981
    char buffer[256];
982
    int length;
983
 
984
    if (!font->subrs[subr_number].used)
985
	return CAIRO_STATUS_SUCCESS;
986
 
987
    length = snprintf (buffer, sizeof buffer,
988
		       "dup %d %d %s ",
989
		       subr_number, subr_string_length, font->rd);
990
    status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
991
    if (unlikely (status))
992
	return status;
993
 
994
    status = cairo_type1_font_subset_write_encrypted (font,
995
					              subr_string,
996
						      subr_string_length);
997
    if (unlikely (status))
998
	return status;
999
 
1000
    if (np) {
1001
	status = cairo_type1_font_subset_write_encrypted (font, np, np_length);
1002
    } else {
1003
	length = snprintf (buffer, sizeof buffer, "%s\n", font->np);
1004
	status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
1005
    }
1006
    if (unlikely (status))
1007
	return status;
1008
 
1009
    return CAIRO_STATUS_SUCCESS;
1010
}
1011
 
1012
typedef cairo_status_t (*subr_func_t) (cairo_type1_font_subset_t *font,
1013
				       int subr_number,
1014
				       const char *subr_string, int subr_string_length,
1015
				       const char *np, int np_length);
1016
 
1017
static cairo_status_t
1018
cairo_type1_font_for_each_subr (cairo_type1_font_subset_t  *font,
1019
				const char                 *array_start,
1020
				const char                 *cleartext_end,
1021
				subr_func_t                 func,
1022
				const char                **array_end)
1023
{
1024
    const char *p, *subr_string;
1025
    char *end;
1026
    int subr_num, subr_length;
1027
    const char *np;
1028
    int np_length;
1029
    cairo_status_t status;
1030
 
1031
    /* We're looking at "dup" at the start of the first subroutine. The subroutines
1032
     * definitions are on the form:
1033
     *
1034
     *   dup 5 23 RD <23 binary bytes> NP
1035
     *
1036
     * or alternatively using -| and |- instead of RD and ND.
1037
     * The first number is the subroutine number.
1038
     */
1039
 
1040
    p = array_start;
1041
    while (p + 3 < cleartext_end && strncmp (p, "dup", 3) == 0) {
1042
	p = skip_token (p, cleartext_end);
1043
 
1044
	/* get subr number */
1045
	subr_num = strtol (p, &end, 10);
1046
	if (p == end)
1047
	    return CAIRO_INT_STATUS_UNSUPPORTED;
1048
 
1049
	if (subr_num < 0 || subr_num >= font->num_subrs)
1050
	    return CAIRO_INT_STATUS_UNSUPPORTED;
1051
 
1052
	/* get subr length */
1053
	p = end;
1054
	subr_length = strtol (p, &end, 10);
1055
	if (p == end)
1056
	    return CAIRO_INT_STATUS_UNSUPPORTED;
1057
 
1058
	/* Skip past -| or RD to binary data.  There is exactly one space
1059
	 * between the -| or RD token and the encrypted data, thus '+ 1'. */
1060
	subr_string = skip_token (end, cleartext_end) + 1;
1061
 
1062
	np = NULL;
1063
	np_length = 0;
1064
 
1065
	/* Skip binary data and | or NP token. */
1066
	p = skip_token (subr_string + subr_length, cleartext_end);
1067
	while (p < cleartext_end && _cairo_isspace(*p))
1068
	    p++;
1069
 
1070
	/* Some fonts have "noaccess put" instead of "NP" */
1071
	if (p + 3 < cleartext_end && strncmp (p, "put", 3) == 0) {
1072
	    p = skip_token (p, cleartext_end);
1073
	    while (p < cleartext_end && _cairo_isspace(*p))
1074
		p++;
1075
 
1076
	    np = subr_string + subr_length;
1077
	    np_length = p - np;
1078
	}
1079
 
1080
	status = func (font, subr_num,
1081
		       subr_string, subr_length, np, np_length);
1082
	if (unlikely (status))
1083
	    return status;
1084
 
1085
    }
1086
 
1087
    *array_end = (char *) p;
1088
 
1089
    return CAIRO_STATUS_SUCCESS;
1090
}
1091
 
1092
static cairo_status_t
1093
cairo_type1_font_subset_build_glyph_list (cairo_type1_font_subset_t *font,
1094
					  int glyph_number,
1095
					  const char *name, int name_length,
1096
					  const char *encrypted_charstring, int encrypted_charstring_length)
1097
{
1098
    char *s;
1099
    glyph_data_t glyph;
1100
    cairo_status_t status;
1101
 
1102
    s = malloc (name_length + 1);
1103
    if (unlikely (s == NULL))
1104
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1105
 
1106
    strncpy (s, name, name_length);
1107
    s[name_length] = 0;
1108
 
1109
    status = _cairo_array_append (&font->glyph_names_array, &s);
1110
    if (unlikely (status))
1111
	return status;
1112
 
1113
    glyph.subset_index = -1;
1114
    glyph.width = 0;
1115
    glyph.encrypted_charstring = encrypted_charstring;
1116
    glyph.encrypted_charstring_length = encrypted_charstring_length;
1117
    status = _cairo_array_append (&font->glyphs_array, &glyph);
1118
 
1119
    return status;
1120
}
1121
 
1122
static cairo_status_t
1897 serge 1123
write_used_glyphs (cairo_type1_font_subset_t *font,
3959 Serge 1124
		   int glyph_number,
1897 serge 1125
		   const char *name, int name_length,
1126
		   const char *charstring, int charstring_length)
1127
{
1128
    cairo_status_t status;
1129
    char buffer[256];
1130
    int length;
3959 Serge 1131
    int subset_id;
1132
    int ch;
1133
    const char *wa_name;
1897 serge 1134
 
3959 Serge 1135
    if (font->glyphs[glyph_number].subset_index < 0)
1136
	return CAIRO_STATUS_SUCCESS;
1137
 
1138
    if (font->scaled_font_subset->is_latin) {
1139
	/* When using the WinAnsi encoding in PDF, the /Encoding array
1140
	 * is ignored and instead glyphs are keyed by glyph names. To
1141
	 * ensure correct rendering we replace the glyph name in the
1142
	 * font with the standard name.
1143
         **/
1144
	subset_id = font->glyphs[glyph_number].subset_index;
1145
	if (subset_id > 0) {
1146
	    ch = font->scaled_font_subset->to_latin_char[subset_id];
1147
	    wa_name = _cairo_winansi_to_glyphname (ch);
1148
	    /* If this subset contains any seac glyphs, additional non
1149
	     * winansi glyphs (wa_name = NULL) may be included in the
1150
	     * subset. In this case the original name is used.
1151
	     */
1152
	    if (wa_name) {
1153
		name = wa_name;
1154
		name_length = strlen(name);
1155
	    }
1156
	}
1157
    }
1158
 
1897 serge 1159
    length = snprintf (buffer, sizeof buffer,
1160
		       "/%.*s %d %s ",
1161
		       name_length, name, charstring_length, font->rd);
1162
    status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
1163
    if (unlikely (status))
1164
	return status;
1165
 
1166
    status = cairo_type1_font_subset_write_encrypted (font,
1167
					              charstring,
1168
						      charstring_length);
1169
    if (unlikely (status))
1170
	return status;
1171
 
1172
    length = snprintf (buffer, sizeof buffer, "%s\n", font->nd);
1173
    status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
1174
    if (unlikely (status))
1175
	return status;
1176
 
1177
    return CAIRO_STATUS_SUCCESS;
1178
}
1179
 
1180
typedef cairo_status_t (*glyph_func_t) (cairo_type1_font_subset_t *font,
3959 Serge 1181
					int glyph_number,
1897 serge 1182
			                const char *name, int name_length,
1183
			                const char *charstring, int charstring_length);
1184
 
1185
static cairo_status_t
1186
cairo_type1_font_subset_for_each_glyph (cairo_type1_font_subset_t *font,
1187
					const char *dict_start,
1188
					const char *dict_end,
1189
					glyph_func_t func,
1190
					const char **dict_out)
1191
{
3959 Serge 1192
    int charstring_length, name_length;
1897 serge 1193
    const char *p, *charstring, *name;
1194
    char *end;
3959 Serge 1195
    cairo_status_t status;
1196
    int glyph_count;
1897 serge 1197
 
1198
    /* We're looking at '/' in the name of the first glyph.  The glyph
1199
     * definitions are on the form:
1200
     *
1201
     *   /name 23 RD <23 binary bytes> ND
1202
     *
1203
     * or alternatively using -| and |- instead of RD and ND.
1204
     *
1205
     * We parse the glyph name and see if it is in the subset.  If it
1206
     * is, we call the specified callback with the glyph name and
1207
     * glyph data, otherwise we just skip it.  We need to parse
1208
     * through a glyph definition; we can't just find the next '/',
1209
     * since the binary data could contain a '/'.
1210
     */
1211
 
1212
    p = dict_start;
3959 Serge 1213
    glyph_count = 0;
1897 serge 1214
    while (*p == '/') {
1215
	name = p + 1;
1216
	p = skip_token (p, dict_end);
1217
	name_length = p - name;
1218
 
1219
	charstring_length = strtol (p, &end, 10);
1220
	if (p == end)
1221
	    return CAIRO_INT_STATUS_UNSUPPORTED;
1222
 
1223
	/* Skip past -| or RD to binary data.  There is exactly one space
1224
	 * between the -| or RD token and the encrypted data, thus '+ 1'. */
1225
	charstring = skip_token (end, dict_end) + 1;
1226
 
1227
	/* Skip binary data and |- or ND token. */
1228
	p = skip_token (charstring + charstring_length, dict_end);
1229
	while (p < dict_end && _cairo_isspace(*p))
1230
	    p++;
1231
 
1232
	/* In case any of the skip_token() calls above reached EOF, p will
1233
	 * be equal to dict_end. */
1234
	if (p == dict_end)
1235
	    return CAIRO_INT_STATUS_UNSUPPORTED;
1236
 
3959 Serge 1237
	status = func (font, glyph_count++,
1238
		       name, name_length,
1239
		       charstring, charstring_length);
1240
	if (unlikely (status))
1241
	    return status;
1897 serge 1242
    }
1243
 
1244
    *dict_out = p;
1245
 
1246
    return CAIRO_STATUS_SUCCESS;
1247
}
1248
 
1249
 
1250
static cairo_status_t
1251
cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
1252
					    const char                *name)
1253
{
1254
    cairo_status_t status;
3959 Serge 1255
    const char *p, *subrs, *charstrings, *array_start, *array_end, *dict_start, *dict_end;
1256
    const char *lenIV_start, *lenIV_end, *closefile_token;
1257
    char buffer[32], *lenIV_str, *subr_count_end, *glyph_count_end;
1258
    int ret, lenIV, length;
1259
    const cairo_scaled_font_backend_t *backend;
1260
    unsigned int i;
1261
    int glyph, j;
1897 serge 1262
 
1263
    /* The private dict holds hint information, common subroutines and
1264
     * the actual glyph definitions (charstrings).
1265
     *
3959 Serge 1266
     * What we do here is scan directly to the /Subrs token, which
1267
     * marks the beginning of the subroutines. We read in all the
1268
     * subroutines, then move on to the /CharString token, which marks
1269
     * the beginning of the glyph definitions, and read in the charstrings.
1897 serge 1270
     *
3959 Serge 1271
     * The charstrings are parsed to extract glyph widths, work out
1272
     * which subroutines are called, and to see if any extra glyphs
1273
     * need to be included due to the use of the seac glyph combining
1274
     * operator.
1275
     *
1276
     * Finally, the private dict is copied to the subset font minus the
1277
     * subroutines and charstrings not required.
1278
     */
1897 serge 1279
 
3959 Serge 1280
    /* Determine lenIV, the number of random characters at the start of
1281
       each encrypted charstring. The default is 4, but this can be
1282
       overridden in the private dict. */
1283
    font->lenIV = 4;
1284
    if ((lenIV_start = find_token (font->cleartext, font->cleartext_end, "/lenIV")) != NULL) {
1285
        lenIV_start += 6;
1286
        lenIV_end = find_token (lenIV_start, font->cleartext_end, "def");
1287
        if (lenIV_end == NULL)
1288
	    return CAIRO_INT_STATUS_UNSUPPORTED;
1289
 
1290
        lenIV_str = malloc (lenIV_end - lenIV_start + 1);
1291
        if (unlikely (lenIV_str == NULL))
1292
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1293
 
1294
        strncpy (lenIV_str, lenIV_start, lenIV_end - lenIV_start);
1295
        lenIV_str[lenIV_end - lenIV_start] = 0;
1296
 
1297
        ret = sscanf(lenIV_str, "%d", &lenIV);
1298
        free(lenIV_str);
1299
 
1300
        if (unlikely (ret <= 0))
1301
	    return CAIRO_INT_STATUS_UNSUPPORTED;
1302
 
1303
        /* Apparently some fonts signal unencrypted charstrings with a negative lenIV,
1304
           though this is not part of the Type 1 Font Format specification.  See, e.g.
1305
           http://lists.gnu.org/archive/html/freetype-devel/2000-06/msg00064.html. */
1306
        if (unlikely (lenIV < 0))
1307
	    return CAIRO_INT_STATUS_UNSUPPORTED;
1308
 
1309
        font->lenIV = lenIV;
1310
    }
1311
 
1312
    /* Find start of Subrs */
1313
    subrs = find_token (font->cleartext, font->cleartext_end, "/Subrs");
1314
    if (subrs == NULL) {
1315
	font->subset_subrs = FALSE;
1316
	p = font->cleartext;
1317
	array_start = NULL;
1318
	goto skip_subrs;
1319
    }
1320
 
1321
    /* Scan past /Subrs and get the array size. */
1322
    p = subrs + strlen ("/Subrs");
1323
    font->num_subrs = strtol (p, &subr_count_end, 10);
1324
    if (subr_count_end == p)
1325
	return CAIRO_INT_STATUS_UNSUPPORTED;
1326
 
1327
    if (font->num_subrs <= 0)
1328
	return CAIRO_INT_STATUS_UNSUPPORTED;
1329
 
1330
    font->subrs = calloc (font->num_subrs, sizeof (font->subrs[0]));
1331
    if (unlikely (font->subrs == NULL))
1332
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1333
 
1334
    /* look for "dup" which marks the beginning of the first subr */
1335
    array_start = find_token (subr_count_end, font->cleartext_end, "dup");
1336
    if (subrs == NULL)
1337
	return CAIRO_INT_STATUS_UNSUPPORTED;
1338
 
1339
    /* Read in the subroutines */
1340
    status = cairo_type1_font_for_each_subr (font,
1341
					     array_start,
1342
					     font->cleartext_end,
1343
					     cairo_type1_font_subset_build_subr_list,
1344
					     &array_end);
1345
    if (unlikely(status))
1346
	return status;
1347
 
1348
    p = array_end;
1349
skip_subrs:
1350
 
1351
    /* Find start of CharStrings */
1352
    charstrings = find_token (p, font->cleartext_end, "/CharStrings");
1897 serge 1353
    if (charstrings == NULL)
1354
	return CAIRO_INT_STATUS_UNSUPPORTED;
1355
 
1356
    /* Scan past /CharStrings and the integer following it. */
1357
    p = charstrings + strlen ("/CharStrings");
3959 Serge 1358
    strtol (p, &glyph_count_end, 10);
1897 serge 1359
    if (p == glyph_count_end)
1360
	return CAIRO_INT_STATUS_UNSUPPORTED;
1361
 
1362
    /* Look for a '/' which marks the beginning of the first glyph
1363
     * definition. */
1364
    for (p = glyph_count_end; p < font->cleartext_end; p++)
1365
	if (*p == '/')
1366
	    break;
1367
    if (p == font->cleartext_end)
1368
	return CAIRO_INT_STATUS_UNSUPPORTED;
1369
    dict_start = p;
1370
 
1371
    /* Now that we have the private dictionary broken down in
1372
     * sections, do the first pass through the glyph definitions to
3959 Serge 1373
     * build a list of glyph names and charstrings. */
1897 serge 1374
    status = cairo_type1_font_subset_for_each_glyph (font,
1375
						     dict_start,
1376
						     font->cleartext_end,
3959 Serge 1377
						     cairo_type1_font_subset_build_glyph_list,
1378
						     &dict_end);
1379
    if (unlikely(status))
1897 serge 1380
	return status;
1381
 
3959 Serge 1382
    font->glyphs = _cairo_array_index (&font->glyphs_array, 0);
1383
    font->glyph_names = _cairo_array_index (&font->glyph_names_array, 0);
1384
    font->base.num_glyphs = _cairo_array_num_elements (&font->glyphs_array);
1385
    font->subset_index_to_glyphs = calloc (font->base.num_glyphs, sizeof font->subset_index_to_glyphs[0]);
1386
    if (unlikely (font->subset_index_to_glyphs == NULL))
1387
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1388
 
1389
    backend = font->scaled_font_subset->scaled_font->backend;
1390
    if (!backend->index_to_glyph_name)
1391
	return CAIRO_INT_STATUS_UNSUPPORTED;
1392
 
1393
    /* Find the glyph number corresponding to each glyph in the subset
1394
     * and mark it as in use */
1395
 
1396
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
1397
	unsigned long index;
1398
 
1399
	status = backend->index_to_glyph_name (font->scaled_font_subset->scaled_font,
1400
					       font->glyph_names,
1401
					       font->base.num_glyphs,
1402
					       font->scaled_font_subset->glyphs[i],
1403
					       &index);
1404
	if (unlikely(status))
1405
	    return status;
1406
 
1407
	cairo_type1_font_subset_use_glyph (font, index);
1408
    }
1409
 
1410
    /* Go through the charstring of each glyph in use, get the glyph
1411
     * width and figure out which extra glyphs may be required by the
1412
     * seac operator (which may cause font->num_glyphs to increase
1413
     * while this loop is executing). Also subset the Subrs. */
1414
    for (j = 0; j < font->num_glyphs; j++) {
1415
	glyph = font->subset_index_to_glyphs[j];
1416
	font->build_stack.sp = 0;
1417
	font->ps_stack.sp = 0;
1418
	status = cairo_type1_font_subset_parse_charstring (font,
1419
							   glyph,
1420
							   font->glyphs[glyph].encrypted_charstring,
1421
							   font->glyphs[glyph].encrypted_charstring_length);
1422
	if (unlikely (status))
1423
	    return status;
1424
    }
1425
 
1426
    /* Always include the first five subroutines in case the Flex/hint mechanism is
1427
     * being used. */
1428
    for (j = 0; j < MIN (font->num_subrs, 5); j++) {
1429
	font->subrs[j].used = TRUE;
1430
    }
1431
 
1432
    closefile_token = find_token (dict_end, font->cleartext_end, "closefile");
1897 serge 1433
    if (closefile_token == NULL)
1434
	return CAIRO_INT_STATUS_UNSUPPORTED;
1435
 
1436
    /* We're ready to start outputting. First write the header,
1437
     * i.e. the public part of the font dict.*/
1438
    status = cairo_type1_font_subset_write_header (font, name);
1439
    if (unlikely (status))
1440
	return status;
1441
 
1442
    font->base.header_size = _cairo_output_stream_get_position (font->output);
1443
 
3959 Serge 1444
    /* Start outputting the private dict */
1445
    if (font->subset_subrs) {
1446
	/* First output everything up to the start of the Subrs array. */
1447
	status = cairo_type1_font_subset_write_encrypted (font, font->cleartext,
1448
							  array_start - font->cleartext);
1449
	if (unlikely (status))
1450
	    return status;
1897 serge 1451
 
3959 Serge 1452
	/* Write out the subr definitions for each of the glyphs in
1453
	 * the subset. */
1454
	status = cairo_type1_font_for_each_subr (font,
1455
						 array_start,
1456
						 font->cleartext_end,
1457
						 write_used_subrs,
1458
						 &p);
1459
	if (unlikely (status))
1460
	    return status;
1461
    } else {
1462
	p = font->cleartext;
1463
    }
1464
 
1465
    /* If subr subsetting, output everything from end of subrs to
1466
     * start of /CharStrings token.  If not subr subsetting, output
1467
     * everything start of private dict to start of /CharStrings
1468
     * token. */
1469
    status = cairo_type1_font_subset_write_encrypted (font, p, charstrings - p);
1897 serge 1470
    if (unlikely (status))
1471
	return status;
1472
 
1473
    /* Write out new charstring count */
1474
    length = snprintf (buffer, sizeof buffer,
1475
		       "/CharStrings %d", font->num_glyphs);
1476
    status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
1477
    if (unlikely (status))
1478
	return status;
1479
 
1480
    /* Write out text between the charstring count and the first
1481
     * charstring definition */
1482
    status = cairo_type1_font_subset_write_encrypted (font, glyph_count_end,
1483
	                                          dict_start - glyph_count_end);
1484
    if (unlikely (status))
1485
	return status;
1486
 
1487
    /* Write out the charstring definitions for each of the glyphs in
1488
     * the subset. */
1489
    status = cairo_type1_font_subset_for_each_glyph (font,
1490
						     dict_start,
1491
						     font->cleartext_end,
1492
						     write_used_glyphs,
1493
						     &p);
1494
    if (unlikely (status))
1495
	return status;
1496
 
1497
    /* Output what's left between the end of the glyph definitions and
1498
     * the end of the private dict to the output. */
1499
    status = cairo_type1_font_subset_write_encrypted (font, p,
1500
	                        closefile_token - p + strlen ("closefile") + 1);
1501
    if (unlikely (status))
1502
	return status;
1503
 
1504
    if (font->hex_encode)
1505
	_cairo_output_stream_write (font->output, "\n", 1);
1506
 
1507
    return CAIRO_STATUS_SUCCESS;
1508
}
1509
 
1510
static cairo_status_t
1511
cairo_type1_font_subset_write_trailer(cairo_type1_font_subset_t *font)
1512
{
1513
    const char *cleartomark_token;
1514
    int i;
1515
    static const char zeros[65] =
1516
	"0000000000000000000000000000000000000000000000000000000000000000\n";
1517
 
1518
 
1519
    for (i = 0; i < 8; i++)
1520
	_cairo_output_stream_write (font->output, zeros, sizeof zeros);
1521
 
1522
    cleartomark_token = find_token (font->type1_data, font->type1_end, "cleartomark");
1523
    if (cleartomark_token) {
1524
	/* Some fonts have conditional save/restore around the entire
1525
	 * font dict, so we need to retain whatever postscript code
1526
	 * that may come after 'cleartomark'. */
1527
 
1528
	_cairo_output_stream_write (font->output, cleartomark_token,
1529
				    font->type1_end - cleartomark_token);
3959 Serge 1530
	if (*(font->type1_end - 1) != '\n')
1531
	    _cairo_output_stream_printf (font->output, "\n");
1532
 
1897 serge 1533
    } else if (!font->eexec_segment_is_ascii) {
1534
	/* Fonts embedded in PDF may omit the fixed-content portion
1535
	 * that includes the 'cleartomark' operator. Type 1 in PDF is
1536
	 * always binary. */
1537
 
3959 Serge 1538
	_cairo_output_stream_printf (font->output, "cleartomark\n");
1897 serge 1539
    } else {
1540
	return CAIRO_INT_STATUS_UNSUPPORTED;
1541
    }
1542
 
1543
    /* some fonts do not have a newline at the end of the last line */
1544
    _cairo_output_stream_printf (font->output, "\n");
1545
 
1546
    return CAIRO_STATUS_SUCCESS;
1547
}
1548
 
1549
static cairo_status_t
1550
type1_font_write (void *closure, const unsigned char *data, unsigned int length)
1551
{
1552
    cairo_type1_font_subset_t *font = closure;
1553
 
1554
    return _cairo_array_append_multiple (&font->contents, data, length);
1555
}
1556
 
1557
static cairo_status_t
1558
cairo_type1_font_subset_write (cairo_type1_font_subset_t *font,
1559
			       const char *name)
1560
{
1561
    cairo_status_t status;
1562
 
1563
    status = cairo_type1_font_subset_find_segments (font);
1564
    if (unlikely (status))
1565
	return status;
1566
 
1567
    status = cairo_type1_font_subset_decrypt_eexec_segment (font);
1568
    if (unlikely (status))
1569
	return status;
1570
 
1571
    /* Determine which glyph definition delimiters to use. */
1572
    if (find_token (font->cleartext, font->cleartext_end, "/-|") != NULL) {
1573
	font->rd = "-|";
1574
	font->nd = "|-";
3959 Serge 1575
	font->np = "|";
1897 serge 1576
    } else if (find_token (font->cleartext, font->cleartext_end, "/RD") != NULL) {
1577
	font->rd = "RD";
1578
	font->nd = "ND";
3959 Serge 1579
	font->np = "NP";
1897 serge 1580
    } else {
1581
	/* Don't know *what* kind of font this is... */
1582
	return CAIRO_INT_STATUS_UNSUPPORTED;
1583
    }
1584
 
1585
    font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY;
1586
    font->hex_column = 0;
1587
 
3959 Serge 1588
    status = cairo_type1_font_subset_get_bbox (font);
1589
    if (unlikely (status))
1590
	return status;
1591
 
1592
    status = cairo_type1_font_subset_get_fontname (font);
1593
    if (unlikely (status))
1594
	return status;
1595
 
1897 serge 1596
    status = cairo_type1_font_subset_write_private_dict (font, name);
1597
    if (unlikely (status))
1598
	return status;
1599
 
1600
    font->base.data_size = _cairo_output_stream_get_position (font->output) -
1601
	font->base.header_size;
1602
 
1603
    status = cairo_type1_font_subset_write_trailer (font);
1604
    if (unlikely (status))
1605
	return status;
1606
 
1607
    font->base.trailer_size =
1608
	_cairo_output_stream_get_position (font->output) -
1609
	font->base.header_size - font->base.data_size;
1610
 
1611
    return CAIRO_STATUS_SUCCESS;
1612
}
1613
 
3959 Serge 1614
static cairo_bool_t
1615
check_fontdata_is_type1 (const unsigned char *data, long length)
1616
{
1617
    /* Test for  Type 1 Binary (PFB) */
1618
    if (length > 2 && data[0] == 0x80 && data[1] == 0x01)
1619
	return TRUE;
1620
 
1621
    /* Test for Type 1 1 ASCII (PFA) */
1622
    if (length > 2 && data[0] == '%' && data[1] == '!')
1623
	return TRUE;
1624
 
1625
    return FALSE;
1626
}
1627
 
1897 serge 1628
static cairo_status_t
1629
cairo_type1_font_subset_generate (void       *abstract_font,
1630
				  const char *name)
1631
 
1632
{
1633
    cairo_type1_font_subset_t *font = abstract_font;
3959 Serge 1634
    cairo_scaled_font_t *scaled_font;
1897 serge 1635
    cairo_status_t status;
3959 Serge 1636
    unsigned long data_length;
1897 serge 1637
 
3959 Serge 1638
    scaled_font = font->scaled_font_subset->scaled_font;
1639
    if (!scaled_font->backend->load_type1_data)
1640
	return CAIRO_INT_STATUS_UNSUPPORTED;
1897 serge 1641
 
3959 Serge 1642
    status = scaled_font->backend->load_type1_data (scaled_font, 0, NULL, &data_length);
1643
    if (status)
1644
	return CAIRO_INT_STATUS_UNSUPPORTED;
1645
 
1646
    font->type1_length = data_length;
1897 serge 1647
    font->type1_data = malloc (font->type1_length);
3959 Serge 1648
    if (unlikely (font->type1_data == NULL))
1649
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1897 serge 1650
 
3959 Serge 1651
    status = scaled_font->backend->load_type1_data (scaled_font, 0,
1652
						    (unsigned char *) font->type1_data,
1653
						    &data_length);
1654
    if (unlikely (status))
1655
        return status;
1897 serge 1656
 
3959 Serge 1657
    if (!check_fontdata_is_type1 ((unsigned char *)font->type1_data, data_length))
1658
	return CAIRO_INT_STATUS_UNSUPPORTED;
1659
 
1897 serge 1660
    status = _cairo_array_grow_by (&font->contents, 4096);
1661
    if (unlikely (status))
3959 Serge 1662
	return status;
1897 serge 1663
 
1664
    font->output = _cairo_output_stream_create (type1_font_write, NULL, font);
1665
    if (unlikely ((status = font->output->status)))
3959 Serge 1666
	return status;
1897 serge 1667
 
1668
    status = cairo_type1_font_subset_write (font, name);
1669
    if (unlikely (status))
3959 Serge 1670
	return status;
1897 serge 1671
 
1672
    font->base.data = _cairo_array_index (&font->contents, 0);
1673
 
1674
    return status;
1675
}
1676
 
1677
static cairo_status_t
1678
_cairo_type1_font_subset_fini (cairo_type1_font_subset_t *font)
1679
{
1680
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
1681
    unsigned int i;
1682
 
1683
    /* If the subset generation failed, some of the pointers below may
1684
     * be NULL depending on at which point the error occurred. */
1685
 
1686
    _cairo_array_fini (&font->contents);
1687
 
1688
    free (font->type1_data);
3959 Serge 1689
    for (i = 0; i < _cairo_array_num_elements (&font->glyph_names_array); i++) {
1690
	char **s;
1691
 
1692
	s = _cairo_array_index (&font->glyph_names_array, i);
1693
	free (*s);
1897 serge 1694
    }
3959 Serge 1695
    _cairo_array_fini (&font->glyph_names_array);
1696
    _cairo_array_fini (&font->glyphs_array);
1897 serge 1697
 
3959 Serge 1698
    free (font->subrs);
1897 serge 1699
 
1700
    if (font->output != NULL)
1701
	status = _cairo_output_stream_destroy (font->output);
1702
 
3959 Serge 1703
    free (font->base.base_font);
1897 serge 1704
 
3959 Serge 1705
    free (font->subset_index_to_glyphs);
1706
 
1707
    free (font->cleartext);
1708
 
1897 serge 1709
    return status;
1710
}
1711
 
1712
cairo_status_t
1713
_cairo_type1_subset_init (cairo_type1_subset_t		*type1_subset,
1714
			  const char			*name,
1715
			  cairo_scaled_font_subset_t	*scaled_font_subset,
1716
                          cairo_bool_t                   hex_encode)
1717
{
1718
    cairo_type1_font_subset_t font;
3959 Serge 1719
    cairo_status_t status;
1720
    unsigned long length;
1897 serge 1721
    unsigned int i;
1722
    char buf[30];
1723
 
3959 Serge 1724
    /* We need to use a fallback font generated from the synthesized outlines. */
1725
    if (scaled_font_subset->scaled_font->backend->is_synthetic &&
1726
	scaled_font_subset->scaled_font->backend->is_synthetic (scaled_font_subset->scaled_font))
1897 serge 1727
	return CAIRO_INT_STATUS_UNSUPPORTED;
1728
 
3959 Serge 1729
    status = _cairo_type1_font_subset_init (&font, scaled_font_subset, hex_encode);
1897 serge 1730
    if (unlikely (status))
1731
	return status;
1732
 
1733
    status = cairo_type1_font_subset_generate (&font, name);
1734
    if (unlikely (status))
1735
	goto fail1;
1736
 
1737
    if (font.base.base_font) {
1738
	type1_subset->base_font = strdup (font.base.base_font);
1739
    } else {
1740
        snprintf(buf, sizeof (buf), "CairoFont-%u-%u",
1741
                 scaled_font_subset->font_id, scaled_font_subset->subset_id);
1742
	type1_subset->base_font = strdup (buf);
1743
    }
1744
    if (unlikely (type1_subset->base_font == NULL))
1745
	goto fail1;
1746
 
1747
    type1_subset->widths = calloc (sizeof (double), font.num_glyphs);
1748
    if (unlikely (type1_subset->widths == NULL))
1749
	goto fail2;
1750
    for (i = 0; i < font.base.num_glyphs; i++) {
1751
	if (font.glyphs[i].subset_index < 0)
1752
	    continue;
1753
	type1_subset->widths[font.glyphs[i].subset_index] =
1754
	    font.glyphs[i].width;
1755
    }
1756
 
1757
    type1_subset->x_min = font.base.x_min;
1758
    type1_subset->y_min = font.base.y_min;
1759
    type1_subset->x_max = font.base.x_max;
1760
    type1_subset->y_max = font.base.y_max;
1761
    type1_subset->ascent = font.base.ascent;
1762
    type1_subset->descent = font.base.descent;
1763
 
1764
    length = font.base.header_size +
1765
	     font.base.data_size +
1766
	     font.base.trailer_size;
1767
    type1_subset->data = malloc (length);
1768
    if (unlikely (type1_subset->data == NULL))
1769
	goto fail3;
1770
 
1771
    memcpy (type1_subset->data,
1772
	    _cairo_array_index (&font.contents, 0), length);
1773
 
1774
    type1_subset->header_length = font.base.header_size;
1775
    type1_subset->data_length = font.base.data_size;
1776
    type1_subset->trailer_length = font.base.trailer_size;
1777
 
1778
    return _cairo_type1_font_subset_fini (&font);
1779
 
1780
 fail3:
1781
    free (type1_subset->widths);
1782
 fail2:
1783
    free (type1_subset->base_font);
1784
 fail1:
3959 Serge 1785
    _cairo_type1_font_subset_fini (&font);
1897 serge 1786
 
1787
    return status;
1788
}
1789
 
1790
void
1791
_cairo_type1_subset_fini (cairo_type1_subset_t *subset)
1792
{
1793
    free (subset->base_font);
1794
    free (subset->widths);
1795
    free (subset->data);
1796
}
1797
 
1798
cairo_bool_t
1799
_cairo_type1_scaled_font_is_type1 (cairo_scaled_font_t *scaled_font)
1800
{
3959 Serge 1801
    cairo_status_t status;
1802
    unsigned long length;
1803
    unsigned char buf[64];
1897 serge 1804
 
3959 Serge 1805
    if (!scaled_font->backend->load_type1_data)
1806
	return FALSE;
1897 serge 1807
 
3959 Serge 1808
    status = scaled_font->backend->load_type1_data (scaled_font, 0, NULL, &length);
1809
    if (status)
1810
	return FALSE;
1897 serge 1811
 
3959 Serge 1812
    /* We only need a few bytes to test for Type 1 */
1813
    if (length > sizeof (buf))
1814
	length = sizeof (buf);
1897 serge 1815
 
3959 Serge 1816
    status = scaled_font->backend->load_type1_data (scaled_font, 0, buf, &length);
1817
    if (status)
1818
	return FALSE;
1897 serge 1819
 
3959 Serge 1820
    return check_fontdata_is_type1 (buf, length);
1897 serge 1821
}
1822
 
1823
#endif /* CAIRO_HAS_FONT_SUBSET */