1
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2
/* cairo - a vector graphics library with display and print output
3
 *
4
 * Copyright © 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
 *	Adrian Johnson <ajohnson@redneon.com>
35
 */
36

            
37
#define _DEFAULT_SOURCE /* for snprintf(), strdup() */
38
#include "cairoint.h"
39

            
40
#include "cairo-array-private.h"
41
#include "cairo-error-private.h"
42

            
43
#if CAIRO_HAS_FONT_SUBSET
44

            
45
#include "cairo-type1-private.h"
46
#include "cairo-scaled-font-subsets-private.h"
47
#include "cairo-path-fixed-private.h"
48
#include "cairo-output-stream-private.h"
49

            
50
typedef enum {
51
    CAIRO_CHARSTRING_TYPE1,
52
    CAIRO_CHARSTRING_TYPE2
53
} cairo_charstring_type_t;
54

            
55
typedef struct _cairo_type1_font {
56
    int *widths;
57

            
58
    cairo_scaled_font_subset_t *scaled_font_subset;
59
    cairo_scaled_font_t        *type1_scaled_font;
60

            
61
    cairo_array_t contents;
62

            
63
    double x_min, y_min, x_max, y_max;
64

            
65
    const char    *data;
66
    unsigned long  header_size;
67
    unsigned long  data_size;
68
    unsigned long  trailer_size;
69
    int            bbox_position;
70
    int            bbox_max_chars;
71

            
72
    cairo_output_stream_t *output;
73

            
74
    unsigned short eexec_key;
75
    cairo_bool_t hex_encode;
76
    int hex_column;
77
} cairo_type1_font_t;
78

            
79
static cairo_status_t
80
cairo_type1_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
81
                         cairo_type1_font_t         **subset_return,
82
                         cairo_bool_t                 hex_encode)
83
{
84
    cairo_type1_font_t *font;
85
    cairo_font_face_t *font_face;
86
    cairo_matrix_t font_matrix;
87
    cairo_matrix_t ctm;
88
    cairo_font_options_t font_options;
89
    cairo_status_t status;
90

            
91
    font = _cairo_calloc (sizeof (cairo_type1_font_t));
92
    if (unlikely (font == NULL))
93
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
94

            
95
    font->widths = _cairo_calloc_ab (scaled_font_subset->num_glyphs, sizeof (int));
96
    if (unlikely (font->widths == NULL)) {
97
	free (font);
98
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
99
    }
100

            
101
    font->scaled_font_subset = scaled_font_subset;
102
    font->hex_encode = hex_encode;
103

            
104
    font_face = cairo_scaled_font_get_font_face (scaled_font_subset->scaled_font);
105

            
106
    cairo_matrix_init_scale (&font_matrix, 1000, -1000);
107
    cairo_matrix_init_identity (&ctm);
108

            
109
    _cairo_font_options_init_default (&font_options);
110
    cairo_scaled_font_get_font_options (scaled_font_subset->scaled_font, &font_options);
111
    cairo_font_options_set_hint_style (&font_options, CAIRO_HINT_STYLE_NONE);
112
    cairo_font_options_set_hint_metrics (&font_options, CAIRO_HINT_METRICS_OFF);
113

            
114
    font->type1_scaled_font = cairo_scaled_font_create (font_face,
115
							&font_matrix,
116
							&ctm,
117
							&font_options);
118
    status = font->type1_scaled_font->status;
119
    if (unlikely (status))
120
        goto fail;
121

            
122
    _cairo_array_init (&font->contents, sizeof (unsigned char));
123
    font->output = NULL;
124

            
125
    *subset_return = font;
126

            
127
    return CAIRO_STATUS_SUCCESS;
128

            
129
fail:
130
    free (font->widths);
131
    free (font);
132

            
133
    return status;
134
}
135

            
136
/* Charstring commands. If the high byte is 0 the command is encoded
137
 * with a single byte. */
138
#define CHARSTRING_sbw        0x0c07
139
#define CHARSTRING_rmoveto    0x0015
140
#define CHARSTRING_rlineto    0x0005
141
#define CHARSTRING_rcurveto   0x0008
142
#define CHARSTRING_closepath  0x0009
143
#define CHARSTRING_endchar    0x000e
144

            
145
/* Before calling this function, the caller must allocate sufficient
146
 * space in data (see _cairo_array_grow_by). The maximum number of
147
 * bytes that will be used is 2.
148
 */
