tizen 2.3.1 release
[framework/graphics/cairo.git] / src / cairo-type1-fallback.c
1 /* cairo - a vector graphics library with display and print output
2  *
3  * Copyright © 2006 Red Hat, Inc
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it either under the terms of the GNU Lesser General Public
7  * License version 2.1 as published by the Free Software Foundation
8  * (the "LGPL") or, at your option, under the terms of the Mozilla
9  * Public License Version 1.1 (the "MPL"). If you do not alter this
10  * notice, a recipient may use your version of this file under either
11  * the MPL or the LGPL.
12  *
13  * You should have received a copy of the LGPL along with this library
14  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16  * You should have received a copy of the MPL along with this library
17  * in the file COPYING-MPL-1.1
18  *
19  * The contents of this file are subject to the Mozilla Public License
20  * Version 1.1 (the "License"); you may not use this file except in
21  * compliance with the License. You may obtain a copy of the License at
22  * http://www.mozilla.org/MPL/
23  *
24  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26  * the specific language governing rights and limitations.
27  *
28  * The Original Code is the cairo graphics library.
29  *
30  * The Initial Developer of the Original Code is Red Hat, Inc.
31  *
32  * Contributor(s):
33  *      Adrian Johnson <ajohnson@redneon.com>
34  */
35
36 #define _BSD_SOURCE /* for snprintf(), strdup() */
37 #include "cairoint.h"
38
39 #include "cairo-array-private.h"
40 #include "cairo-error-private.h"
41
42 #if CAIRO_HAS_FONT_SUBSET
43
44 #include "cairo-type1-private.h"
45 #include "cairo-scaled-font-subsets-private.h"
46 #include "cairo-path-fixed-private.h"
47 #include "cairo-output-stream-private.h"
48
49 typedef enum {
50     CAIRO_CHARSTRING_TYPE1,
51     CAIRO_CHARSTRING_TYPE2
52 } cairo_charstring_type_t;
53
54 typedef struct _cairo_type1_font {
55     int *widths;
56
57     cairo_scaled_font_subset_t *scaled_font_subset;
58     cairo_scaled_font_t        *type1_scaled_font;
59
60     cairo_array_t contents;
61
62     double x_min, y_min, x_max, y_max;
63
64     const char    *data;
65     unsigned long  header_size;
66     unsigned long  data_size;
67     unsigned long  trailer_size;
68     int            bbox_position;
69     int            bbox_max_chars;
70
71     cairo_output_stream_t *output;
72
73     unsigned short eexec_key;
74     cairo_bool_t hex_encode;
75     int hex_column;
76 } cairo_type1_font_t;
77
78 static cairo_status_t
79 cairo_type1_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
80                          cairo_type1_font_t         **subset_return,
81                          cairo_bool_t                 hex_encode)
82 {
83     cairo_type1_font_t *font;
84     cairo_font_face_t *font_face;
85     cairo_matrix_t font_matrix;
86     cairo_matrix_t ctm;
87     cairo_font_options_t font_options;
88     cairo_status_t status;
89
90     font = calloc (1, sizeof (cairo_type1_font_t));
91     if (unlikely (font == NULL))
92         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
93
94     font->widths = calloc (scaled_font_subset->num_glyphs, sizeof (int));
95     if (unlikely (font->widths == NULL)) {
96         free (font);
97         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
98     }
99
100     font->scaled_font_subset = scaled_font_subset;
101     font->hex_encode = hex_encode;
102
103     font_face = cairo_scaled_font_get_font_face (scaled_font_subset->scaled_font);
104
105     cairo_matrix_init_scale (&font_matrix, 1000, -1000);
106     cairo_matrix_init_identity (&ctm);
107
108     _cairo_font_options_init_default (&font_options);
109     cairo_font_options_set_hint_style (&font_options, CAIRO_HINT_STYLE_NONE);
110     cairo_font_options_set_hint_metrics (&font_options, CAIRO_HINT_METRICS_OFF);
111
112     font->type1_scaled_font = cairo_scaled_font_create (font_face,
113                                                         &font_matrix,
114                                                         &ctm,
115                                                         &font_options);
116     status = font->type1_scaled_font->status;
117     if (unlikely (status))
118         goto fail;
119
120     _cairo_array_init (&font->contents, sizeof (unsigned char));
121     font->output = NULL;
122
123     *subset_return = font;
124
125     return CAIRO_STATUS_SUCCESS;
126
127 fail:
128     free (font->widths);
129     free (font);
130
131     return status;
132 }
133
134 /* Charstring commands. If the high byte is 0 the command is encoded
135  * with a single byte. */
136 #define CHARSTRING_sbw        0x0c07
137 #define CHARSTRING_rmoveto    0x0015
138 #define CHARSTRING_rlineto    0x0005
139 #define CHARSTRING_rcurveto   0x0008
140 #define CHARSTRING_closepath  0x0009
141 #define CHARSTRING_endchar    0x000e
142
143 /* Before calling this function, the caller must allocate sufficient
144  * space in data (see _cairo_array_grow_by). The maximum number of
145  * bytes that will be used is 2.
146  */
147 static void
148 charstring_encode_command (cairo_array_t *data, int command)
149 {
150     cairo_status_t status;
151     unsigned int orig_size;
152     unsigned char buf[5];
153     unsigned char *p = buf;
154
155     if (command & 0xff00)
156         *p++ = command >> 8;
157     *p++ = command & 0x00ff;
158
159     /* Ensure the array doesn't grow, which allows this function to
160      * have no possibility of failure. */
161     orig_size = _cairo_array_size (data);
162     status = _cairo_array_append_multiple (data, buf, p - buf);
163
164     assert (status == CAIRO_STATUS_SUCCESS);
165     assert (_cairo_array_size (data) == orig_size);
166 }
167
168 /* Before calling this function, the caller must allocate sufficient
169  * space in data (see _cairo_array_grow_by). The maximum number of
170  * bytes that will be used is 5.
171  */
172 static void
173 charstring_encode_integer (cairo_array_t *data,
174                            int i,
175                            cairo_charstring_type_t type)
176 {
177     cairo_status_t status;
178     unsigned int orig_size;
179     unsigned char buf[10];
180     unsigned char *p = buf;
181
182     if (i >= -107 && i <= 107) {
183         *p++ = i + 139;
184     } else if (i >= 108 && i <= 1131) {
185         i -= 108;
186         *p++ = (i >> 8)+ 247;
187         *p++ = i & 0xff;
188     } else if (i >= -1131 && i <= -108) {
189         i = -i - 108;
190         *p++ = (i >> 8)+ 251;
191         *p++ = i & 0xff;
192     } else {
193         if (type == CAIRO_CHARSTRING_TYPE1) {
194             *p++ = 0xff;
195             *p++ = i >> 24;
196             *p++ = (i >> 16) & 0xff;
197             *p++ = (i >> 8)  & 0xff;
198             *p++ = i & 0xff;
199         } else {
200             *p++ = 0xff;
201             *p++ = (i >> 8)  & 0xff;
202             *p++ = i & 0xff;
203             *p++ = 0;
204             *p++ = 0;
205         }
206     }
207
208     /* Ensure the array doesn't grow, which allows this function to
209      * have no possibility of failure. */
210     orig_size = _cairo_array_size (data);
211     status = _cairo_array_append_multiple (data, buf, p - buf);
212
213     assert (status == CAIRO_STATUS_SUCCESS);
214     assert (_cairo_array_size (data) == orig_size);
215 }
216
217 typedef struct _ps_path_info {
218     cairo_array_t *data;
219     int current_x, current_y;
220     cairo_charstring_type_t type;
221 } t1_path_info_t;
222
223 static cairo_status_t
224 _charstring_move_to (void                   *closure,
225                      const cairo_point_t    *point)
226 {
227     t1_path_info_t *path_info = (t1_path_info_t *) closure;
228     int dx, dy;
229     cairo_status_t status;
230
231     status = _cairo_array_grow_by (path_info->data, 12);
232     if (unlikely (status))
233         return status;
234
235     dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
236     dy = _cairo_fixed_integer_part (point->y) - path_info->current_y;
237     charstring_encode_integer (path_info->data, dx, path_info->type);
238     charstring_encode_integer (path_info->data, dy, path_info->type);
239     path_info->current_x += dx;
240     path_info->current_y += dy;
241
242     charstring_encode_command (path_info->data, CHARSTRING_rmoveto);
243
244     return CAIRO_STATUS_SUCCESS;
245 }
246
247 static cairo_status_t
248 _charstring_line_to (void                   *closure,
249                      const cairo_point_t    *point)
250 {
251     t1_path_info_t *path_info = (t1_path_info_t *) closure;
252     int dx, dy;
253     cairo_status_t status;
254
255     status = _cairo_array_grow_by (path_info->data, 12);
256     if (unlikely (status))
257         return status;
258
259     dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
260     dy = _cairo_fixed_integer_part (point->y) - path_info->current_y;
261     charstring_encode_integer (path_info->data, dx, path_info->type);
262     charstring_encode_integer (path_info->data, dy, path_info->type);
263     path_info->current_x += dx;
264     path_info->current_y += dy;
265
266     charstring_encode_command (path_info->data, CHARSTRING_rlineto);
267
268     return CAIRO_STATUS_SUCCESS;
269 }
270
271 static cairo_status_t
272 _charstring_curve_to (void                  *closure,
273                       const cairo_point_t   *point1,
274                       const cairo_point_t   *point2,
275                       const cairo_point_t   *point3)
276 {
277     t1_path_info_t *path_info = (t1_path_info_t *) closure;
278     int dx1, dy1, dx2, dy2, dx3, dy3;
279     cairo_status_t status;
280
281     status = _cairo_array_grow_by (path_info->data, 32);
282     if (unlikely (status))
283         return status;
284
285     dx1 = _cairo_fixed_integer_part (point1->x) - path_info->current_x;
286     dy1 = _cairo_fixed_integer_part (point1->y) - path_info->current_y;
287     dx2 = _cairo_fixed_integer_part (point2->x) - path_info->current_x - dx1;
288     dy2 = _cairo_fixed_integer_part (point2->y) - path_info->current_y - dy1;
289     dx3 = _cairo_fixed_integer_part (point3->x) - path_info->current_x - dx1 - dx2;
290     dy3 = _cairo_fixed_integer_part (point3->y) - path_info->current_y - dy1 - dy2;
291     charstring_encode_integer (path_info->data, dx1, path_info->type);
292     charstring_encode_integer (path_info->data, dy1, path_info->type);
293     charstring_encode_integer (path_info->data, dx2, path_info->type);
294     charstring_encode_integer (path_info->data, dy2, path_info->type);
295     charstring_encode_integer (path_info->data, dx3, path_info->type);
296     charstring_encode_integer (path_info->data, dy3, path_info->type);
297     path_info->current_x += dx1 + dx2 + dx3;
298     path_info->current_y += dy1 + dy2 + dy3;
299     charstring_encode_command (path_info->data, CHARSTRING_rcurveto);
300
301     return CAIRO_STATUS_SUCCESS;
302 }
303
304 static cairo_status_t
305 _charstring_close_path (void *closure)
306 {
307     cairo_status_t status;
308     t1_path_info_t *path_info = (t1_path_info_t *) closure;
309
310     if (path_info->type == CAIRO_CHARSTRING_TYPE2)
311         return CAIRO_STATUS_SUCCESS;
312
313     status = _cairo_array_grow_by (path_info->data, 2);
314     if (unlikely (status))
315         return status;
316
317     charstring_encode_command (path_info->data, CHARSTRING_closepath);
318
319     return CAIRO_STATUS_SUCCESS;
320 }
321
322 static void
323 charstring_encrypt (cairo_array_t *data)
324 {
325     unsigned char *d, *end;
326     uint16_t c, p, r;
327
328     r = CAIRO_TYPE1_CHARSTRING_KEY;
329     d = (unsigned char *) _cairo_array_index (data, 0);
330     if (d == NULL)
331         return;
332
333     end = d + _cairo_array_num_elements (data);
334     while (d < end) {
335         p = *d;
336         c = p ^ (r >> 8);
337         r = (c + r) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
338         *d++ = c;
339     }
340 }
341
342 static cairo_int_status_t
343 cairo_type1_font_create_charstring (cairo_type1_font_t      *font,
344                                     int                      subset_index,
345                                     int                      glyph_index,
346                                     cairo_charstring_type_t  type,
347                                     cairo_array_t           *data)
348 {
349     cairo_int_status_t status;
350     cairo_scaled_glyph_t *scaled_glyph;
351     t1_path_info_t path_info;
352     cairo_text_extents_t *metrics;
353     cairo_bool_t emit_path = TRUE;
354
355     /* This call may return CAIRO_INT_STATUS_UNSUPPORTED for bitmap fonts. */
356     status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
357                                          glyph_index,
358                                          CAIRO_SCALED_GLYPH_INFO_METRICS|
359                                          CAIRO_SCALED_GLYPH_INFO_PATH,
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                                              &scaled_glyph);
370     }
371     if (unlikely (status))
372         return status;
373
374     metrics = &scaled_glyph->metrics;
375     if (subset_index == 0) {
376         font->x_min = metrics->x_bearing;
377         font->y_min = metrics->y_bearing;
378         font->x_max = metrics->x_bearing + metrics->width;
379         font->y_max = metrics->y_bearing + metrics->height;
380     } else {
381         if (metrics->x_bearing < font->x_min)
382             font->x_min = metrics->x_bearing;
383         if (metrics->y_bearing < font->y_min)
384             font->y_min = metrics->y_bearing;
385         if (metrics->x_bearing + metrics->width > font->x_max)
386             font->x_max = metrics->x_bearing + metrics->width;
387         if (metrics->y_bearing + metrics->height > font->y_max)
388             font->y_max = metrics->y_bearing + metrics->height;
389     }
390     font->widths[subset_index] = metrics->x_advance;
391
392     status = _cairo_array_grow_by (data, 30);
393     if (unlikely (status))
394         return status;
395
396     if (type == CAIRO_CHARSTRING_TYPE1) {
397         charstring_encode_integer (data, (int) scaled_glyph->metrics.x_bearing, type);
398         charstring_encode_integer (data, (int) scaled_glyph->metrics.y_bearing, type);
399         charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type);
400         charstring_encode_integer (data, (int) scaled_glyph->metrics.y_advance, type);
401         charstring_encode_command (data, CHARSTRING_sbw);
402
403         path_info.current_x = (int) scaled_glyph->metrics.x_bearing;
404         path_info.current_y = (int) scaled_glyph->metrics.y_bearing;
405     } else {
406         charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type);
407
408         path_info.current_x = 0;
409         path_info.current_y = 0;
410     }
411     path_info.data = data;
412     path_info.type = type;
413     if (emit_path) {
414         status = _cairo_path_fixed_interpret (scaled_glyph->path,
415                                               _charstring_move_to,
416                                               _charstring_line_to,
417                                               _charstring_curve_to,
418                                               _charstring_close_path,
419                                               &path_info);
420         if (unlikely (status))
421             return status;
422     }
423
424     status = _cairo_array_grow_by (data, 1);
425     if (unlikely (status))
426         return status;
427     charstring_encode_command (path_info.data, CHARSTRING_endchar);
428
429     return CAIRO_STATUS_SUCCESS;
430 }
431
432 static cairo_int_status_t
433 cairo_type1_font_write_charstrings (cairo_type1_font_t    *font,
434                                     cairo_output_stream_t *encrypted_output)
435 {
436     cairo_status_t status;
437     unsigned char zeros[] = { 0, 0, 0, 0 };
438     cairo_array_t data;
439     unsigned int i;
440     int length;
441
442     _cairo_array_init (&data, sizeof (unsigned char));
443     status = _cairo_array_grow_by (&data, 1024);
444     if (unlikely (status))
445         goto fail;
446
447     _cairo_output_stream_printf (encrypted_output,
448                                  "2 index /CharStrings %d dict dup begin\n",
449                                  font->scaled_font_subset->num_glyphs + 1);
450
451     _cairo_scaled_font_freeze_cache (font->type1_scaled_font);
452     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
453         _cairo_array_truncate (&data, 0);
454         /* four "random" bytes required by encryption algorithm */
455         status = _cairo_array_append_multiple (&data, zeros, 4);
456         if (unlikely (status))
457             break;
458
459         status = cairo_type1_font_create_charstring (font, i,
460                                                      font->scaled_font_subset->glyphs[i],
461                                                      CAIRO_CHARSTRING_TYPE1,
462                                                      &data);
463         if (unlikely (status))
464             break;
465
466         charstring_encrypt (&data);
467         length = _cairo_array_num_elements (&data);
468         if (font->scaled_font_subset->glyph_names != NULL) {
469             _cairo_output_stream_printf (encrypted_output, "/%s %d RD ",
470                                          font->scaled_font_subset->glyph_names[i],
471                                          length);
472         } else if (i == 0) {
473             _cairo_output_stream_printf (encrypted_output, "/.notdef %d RD ", length);
474         } else {
475             _cairo_output_stream_printf (encrypted_output, "/g%d %d RD ", i, length);
476         }
477         _cairo_output_stream_write (encrypted_output,
478                                     _cairo_array_index (&data, 0),
479                                     length);
480         _cairo_output_stream_printf (encrypted_output, " ND\n");
481     }
482     _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
483
484 fail:
485     _cairo_array_fini (&data);
486     return status;
487 }
488
489 static void
490 cairo_type1_font_write_header (cairo_type1_font_t *font,
491                                const char         *name)
492 {
493     unsigned int i;
494     const char spaces[50] = "                                                  ";
495
496     _cairo_output_stream_printf (font->output,
497                                  "%%!FontType1-1.1 %s 1.0\n"
498                                  "11 dict begin\n"
499                                  "/FontName /%s def\n"
500                                  "/PaintType 0 def\n"
501                                  "/FontType 1 def\n"
502                                   "/FontMatrix [0.001 0 0 0.001 0 0] readonly def\n",
503                                  name,
504                                  name);
505
506     /* We don't know the bbox values until after the charstrings have
507      * been generated.  Reserve some space and fill in the bbox
508      * later. */
509
510     /* Worst case for four signed ints with spaces between each number */
511     font->bbox_max_chars = 50;
512
513     _cairo_output_stream_printf (font->output, "/FontBBox {");
514     font->bbox_position = _cairo_output_stream_get_position (font->output);
515     _cairo_output_stream_write (font->output, spaces, font->bbox_max_chars);
516
517     _cairo_output_stream_printf (font->output,
518                                  "} readonly def\n"
519                                  "/Encoding 256 array\n"
520                                  "0 1 255 {1 index exch /.notdef put} for\n");
521     if (font->scaled_font_subset->is_latin) {
522         for (i = 1; i < 256; i++) {
523             int subset_glyph = font->scaled_font_subset->latin_to_subset_glyph_index[i];
524
525             if (subset_glyph > 0) {
526                 if (font->scaled_font_subset->glyph_names != NULL) {
527                     _cairo_output_stream_printf (font->output, "dup %d /%s put\n",
528                                                  i, font->scaled_font_subset->glyph_names[subset_glyph]);
529                 } else {
530                     _cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, subset_glyph);
531                 }
532             }
533         }
534     } else {
535         for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
536             if (font->scaled_font_subset->glyph_names != NULL) {
537                 _cairo_output_stream_printf (font->output, "dup %d /%s put\n",
538                                              i, font->scaled_font_subset->glyph_names[i]);
539             } else {
540                 _cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, i);
541             }
542         }
543     }
544     _cairo_output_stream_printf (font->output,
545                                  "readonly def\n"
546                                  "currentdict end\n"
547                                  "currentfile eexec\n");
548 }
549
550 static cairo_status_t
551 cairo_type1_write_stream_encrypted (void                *closure,
552                                     const unsigned char *data,
553                                     unsigned int         length)
554 {
555     const unsigned char *in, *end;
556     uint16_t c, p;
557     static const char hex_digits[16] = "0123456789abcdef";
558     char digits[3];
559     cairo_type1_font_t *font = closure;
560
561     in = (const unsigned char *) data;
562     end = (const unsigned char *) data + length;
563     while (in < end) {
564         p = *in++;
565         c = p ^ (font->eexec_key >> 8);
566         font->eexec_key = (c + font->eexec_key) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
567
568         if (font->hex_encode) {
569             digits[0] = hex_digits[c >> 4];
570             digits[1] = hex_digits[c & 0x0f];
571             digits[2] = '\n';
572             font->hex_column += 2;
573
574             if (font->hex_column == 78) {
575                 _cairo_output_stream_write (font->output, digits, 3);
576                 font->hex_column = 0;
577             } else {
578                 _cairo_output_stream_write (font->output, digits, 2);
579             }
580         } else {
581             digits[0] = c;
582             _cairo_output_stream_write (font->output, digits, 1);
583         }
584     }
585
586     return CAIRO_STATUS_SUCCESS;
587 }
588
589 static cairo_int_status_t
590 cairo_type1_font_write_private_dict (cairo_type1_font_t *font,
591                                      const char         *name)
592 {
593     cairo_int_status_t status;
594     cairo_status_t status2;
595     cairo_output_stream_t *encrypted_output;
596
597     font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY;
598     font->hex_column = 0;
599     encrypted_output = _cairo_output_stream_create (
600         cairo_type1_write_stream_encrypted,
601         NULL,
602         font);
603     if (_cairo_output_stream_get_status (encrypted_output))
604         return  _cairo_output_stream_destroy (encrypted_output);
605
606     /* Note: the first four spaces at the start of this private dict
607      * are the four "random" bytes of plaintext required by the
608      * encryption algorithm */
609     _cairo_output_stream_printf (encrypted_output,
610                                  "    dup /Private 9 dict dup begin\n"
611                                  "/RD {string currentfile exch readstring pop}"
612                                  " bind executeonly def\n"
613                                  "/ND {noaccess def} executeonly def\n"
614                                  "/NP {noaccess put} executeonly def\n"
615                                  "/BlueValues [] def\n"
616                                  "/MinFeature {16 16} def\n"
617                                  "/lenIV 4 def\n"
618                                  "/password 5839 def\n");
619
620     status = cairo_type1_font_write_charstrings (font, encrypted_output);
621     if (unlikely (status))
622         goto fail;
623
624     _cairo_output_stream_printf (encrypted_output,
625                                  "end\n"
626                                  "end\n"
627                                  "readonly put\n"
628                                  "noaccess put\n"
629                                  "dup /FontName get exch definefont pop\n"
630                                  "mark currentfile closefile\n");
631
632   fail:
633     status2 = _cairo_output_stream_destroy (encrypted_output);
634     if (status == CAIRO_INT_STATUS_SUCCESS)
635         status = status2;
636
637     return status;
638 }
639
640 static void
641 cairo_type1_font_write_trailer(cairo_type1_font_t *font)
642 {
643     int i;
644     static const char zeros[65] =
645         "0000000000000000000000000000000000000000000000000000000000000000\n";
646
647     for (i = 0; i < 8; i++)
648         _cairo_output_stream_write (font->output, zeros, sizeof zeros);
649
650     _cairo_output_stream_printf (font->output, "cleartomark\n");
651 }
652
653 static cairo_status_t
654 cairo_type1_write_stream (void *closure,
655                          const unsigned char *data,
656                          unsigned int length)
657 {
658     cairo_type1_font_t *font = closure;
659
660     return _cairo_array_append_multiple (&font->contents, data, length);
661 }
662
663 static cairo_int_status_t
664 cairo_type1_font_write (cairo_type1_font_t *font,
665                         const char *name)
666 {
667     cairo_int_status_t status;
668
669     cairo_type1_font_write_header (font, name);
670     font->header_size = _cairo_output_stream_get_position (font->output);
671
672     status = cairo_type1_font_write_private_dict (font, name);
673     if (unlikely (status))
674         return status;
675
676     font->data_size = _cairo_output_stream_get_position (font->output) -
677         font->header_size;
678
679     cairo_type1_font_write_trailer (font);
680     font->trailer_size =
681         _cairo_output_stream_get_position (font->output) -
682         font->header_size - font->data_size;
683
684     return CAIRO_STATUS_SUCCESS;
685 }
686
687 static cairo_int_status_t
688 cairo_type1_font_generate (cairo_type1_font_t *font, const char *name)
689 {
690     cairo_int_status_t status;
691
692     status = _cairo_array_grow_by (&font->contents, 4096);
693     if (unlikely (status))
694         return status;
695
696     font->output = _cairo_output_stream_create (cairo_type1_write_stream, NULL, font);
697     if (_cairo_output_stream_get_status (font->output))
698         return _cairo_output_stream_destroy (font->output);
699
700     status = cairo_type1_font_write (font, name);
701     if (unlikely (status))
702         return status;
703
704     font->data = _cairo_array_index (&font->contents, 0);
705
706     return CAIRO_STATUS_SUCCESS;
707 }
708
709 static cairo_status_t
710 cairo_type1_font_destroy (cairo_type1_font_t *font)
711 {
712     cairo_status_t status = CAIRO_STATUS_SUCCESS;
713
714     free (font->widths);
715     cairo_scaled_font_destroy (font->type1_scaled_font);
716     _cairo_array_fini (&font->contents);
717     if (font->output)
718         status = _cairo_output_stream_destroy (font->output);
719     free (font);
720
721     return status;
722 }
723
724 static cairo_status_t
725 _cairo_type1_fallback_init_internal (cairo_type1_subset_t       *type1_subset,
726                                      const char                 *name,
727                                      cairo_scaled_font_subset_t *scaled_font_subset,
728                                      cairo_bool_t                hex_encode)
729 {
730     cairo_type1_font_t *font;
731     cairo_status_t status;
732     unsigned long length;
733     unsigned int i, len;
734
735     status = cairo_type1_font_create (scaled_font_subset, &font, hex_encode);
736     if (unlikely (status))
737         return status;
738
739     status = cairo_type1_font_generate (font, name);
740     if (unlikely (status))
741         goto fail1;
742
743     type1_subset->base_font = strdup (name);
744     if (unlikely (type1_subset->base_font == NULL)) {
745         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
746         goto fail1;
747     }
748
749     type1_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
750     if (unlikely (type1_subset->widths == NULL)) {
751         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
752         goto fail2;
753     }
754     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
755         type1_subset->widths[i] = (double)font->widths[i]/1000;
756
757     type1_subset->x_min   = (double)font->x_min/1000;
758     type1_subset->y_min   = (double)font->y_min/1000;
759     type1_subset->x_max   = (double)font->x_max/1000;
760     type1_subset->y_max   = (double)font->y_max/1000;
761     type1_subset->ascent  = (double)font->y_max/1000;
762     type1_subset->descent = (double)font->y_min/1000;
763
764     length = font->header_size + font->data_size +
765         font->trailer_size;
766     type1_subset->data = malloc (length);
767     if (unlikely (type1_subset->data == NULL)) {
768         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
769         goto fail3;
770     }
771     memcpy (type1_subset->data,
772             _cairo_array_index (&font->contents, 0), length);
773
774     len = snprintf(type1_subset->data + font->bbox_position,
775                    font->bbox_max_chars,
776                    "%d %d %d %d",
777                    (int)font->x_min,
778                    (int)font->y_min,
779                    (int)font->x_max,
780                    (int)font->y_max);
781     type1_subset->data[font->bbox_position + len] = ' ';
782
783     type1_subset->header_length = font->header_size;
784     type1_subset->data_length = font->data_size;
785     type1_subset->trailer_length = font->trailer_size;
786
787     return cairo_type1_font_destroy (font);
788
789  fail3:
790     free (type1_subset->widths);
791  fail2:
792     free (type1_subset->base_font);
793  fail1:
794     /* status is already set, ignore further errors */
795     cairo_type1_font_destroy (font);
796
797     return status;
798 }
799
800 cairo_status_t
801 _cairo_type1_fallback_init_binary (cairo_type1_subset_t       *type1_subset,
802                                    const char                 *name,
803                                    cairo_scaled_font_subset_t *scaled_font_subset)
804 {
805     return _cairo_type1_fallback_init_internal (type1_subset,
806                                                 name,
807                                                 scaled_font_subset, FALSE);
808 }
809
810 cairo_status_t
811 _cairo_type1_fallback_init_hex (cairo_type1_subset_t       *type1_subset,
812                                 const char                 *name,
813                                 cairo_scaled_font_subset_t *scaled_font_subset)
814 {
815     return _cairo_type1_fallback_init_internal (type1_subset,
816                                                 name,
817                                                 scaled_font_subset, TRUE);
818 }
819
820 void
821 _cairo_type1_fallback_fini (cairo_type1_subset_t *subset)
822 {
823     free (subset->base_font);
824     free (subset->widths);
825     free (subset->data);
826 }
827
828 cairo_status_t
829 _cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset,
830                                cairo_scaled_font_subset_t *scaled_font_subset)
831 {
832     cairo_type1_font_t *font;
833     cairo_status_t status;
834     unsigned int i;
835     cairo_array_t charstring;
836
837     status = cairo_type1_font_create (scaled_font_subset, &font, FALSE);
838     if (unlikely (status))
839         return status;
840
841     _cairo_array_init (&type2_subset->charstrings, sizeof (cairo_array_t));
842
843     type2_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
844     if (unlikely (type2_subset->widths == NULL)) {
845         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
846         goto fail1;
847     }
848
849     _cairo_scaled_font_freeze_cache (font->type1_scaled_font);
850     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
851         _cairo_array_init (&charstring, sizeof (unsigned char));
852         status = _cairo_array_grow_by (&charstring, 32);
853         if (unlikely (status))
854             goto fail2;
855
856         status = cairo_type1_font_create_charstring (font, i,
857                                                      font->scaled_font_subset->glyphs[i],
858                                                      CAIRO_CHARSTRING_TYPE2,
859                                                      &charstring);
860         if (unlikely (status))
861             goto fail2;
862
863         status = _cairo_array_append (&type2_subset->charstrings, &charstring);
864         if (unlikely (status))
865             goto fail2;
866     }
867     _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
868
869     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
870         type2_subset->widths[i] = font->widths[i];
871
872     type2_subset->x_min   = (int) font->x_min;
873     type2_subset->y_min   = (int) font->y_min;
874     type2_subset->x_max   = (int) font->x_max;
875     type2_subset->y_max   = (int) font->y_max;
876     type2_subset->ascent  = (int) font->y_max;
877     type2_subset->descent = (int) font->y_min;
878
879     return cairo_type1_font_destroy (font);
880
881 fail2:
882     _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
883     _cairo_array_fini (&charstring);
884     _cairo_type2_charstrings_fini (type2_subset);
885 fail1:
886     cairo_type1_font_destroy (font);
887     return status;
888 }
889
890 void
891 _cairo_type2_charstrings_fini (cairo_type2_charstrings_t *type2_subset)
892 {
893     unsigned int i, num_charstrings;
894     cairo_array_t *charstring;
895
896     num_charstrings = _cairo_array_num_elements (&type2_subset->charstrings);
897     for (i = 0; i < num_charstrings; i++) {
898         charstring = _cairo_array_index (&type2_subset->charstrings, i);
899         if (charstring)
900             _cairo_array_fini (charstring);
901     }
902     _cairo_array_fini (&type2_subset->charstrings);
903
904     free (type2_subset->widths);
905 }
906
907 #endif /* CAIRO_HAS_FONT_SUBSET */