149
static void
150
charstring_encode_command (cairo_array_t *data, int command)
151
{
152
    cairo_status_t status;
153
    unsigned int orig_size;
154
    unsigned char buf[5];
155
    unsigned char *p = buf;
156

            
157
    if (command & 0xff00)
158
        *p++ = command >> 8;
159
    *p++ = command & 0x00ff;
160

            
161
    /* Ensure the array doesn't grow, which allows this function to
162
     * have no possibility of failure. */
163
    orig_size = _cairo_array_size (data);
164
    status = _cairo_array_append_multiple (data, buf, p - buf);
165

            
166
    assert (status == CAIRO_STATUS_SUCCESS);
167
    assert (_cairo_array_size (data) == orig_size);
168
}
169

            
170
/* Before calling this function, the caller must allocate sufficient
171
 * space in data (see _cairo_array_grow_by). The maximum number of
172
 * bytes that will be used is 5.
173
 */
174
static void
175
charstring_encode_integer (cairo_array_t *data,
176
                           int i,
177
                           cairo_charstring_type_t type)
178
{
179
    cairo_status_t status;
180
    unsigned int orig_size;
181
    unsigned char buf[10];
182
    unsigned char *p = buf;
183

            
184
    if (i >= -107 && i <= 107) {
185
        *p++ = i + 139;
186
    } else if (i >= 108 && i <= 1131) {
187
        i -= 108;
188
        *p++ = (i >> 8)+ 247;
189
        *p++ = i & 0xff;
190
    } else if (i >= -1131 && i <= -108) {
191
        i = -i - 108;
192
        *p++ = (i >> 8)+ 251;
193
        *p++ = i & 0xff;
194
    } else {
195
        if (type == CAIRO_CHARSTRING_TYPE1) {
196
            *p++ = 0xff;
197
            *p++ = i >> 24;
198
            *p++ = (i >> 16) & 0xff;
199
            *p++ = (i >> 8)  & 0xff;
200
            *p++ = i & 0xff;
201
        } else {
202
            *p++ = 0xff;
203
            *p++ = (i >> 8)  & 0xff;
204
            *p++ = i & 0xff;
205
            *p++ = 0;
206
            *p++ = 0;
207
        }
208
    }
209

            
210
    /* Ensure the array doesn't grow, which allows this function to
211
     * have no possibility of failure. */
212
    orig_size = _cairo_array_size (data);
213
    status = _cairo_array_append_multiple (data, buf, p - buf);
214

            
215
    assert (status == CAIRO_STATUS_SUCCESS);
216
    assert (_cairo_array_size (data) == orig_size);
217
}
218

            
219
typedef struct _ps_path_info {
220
    cairo_array_t *data;
221
    int current_x, current_y;
222
    cairo_charstring_type_t type;
223
} t1_path_info_t;
224

            
225
static cairo_status_t
226
_charstring_move_to (void		    *closure,
227
                     const cairo_point_t    *point)
228
{
229
    t1_path_info_t *path_info = (t1_path_info_t *) closure;
230
    int dx, dy;
231
    cairo_status_t status;
232

            
233
    status = _cairo_array_grow_by (path_info->data, 12);
234
    if (unlikely (status))
235
        return status;
236

            
237
    dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
238
    dy = _cairo_fixed_integer_part (point->y) - path_info->current_y;
239
    charstring_encode_integer (path_info->data, dx, path_info->type);
240
    charstring_encode_integer (path_info->data, dy, path_info->type);
241
    path_info->current_x += dx;
242
    path_info->current_y += dy;
243

            
244
    charstring_encode_command (path_info->data, CHARSTRING_rmoveto);
245

            
246
    return CAIRO_STATUS_SUCCESS;
247
}
248

            
249
static cairo_status_t
250
_charstring_line_to (void		    *closure,
251
                     const cairo_point_t    *point)
252
{
253
    t1_path_info_t *path_info = (t1_path_info_t *) closure;
254
    int dx, dy;
255
    cairo_status_t status;
256

            
257
    status = _cairo_array_grow_by (path_info->data, 12);
258
    if (unlikely (status))
259
        return status;
260

            
261
    dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
262
    dy = _cairo_fixed_integer_part (point->y) - path_info->current_y;
263
    charstring_encode_integer (path_info->data, dx, path_info->type);
264
    charstring_encode_integer (path_info->data, dy, path_info->type);
265
    path_info->current_x += dx;
266
    path_info->current_y += dy;
267

            
268
    charstring_encode_command (path_info->data, CHARSTRING_rlineto);
269

            
270
    return CAIRO_STATUS_SUCCESS;
271
}
272

            
273
static cairo_status_t
274
_charstring_curve_to (void		    *closure,
275
                      const cairo_point_t   *point1,
276
                      const cairo_point_t   *point2,
277
                      const cairo_point_t   *point3)
278
{
279
    t1_path_info_t *path_info = (t1_path_info_t *) closure;
280
    int dx1, dy1, dx2, dy2, dx3, dy3;
281
    cairo_status_t status;
282

            
283
    status = _cairo_array_grow_by (path_info->data, 32);
284
    if (unlikely (status))
285
        return status;
286

            
287
    dx1 = _cairo_fixed_integer_part (point1->x) - path_info->current_x;
288
    dy1 = _cairo_fixed_integer_part (point1->y) - path_info->current_y;
289
    dx2 = _cairo_fixed_integer_part (point2->x) - path_info->current_x - dx1;
290
    dy2 = _cairo_fixed_integer_part (point2->y) - path_info->current_y - dy1;
291
    dx3 = _cairo_fixed_integer_part (point3->x) - path_info->current_x - dx1 - dx2;
292
    dy3 = _cairo_fixed_integer_part (point3->y) - path_info->current_y - dy1 - dy2;
293
    charstring_encode_integer (path_info->data, dx1, path_info->type);
294
    charstring_encode_integer (path_info->data, dy1, path_info->type);
295
    charstring_encode_integer (path_info->data, dx2, path_info->type);
296
    charstring_encode_integer (path_info->data, dy2, path_info->type);
297
    charstring_encode_integer (path_info->data, dx3, path_info->type);
298
    charstring_encode_integer (path_info->data, dy3, path_info->type);
299
    path_info->current_x += dx1 + dx2 + dx3;
300
    path_info->current_y += dy1 + dy2 + dy3;
301
    charstring_encode_command (path_info->data, CHARSTRING_rcurveto);
302

            
303
    return CAIRO_STATUS_SUCCESS;
304
}
305

            
306
static cairo_status_t
307
_charstring_close_path (void *closure)
308
{
309
    cairo_status_t status;
310
    t1_path_info_t *path_info = (t1_path_info_t *) closure;
311

            
312
    if (path_info->type == CAIRO_CHARSTRING_TYPE2)
313
        return CAIRO_STATUS_SUCCESS;
314

            
315
    status = _cairo_array_grow_by (path_info->data, 2);
316
    if (unlikely (status))
317
	return status;
318

            
319
    charstring_encode_command (path_info->data, CHARSTRING_closepath);
320

            
321
    return CAIRO_STATUS_SUCCESS;
322
}
323

            
324
static void
325
charstring_encrypt (cairo_array_t *data)
326
{
327
    unsigned char *d, *end;
328
    uint16_t c, p, r;
329

            
330
    r = CAIRO_TYPE1_CHARSTRING_KEY;
331
    d = (unsigned char *) _cairo_array_index (data, 0);
332
    end = d + _cairo_array_num_elements (data);
333
    while (d < end) {
334
	p = *d;
335
	c = p ^ (r >> 8);
336
	r = (c + r) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
337
        *d++ = c;
338
    }
339
}
340

            
341
static cairo_int_status_t
342
cairo_type1_font_create_charstring (cairo_type1_font_t      *font,
343
                                    int                      subset_index,
344
                                    int                      glyph_index,
345
                                    cairo_charstring_type_t  type,
346
                                    cairo_array_t           *data)
347
{
348
    cairo_int_status_t status;
349
    cairo_scaled_glyph_t *scaled_glyph;
350
    t1_path_info_t path_info;
351
    cairo_text_extents_t *metrics;
352
    cairo_bool_t emit_path = TRUE;
353

            
354
    /* This call may return CAIRO_INT_STATUS_UNSUPPORTED for bitmap fonts. */
355
    status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
356
					 glyph_index,
357
					 CAIRO_SCALED_GLYPH_INFO_METRICS|
358
					 CAIRO_SCALED_GLYPH_INFO_PATH,
359
					 NULL, /* foreground color */
360
					 &scaled_glyph);
361

            
362
    /* It is ok for the .notdef glyph to not have a path available. We
363
     * just need the metrics to emit an empty glyph.  */
364
    if (glyph_index == 0 && status == CAIRO_INT_STATUS_UNSUPPORTED) {
365
	emit_path = FALSE;
366
	status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
367
					     glyph_index,
368
					     CAIRO_SCALED_GLYPH_INFO_METRICS,
369
                                             NULL, /* foreground color */
370
					     &scaled_glyph);
371
    }
372
    if (unlikely (status))
373
        return status;
374

            
375
    metrics = &scaled_glyph->metrics;
376
    if (subset_index == 0) {
377
        font->x_min = metrics->x_bearing;
378
        font->y_min = metrics->y_bearing;
379
        font->x_max = metrics->x_bearing + metrics->width;
380
        font->y_max = metrics->y_bearing + metrics->height;
381
    } else {
382
        if (metrics->x_bearing < font->x_min)
383
            font->x_min = metrics->x_bearing;
384
        if (metrics->y_bearing < font->y_min)
385
            font->y_min = metrics->y_bearing;
386
        if (metrics->x_bearing + metrics->width > font->x_max)
387
            font->x_max = metrics->x_bearing + metrics->width;
388
        if (metrics->y_bearing + metrics->height > font->y_max)
389
            font->y_max = metrics->y_bearing + metrics->height;
390
    }
391
    font->widths[subset_index] = metrics->x_advance;
392

            
393
    status = _cairo_array_grow_by (data, 30);
394
    if (unlikely (status))
395
        return status;
396

            
397
    if (type == CAIRO_CHARSTRING_TYPE1) {
398
        charstring_encode_integer (data, (int) scaled_glyph->metrics.x_bearing, type);
399
        charstring_encode_integer (data, (int) scaled_glyph->metrics.y_bearing, type);
400
        charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type);
401
        charstring_encode_integer (data, (int) scaled_glyph->metrics.y_advance, type);
402
        charstring_encode_command (data, CHARSTRING_sbw);
403

            
404
        path_info.current_x = (int) scaled_glyph->metrics.x_bearing;
405
        path_info.current_y = (int) scaled_glyph->metrics.y_bearing;
406
    } else {
407
        charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type);
408

            
409
        path_info.current_x = 0;
410
        path_info.current_y = 0;
411
    }
412
    path_info.data = data;
413
    path_info.type = type;
414
    if (emit_path) {
415
	status = _cairo_path_fixed_interpret (scaled_glyph->path,
416
					      _charstring_move_to,
417
					      _charstring_line_to,
418
					      _charstring_curve_to,
419
					      _charstring_close_path,
420
					      &path_info);
421
	if (unlikely (status))
422
	    return status;
423
    }
424

            
425
    status = _cairo_array_grow_by (data, 1);
426
    if (unlikely (status))
427
        return status;
428
    charstring_encode_command (path_info.data, CHARSTRING_endchar);
429

            
430
    return CAIRO_STATUS_SUCCESS;
431
}
432

            
433
static cairo_int_status_t
434
cairo_type1_font_write_charstrings (cairo_type1_font_t    *font,
435
                                    cairo_output_stream_t *encrypted_output)
436
{
437
    cairo_status_t status;
438
    unsigned char zeros[] = { 0, 0, 0, 0 };
439
    cairo_array_t data;
440
    unsigned int i;
441
    int length;
442

            
443
    _cairo_array_init (&data, sizeof (unsigned char));
444
    status = _cairo_array_grow_by (&data, 1024);
445
    if (unlikely (status))
446
        goto fail;
447

            
448
    _cairo_output_stream_printf (encrypted_output,
449
                                 "2 index /CharStrings %d dict dup begin\n",
450
                                 font->scaled_font_subset->num_glyphs + 1);
451

            
452
    _cairo_scaled_font_freeze_cache (font->type1_scaled_font);
453
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
454
        _cairo_array_truncate (&data, 0);
455
        /* four "random" bytes required by encryption algorithm */
456
        status = _cairo_array_append_multiple (&data, zeros, 4);
457
        if (unlikely (status))
458
	    break;
459

            
460
        status = cairo_type1_font_create_charstring (font, i,
461
						     font->scaled_font_subset->glyphs[i],
462
                                                     CAIRO_CHARSTRING_TYPE1,
463
						     &data);
464
        if (unlikely (status))
465
	    break;
466

            
467
        charstring_encrypt (&data);
468
        length = _cairo_array_num_elements (&data);
469
	if (font->scaled_font_subset->glyph_names != NULL) {
470
	    _cairo_output_stream_printf (encrypted_output, "/%s %d RD ",
471
					 font->scaled_font_subset->glyph_names[i],
472
					 length);
473
	} else if (i == 0) {
474
	    _cairo_output_stream_printf (encrypted_output, "/.notdef %d RD ", length);
475
	} else {
476
	    _cairo_output_stream_printf (encrypted_output, "/g%d %d RD ", i, length);
477
	}
478
        _cairo_output_stream_write (encrypted_output,
479
                                    _cairo_array_index (&data, 0),
480
                                    length);
481
        _cairo_output_stream_printf (encrypted_output, " ND\n");
482
    }
483
    _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
484

            
485
fail:
486
    _cairo_array_fini (&data);
487
    return status;
488
}
489

            
490
static void
491
cairo_type1_font_write_header (cairo_type1_font_t *font,
492
                               const char         *name)
493
{
494
    unsigned int i;
495
    const char spaces[50] = "                                                  ";
496

            
497
    _cairo_output_stream_printf (font->output,
498
                                 "%%!FontType1-1.1 %s 1.0\n"
499
                                 "11 dict begin\n"
500
                                 "/FontName /%s def\n"
501
                                 "/PaintType 0 def\n"
502
                                 "/FontType 1 def\n"
503
                                  "/FontMatrix [0.001 0 0 0.001 0 0] readonly def\n",
504
                                 name,
505
                                 name);
506

            
507
    /* We don't know the bbox values until after the charstrings have
508
     * been generated.  Reserve some space and fill in the bbox
509
     * later. */
510

            
511
    /* Worst case for four signed ints with spaces between each number */
512
    font->bbox_max_chars = 50;
513

            
514
    _cairo_output_stream_printf (font->output, "/FontBBox {");
515
    font->bbox_position = _cairo_output_stream_get_position (font->output);
516
    _cairo_output_stream_write (font->output, spaces, font->bbox_max_chars);
517

            
518
    _cairo_output_stream_printf (font->output,
519
                                 "} readonly def\n"
520
                                 "/Encoding 256 array\n"
521
				 "0 1 255 {1 index exch /.notdef put} for\n");
522
    if (font->scaled_font_subset->is_latin) {
523
	for (i = 1; i < 256; i++) {
524
	    int subset_glyph = font->scaled_font_subset->latin_to_subset_glyph_index[i];
525

            
526
	    if (subset_glyph > 0) {
527
		if (font->scaled_font_subset->glyph_names != NULL) {
528
		    _cairo_output_stream_printf (font->output, "dup %d /%s put\n",
529
						 i, font->scaled_font_subset->glyph_names[subset_glyph]);
530
		} else {
531
		    _cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, subset_glyph);
532
		}
533
	    }
534
	}
535
    } else {
536
	for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
537
	    if (font->scaled_font_subset->glyph_names != NULL) {
538
		_cairo_output_stream_printf (font->output, "dup %d /%s put\n",
539
					     i, font->scaled_font_subset->glyph_names[i]);
540
	    } else {
541
		_cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, i);
542
	    }
543
	}
544
    }
545
    _cairo_output_stream_printf (font->output,
546
                                 "readonly def\n"
547
                                 "currentdict end\n"
548
                                 "currentfile eexec\n");
549
}
550

            
551
static cairo_status_t
552
cairo_type1_write_stream_encrypted (void                *closure,
553
                                    const unsigned char *data,
554
                                    unsigned int         length)
555
{
556
    const unsigned char *in, *end;
557
    uint16_t c, p;
558
    static const char hex_digits[16] = "0123456789abcdef";
559
    char digits[3];
560
    cairo_type1_font_t *font = closure;
561

            
562
    in = (const unsigned char *) data;
563
    end = (const unsigned char *) data + length;
564
    while (in < end) {
565
	p = *in++;
566
	c = p ^ (font->eexec_key >> 8);
567
	font->eexec_key = (c + font->eexec_key) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
568

            
569
	if (font->hex_encode) {
570
	    digits[0] = hex_digits[c >> 4];
571
	    digits[1] = hex_digits[c & 0x0f];
572
	    digits[2] = '\n';
573
	    font->hex_column += 2;
574

            
575
	    if (font->hex_column == 78) {
576
		_cairo_output_stream_write (font->output, digits, 3);
577
		font->hex_column = 0;
578
	    } else {
579
		_cairo_output_stream_write (font->output, digits, 2);
580
	    }
581
	} else {
582
	    digits[0] = c;
583
	    _cairo_output_stream_write (font->output, digits, 1);
584
	}
585
    }
586

            
587
    return CAIRO_STATUS_SUCCESS;
588
}
589

            
590
static cairo_int_status_t
591
cairo_type1_font_write_private_dict (cairo_type1_font_t *font,
592
                                     const char         *name)
593
{
594
    cairo_int_status_t status;
595
    cairo_status_t status2;
596
    cairo_output_stream_t *encrypted_output;
597

            
598
    font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY;
599
    font->hex_column = 0;
600
    encrypted_output = _cairo_output_stream_create (
601
        cairo_type1_write_stream_encrypted,
602
        NULL,
603
        font);
604
    if (_cairo_output_stream_get_status (encrypted_output))
605
	return  _cairo_output_stream_destroy (encrypted_output);
606

            
607
    /* Note: the first four spaces at the start of this private dict
608
     * are the four "random" bytes of plaintext required by the
609
     * encryption algorithm */
610
    _cairo_output_stream_printf (encrypted_output,
611
                                 "    dup /Private 9 dict dup begin\n"
612
                                 "/RD {string currentfile exch readstring pop}"
613
                                 " bind executeonly def\n"
614
                                 "/ND {noaccess def} executeonly def\n"
615
                                 "/NP {noaccess put} executeonly def\n"
616
                                 "/BlueValues [] def\n"
617
                                 "/MinFeature {16 16} def\n"
618
                                 "/lenIV 4 def\n"
619
                                 "/password 5839 def\n");
620

            
621
    status = cairo_type1_font_write_charstrings (font, encrypted_output);
622
    if (unlikely (status))
623
	goto fail;
624

            
625
    _cairo_output_stream_printf (encrypted_output,
626
                                 "end\n"
627
                                 "end\n"
628
                                 "readonly put\n"
629
                                 "noaccess put\n"
630
                                 "dup /FontName get exch definefont pop\n"
631
                                 "mark currentfile closefile\n");
632

            
633
  fail:
634
    status2 = _cairo_output_stream_destroy (encrypted_output);
635
    if (status == CAIRO_INT_STATUS_SUCCESS)
636
	status = status2;
637

            
638
    return status;
639
}
640

            
641
static void
642
cairo_type1_font_write_trailer(cairo_type1_font_t *font)
643
{
644
    int i;
645
    static const char zeros[65] =
646
	"0000000000000000000000000000000000000000000000000000000000000000\n";
647

            
648
    for (i = 0; i < 8; i++)
649
	_cairo_output_stream_write (font->output, zeros, sizeof zeros);
650

            
651
    _cairo_output_stream_printf (font->output, "cleartomark\n");
652
}
653

            
654
static cairo_status_t
655
cairo_type1_write_stream (void *closure,
656
                         const unsigned char *data,
657
                         unsigned int length)
658
{
659
    cairo_type1_font_t *font = closure;
660

            
661
    return _cairo_array_append_multiple (&font->contents, data, length);
662
}
663

            
664
static cairo_int_status_t
665
cairo_type1_font_write (cairo_type1_font_t *font,
666
                        const char *name)
667
{
668
    cairo_int_status_t status;
669

            
670
    cairo_type1_font_write_header (font, name);
671
    font->header_size = _cairo_output_stream_get_position (font->output);
672

            
673
    status = cairo_type1_font_write_private_dict (font, name);
674
    if (unlikely (status))
675
	return status;
676

            
677
    font->data_size = _cairo_output_stream_get_position (font->output) -
678
	font->header_size;
679

            
680
    cairo_type1_font_write_trailer (font);
681
    font->trailer_size =
682
	_cairo_output_stream_get_position (font->output) -
683
	font->header_size - font->data_size;
684

            
685
    return CAIRO_STATUS_SUCCESS;
686
}
687

            
688
static cairo_int_status_t
689
cairo_type1_font_generate (cairo_type1_font_t *font, const char *name)
690
{
691
    cairo_int_status_t status;
692

            
693
    status = _cairo_array_grow_by (&font->contents, 4096);
694
    if (unlikely (status))
695
	return status;
696

            
697
    font->output = _cairo_output_stream_create (cairo_type1_write_stream, NULL, font);
698
    if (_cairo_output_stream_get_status (font->output))
699
	return _cairo_output_stream_destroy (font->output);
700

            
701
    status = cairo_type1_font_write (font, name);
702
    if (unlikely (status))
703
	return status;
704

            
705
    font->data = _cairo_array_index (&font->contents, 0);
706

            
707
    return CAIRO_STATUS_SUCCESS;
708
}
709

            
710
static cairo_status_t
711
cairo_type1_font_destroy (cairo_type1_font_t *font)
712
{
713
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
714

            
715
    free (font->widths);
716
    cairo_scaled_font_destroy (font->type1_scaled_font);
717
    _cairo_array_fini (&font->contents);
718
    if (font->output)
719
	status = _cairo_output_stream_destroy (font->output);
720
    free (font);
721

            
722
    return status;
723
}
724

            
725
static cairo_status_t
726
_cairo_type1_fallback_init_internal (cairo_type1_subset_t	*type1_subset,
727
                                     const char			*name,
728
                                     cairo_scaled_font_subset_t	*scaled_font_subset,
729
                                     cairo_bool_t                hex_encode)
730
{
731
    cairo_type1_font_t *font;
732
    cairo_status_t status;
733
    unsigned long length;
734
    unsigned int i, len;
735

            
736
    status = cairo_type1_font_create (scaled_font_subset, &font, hex_encode);
737
    if (unlikely (status))
738
	return status;
739

            
740
    status = cairo_type1_font_generate (font, name);
741
    if (unlikely (status))
742
	goto fail1;
743

            
744
    type1_subset->base_font = strdup (name);
745
    if (unlikely (type1_subset->base_font == NULL)) {
746
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
747
        goto fail1;
748
    }
749

            
750
    type1_subset->widths = _cairo_calloc_ab (font->scaled_font_subset->num_glyphs,
751
					     sizeof (double));
752
    if (unlikely (type1_subset->widths == NULL)) {
753
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
754
        goto fail2;
755
    }
756
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
757
	type1_subset->widths[i] = (double)font->widths[i]/1000;
758

            
759
    type1_subset->x_min   = (double)font->x_min/1000;
760
    type1_subset->y_min   = (double)font->y_min/1000;
761
    type1_subset->x_max   = (double)font->x_max/1000;
762
    type1_subset->y_max   = (double)font->y_max/1000;
763
    type1_subset->ascent  = (double)font->y_max/1000;
764
    type1_subset->descent = (double)font->y_min/1000;
765

            
766
    length = font->header_size + font->data_size +
767
	font->trailer_size;
768
    type1_subset->data = _cairo_malloc (length);
769
    if (unlikely (type1_subset->data == NULL)) {
770
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
771
	goto fail3;
772
    }
773
    memcpy (type1_subset->data,
774
	    _cairo_array_index (&font->contents, 0), length);
775

            
776
    len = snprintf(type1_subset->data + font->bbox_position,
777
                   font->bbox_max_chars,
778
                   "%d %d %d %d",
779
                   (int)font->x_min,
780
                   (int)font->y_min,
781
                   (int)font->x_max,
782
                   (int)font->y_max);
783
    type1_subset->data[font->bbox_position + len] = ' ';
784

            
785
    type1_subset->header_length = font->header_size;
786
    type1_subset->data_length = font->data_size;
787
    type1_subset->trailer_length = font->trailer_size;
788

            
789
    return cairo_type1_font_destroy (font);
790

            
791
 fail3:
792
    free (type1_subset->widths);
793
 fail2:
794
    free (type1_subset->base_font);
795
 fail1:
796
    /* status is already set, ignore further errors */
797
    cairo_type1_font_destroy (font);
798

            
799
    return status;
800
}
801

            
802
cairo_status_t
803
_cairo_type1_fallback_init_binary (cairo_type1_subset_t	      *type1_subset,
804
                                   const char		      *name,
805
                                   cairo_scaled_font_subset_t *scaled_font_subset)
806
{
807
    return _cairo_type1_fallback_init_internal (type1_subset,
808
                                                name,
809
                                                scaled_font_subset, FALSE);
810
}
811

            
812
cairo_status_t
813
_cairo_type1_fallback_init_hex (cairo_type1_subset_t	   *type1_subset,
814
                                const char		   *name,
815
                                cairo_scaled_font_subset_t *scaled_font_subset)
816
{
817
    return _cairo_type1_fallback_init_internal (type1_subset,
818
                                                name,
819
                                                scaled_font_subset, TRUE);
820
}
821

            
822
void
823
_cairo_type1_fallback_fini (cairo_type1_subset_t *subset)
824
{
825
    free (subset->base_font);
826
    free (subset->widths);
827
    free (subset->data);
828
}
829

            
830
cairo_status_t
831
_cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset,
832
                               cairo_scaled_font_subset_t *scaled_font_subset)
833
{
834
    cairo_type1_font_t *font;
835
    cairo_status_t status;
836
    unsigned int i;
837
    cairo_array_t charstring;
838

            
839
    status = cairo_type1_font_create (scaled_font_subset, &font, FALSE);
840
    if (unlikely (status))
841
	return status;
842

            
843
    _cairo_array_init (&type2_subset->charstrings, sizeof (cairo_array_t));
844

            
845
    type2_subset->widths = _cairo_calloc_ab (font->scaled_font_subset->num_glyphs, sizeof (int));
846
    if (unlikely (type2_subset->widths == NULL)) {
847
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
848
        goto fail1;
849
    }
850

            
851
    _cairo_scaled_font_freeze_cache (font->type1_scaled_font);
852
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
853
        _cairo_array_init (&charstring, sizeof (unsigned char));
854
        status = _cairo_array_grow_by (&charstring, 32);
855
        if (unlikely (status))
856
            goto fail2;
857

            
858
	status = cairo_type1_font_create_charstring (font, i,
859
						     font->scaled_font_subset->glyphs[i],
860
						     CAIRO_CHARSTRING_TYPE2,
861
						     &charstring);
862
        if (unlikely (status))
863
            goto fail2;
864

            
865
        status = _cairo_array_append (&type2_subset->charstrings, &charstring);
866
        if (unlikely (status))
867
            goto fail2;
868
    }
869
    _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
870

            
871
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
872
	type2_subset->widths[i] = font->widths[i];
873

            
874
    type2_subset->x_min   = (int) font->x_min;
875
    type2_subset->y_min   = (int) font->y_min;
876
    type2_subset->x_max   = (int) font->x_max;
877
    type2_subset->y_max   = (int) font->y_max;
878
    type2_subset->ascent  = (int) font->y_max;
879
    type2_subset->descent = (int) font->y_min;
880

            
881
    return cairo_type1_font_destroy (font);
882

            
883
fail2:
884
    _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
885
    _cairo_array_fini (&charstring);
886
    _cairo_type2_charstrings_fini (type2_subset);
887
fail1:
888
    cairo_type1_font_destroy (font);
889
    return status;
890
}
891

            
892
void
893
_cairo_type2_charstrings_fini (cairo_type2_charstrings_t *type2_subset)
894
{
895
    unsigned int i, num_charstrings;
896
    cairo_array_t *charstring;
897

            
898
    num_charstrings = _cairo_array_num_elements (&type2_subset->charstrings);
899
    for (i = 0; i < num_charstrings; i++) {
900
        charstring = _cairo_array_index (&type2_subset->charstrings, i);
901
        _cairo_array_fini (charstring);
902
    }
903
    _cairo_array_fini (&type2_subset->charstrings);
904

            
905
    free (type2_subset->widths);
906
}
907

            
908
#endif /* CAIRO_HAS_FONT_SUBSET */