beta-0.89.2
[luatex.git] / source / libs / cairo / cairo-src / src / cairo-type1-fallback.c
blob4a657413e48dba6100b43a20c5af5d377d3de4d1
1 /* cairo - a vector graphics library with display and print output
3 * Copyright © 2006 Red Hat, Inc
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.
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
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/
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.
28 * The Original Code is the cairo graphics library.
30 * The Initial Developer of the Original Code is Red Hat, Inc.
32 * Contributor(s):
33 * Adrian Johnson <ajohnson@redneon.com>
36 #define _BSD_SOURCE /* for snprintf(), strdup() */
37 #include "cairoint.h"
39 #include "cairo-array-private.h"
40 #include "cairo-error-private.h"
42 #if CAIRO_HAS_FONT_SUBSET
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"
49 typedef enum {
50 CAIRO_CHARSTRING_TYPE1,
51 CAIRO_CHARSTRING_TYPE2
52 } cairo_charstring_type_t;
54 typedef struct _cairo_type1_font {
55 int *widths;
57 cairo_scaled_font_subset_t *scaled_font_subset;
58 cairo_scaled_font_t *type1_scaled_font;
60 cairo_array_t contents;
62 double x_min, y_min, x_max, y_max;
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;
71 cairo_output_stream_t *output;
73 unsigned short eexec_key;
74 cairo_bool_t hex_encode;
75 int hex_column;
76 } cairo_type1_font_t;
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)
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;
90 font = calloc (1, sizeof (cairo_type1_font_t));
91 if (unlikely (font == NULL))
92 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
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);
100 font->scaled_font_subset = scaled_font_subset;
101 font->hex_encode = hex_encode;
103 font_face = cairo_scaled_font_get_font_face (scaled_font_subset->scaled_font);
105 cairo_matrix_init_scale (&font_matrix, 1000, -1000);
106 cairo_matrix_init_identity (&ctm);
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);
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;
120 _cairo_array_init (&font->contents, sizeof (unsigned char));
121 font->output = NULL;
123 *subset_return = font;
125 return CAIRO_STATUS_SUCCESS;
127 fail:
128 free (font->widths);
129 free (font);
131 return status;
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
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.
147 static void
148 charstring_encode_command (cairo_array_t *data, int command)
150 cairo_status_t status;
151 unsigned int orig_size;
152 unsigned char buf[5];
153 unsigned char *p = buf;
155 if (command & 0xff00)
156 *p++ = command >> 8;
157 *p++ = command & 0x00ff;
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);
164 assert (status == CAIRO_STATUS_SUCCESS);
165 assert (_cairo_array_size (data) == orig_size);
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.
172 static void
173 charstring_encode_integer (cairo_array_t *data,
174 int i,
175 cairo_charstring_type_t type)
177 cairo_status_t status;
178 unsigned int orig_size;
179 unsigned char buf[10];
180 unsigned char *p = buf;
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;
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);
213 assert (status == CAIRO_STATUS_SUCCESS);
214 assert (_cairo_array_size (data) == orig_size);
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;
223 static cairo_status_t
224 _charstring_move_to (void *closure,
225 const cairo_point_t *point)
227 t1_path_info_t *path_info = (t1_path_info_t *) closure;
228 int dx, dy;
229 cairo_status_t status;
231 status = _cairo_array_grow_by (path_info->data, 12);
232 if (unlikely (status))
233 return status;
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;
242 charstring_encode_command (path_info->data, CHARSTRING_rmoveto);
244 return CAIRO_STATUS_SUCCESS;
247 static cairo_status_t
248 _charstring_line_to (void *closure,
249 const cairo_point_t *point)
251 t1_path_info_t *path_info = (t1_path_info_t *) closure;
252 int dx, dy;
253 cairo_status_t status;
255 status = _cairo_array_grow_by (path_info->data, 12);
256 if (unlikely (status))
257 return status;
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;
266 charstring_encode_command (path_info->data, CHARSTRING_rlineto);
268 return CAIRO_STATUS_SUCCESS;
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)
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;
281 status = _cairo_array_grow_by (path_info->data, 32);
282 if (unlikely (status))
283 return status;
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);
301 return CAIRO_STATUS_SUCCESS;
304 static cairo_status_t
305 _charstring_close_path (void *closure)
307 cairo_status_t status;
308 t1_path_info_t *path_info = (t1_path_info_t *) closure;
310 if (path_info->type == CAIRO_CHARSTRING_TYPE2)
311 return CAIRO_STATUS_SUCCESS;
313 status = _cairo_array_grow_by (path_info->data, 2);
314 if (unlikely (status))
315 return status;
317 charstring_encode_command (path_info->data, CHARSTRING_closepath);
319 return CAIRO_STATUS_SUCCESS;
322 static void
323 charstring_encrypt (cairo_array_t *data)
325 unsigned char *d, *end;
326 uint16_t c, p, r;
328 r = CAIRO_TYPE1_CHARSTRING_KEY;
329 d = (unsigned char *) _cairo_array_index (data, 0);
330 end = d + _cairo_array_num_elements (data);
331 while (d < end) {
332 p = *d;
333 c = p ^ (r >> 8);
334 r = (c + r) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
335 *d++ = c;
339 static cairo_int_status_t
340 cairo_type1_font_create_charstring (cairo_type1_font_t *font,
341 int subset_index,
342 int glyph_index,
343 cairo_charstring_type_t type,
344 cairo_array_t *data)
346 cairo_int_status_t status;
347 cairo_scaled_glyph_t *scaled_glyph;
348 t1_path_info_t path_info;
349 cairo_text_extents_t *metrics;
350 cairo_bool_t emit_path = TRUE;
352 /* This call may return CAIRO_INT_STATUS_UNSUPPORTED for bitmap fonts. */
353 status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
354 glyph_index,
355 CAIRO_SCALED_GLYPH_INFO_METRICS|
356 CAIRO_SCALED_GLYPH_INFO_PATH,
357 &scaled_glyph);
359 /* It is ok for the .notdef glyph to not have a path available. We
360 * just need the metrics to emit an empty glyph. */
361 if (glyph_index == 0 && status == CAIRO_INT_STATUS_UNSUPPORTED) {
362 emit_path = FALSE;
363 status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
364 glyph_index,
365 CAIRO_SCALED_GLYPH_INFO_METRICS,
366 &scaled_glyph);
368 if (unlikely (status))
369 return status;
371 metrics = &scaled_glyph->metrics;
372 if (subset_index == 0) {
373 font->x_min = metrics->x_bearing;
374 font->y_min = metrics->y_bearing;
375 font->x_max = metrics->x_bearing + metrics->width;
376 font->y_max = metrics->y_bearing + metrics->height;
377 } else {
378 if (metrics->x_bearing < font->x_min)
379 font->x_min = metrics->x_bearing;
380 if (metrics->y_bearing < font->y_min)
381 font->y_min = metrics->y_bearing;
382 if (metrics->x_bearing + metrics->width > font->x_max)
383 font->x_max = metrics->x_bearing + metrics->width;
384 if (metrics->y_bearing + metrics->height > font->y_max)
385 font->y_max = metrics->y_bearing + metrics->height;
387 font->widths[subset_index] = metrics->x_advance;
389 status = _cairo_array_grow_by (data, 30);
390 if (unlikely (status))
391 return status;
393 if (type == CAIRO_CHARSTRING_TYPE1) {
394 charstring_encode_integer (data, (int) scaled_glyph->metrics.x_bearing, type);
395 charstring_encode_integer (data, (int) scaled_glyph->metrics.y_bearing, type);
396 charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type);
397 charstring_encode_integer (data, (int) scaled_glyph->metrics.y_advance, type);
398 charstring_encode_command (data, CHARSTRING_sbw);
400 path_info.current_x = (int) scaled_glyph->metrics.x_bearing;
401 path_info.current_y = (int) scaled_glyph->metrics.y_bearing;
402 } else {
403 charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type);
405 path_info.current_x = 0;
406 path_info.current_y = 0;
408 path_info.data = data;
409 path_info.type = type;
410 if (emit_path) {
411 status = _cairo_path_fixed_interpret (scaled_glyph->path,
412 _charstring_move_to,
413 _charstring_line_to,
414 _charstring_curve_to,
415 _charstring_close_path,
416 &path_info);
417 if (unlikely (status))
418 return status;
421 status = _cairo_array_grow_by (data, 1);
422 if (unlikely (status))
423 return status;
424 charstring_encode_command (path_info.data, CHARSTRING_endchar);
426 return CAIRO_STATUS_SUCCESS;
429 static cairo_int_status_t
430 cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
431 cairo_output_stream_t *encrypted_output)
433 cairo_status_t status;
434 unsigned char zeros[] = { 0, 0, 0, 0 };
435 cairo_array_t data;
436 unsigned int i;
437 int length;
439 _cairo_array_init (&data, sizeof (unsigned char));
440 status = _cairo_array_grow_by (&data, 1024);
441 if (unlikely (status))
442 goto fail;
444 _cairo_output_stream_printf (encrypted_output,
445 "2 index /CharStrings %d dict dup begin\n",
446 font->scaled_font_subset->num_glyphs + 1);
448 _cairo_scaled_font_freeze_cache (font->type1_scaled_font);
449 for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
450 _cairo_array_truncate (&data, 0);
451 /* four "random" bytes required by encryption algorithm */
452 status = _cairo_array_append_multiple (&data, zeros, 4);
453 if (unlikely (status))
454 break;
456 status = cairo_type1_font_create_charstring (font, i,
457 font->scaled_font_subset->glyphs[i],
458 CAIRO_CHARSTRING_TYPE1,
459 &data);
460 if (unlikely (status))
461 break;
463 charstring_encrypt (&data);
464 length = _cairo_array_num_elements (&data);
465 if (font->scaled_font_subset->glyph_names != NULL) {
466 _cairo_output_stream_printf (encrypted_output, "/%s %d RD ",
467 font->scaled_font_subset->glyph_names[i],
468 length);
469 } else if (i == 0) {
470 _cairo_output_stream_printf (encrypted_output, "/.notdef %d RD ", length);
471 } else {
472 _cairo_output_stream_printf (encrypted_output, "/g%d %d RD ", i, length);
474 _cairo_output_stream_write (encrypted_output,
475 _cairo_array_index (&data, 0),
476 length);
477 _cairo_output_stream_printf (encrypted_output, " ND\n");
479 _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
481 fail:
482 _cairo_array_fini (&data);
483 return status;
486 static void
487 cairo_type1_font_write_header (cairo_type1_font_t *font,
488 const char *name)
490 unsigned int i;
491 const char spaces[50] = " ";
493 _cairo_output_stream_printf (font->output,
494 "%%!FontType1-1.1 %s 1.0\n"
495 "11 dict begin\n"
496 "/FontName /%s def\n"
497 "/PaintType 0 def\n"
498 "/FontType 1 def\n"
499 "/FontMatrix [0.001 0 0 0.001 0 0] readonly def\n",
500 name,
501 name);
503 /* We don't know the bbox values until after the charstrings have
504 * been generated. Reserve some space and fill in the bbox
505 * later. */
507 /* Worst case for four signed ints with spaces between each number */
508 font->bbox_max_chars = 50;
510 _cairo_output_stream_printf (font->output, "/FontBBox {");
511 font->bbox_position = _cairo_output_stream_get_position (font->output);
512 _cairo_output_stream_write (font->output, spaces, font->bbox_max_chars);
514 _cairo_output_stream_printf (font->output,
515 "} readonly def\n"
516 "/Encoding 256 array\n"
517 "0 1 255 {1 index exch /.notdef put} for\n");
518 if (font->scaled_font_subset->is_latin) {
519 for (i = 1; i < 256; i++) {
520 int subset_glyph = font->scaled_font_subset->latin_to_subset_glyph_index[i];
522 if (subset_glyph > 0) {
523 if (font->scaled_font_subset->glyph_names != NULL) {
524 _cairo_output_stream_printf (font->output, "dup %d /%s put\n",
525 i, font->scaled_font_subset->glyph_names[subset_glyph]);
526 } else {
527 _cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, subset_glyph);
531 } else {
532 for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
533 if (font->scaled_font_subset->glyph_names != NULL) {
534 _cairo_output_stream_printf (font->output, "dup %d /%s put\n",
535 i, font->scaled_font_subset->glyph_names[i]);
536 } else {
537 _cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, i);
541 _cairo_output_stream_printf (font->output,
542 "readonly def\n"
543 "currentdict end\n"
544 "currentfile eexec\n");
547 static cairo_status_t
548 cairo_type1_write_stream_encrypted (void *closure,
549 const unsigned char *data,
550 unsigned int length)
552 const unsigned char *in, *end;
553 uint16_t c, p;
554 static const char hex_digits[16] = "0123456789abcdef";
555 char digits[3];
556 cairo_type1_font_t *font = closure;
558 in = (const unsigned char *) data;
559 end = (const unsigned char *) data + length;
560 while (in < end) {
561 p = *in++;
562 c = p ^ (font->eexec_key >> 8);
563 font->eexec_key = (c + font->eexec_key) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
565 if (font->hex_encode) {
566 digits[0] = hex_digits[c >> 4];
567 digits[1] = hex_digits[c & 0x0f];
568 digits[2] = '\n';
569 font->hex_column += 2;
571 if (font->hex_column == 78) {
572 _cairo_output_stream_write (font->output, digits, 3);
573 font->hex_column = 0;
574 } else {
575 _cairo_output_stream_write (font->output, digits, 2);
577 } else {
578 digits[0] = c;
579 _cairo_output_stream_write (font->output, digits, 1);
583 return CAIRO_STATUS_SUCCESS;
586 static cairo_int_status_t
587 cairo_type1_font_write_private_dict (cairo_type1_font_t *font,
588 const char *name)
590 cairo_int_status_t status;
591 cairo_status_t status2;
592 cairo_output_stream_t *encrypted_output;
594 font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY;
595 font->hex_column = 0;
596 encrypted_output = _cairo_output_stream_create (
597 cairo_type1_write_stream_encrypted,
598 NULL,
599 font);
600 if (_cairo_output_stream_get_status (encrypted_output))
601 return _cairo_output_stream_destroy (encrypted_output);
603 /* Note: the first four spaces at the start of this private dict
604 * are the four "random" bytes of plaintext required by the
605 * encryption algorithm */
606 _cairo_output_stream_printf (encrypted_output,
607 " dup /Private 9 dict dup begin\n"
608 "/RD {string currentfile exch readstring pop}"
609 " bind executeonly def\n"
610 "/ND {noaccess def} executeonly def\n"
611 "/NP {noaccess put} executeonly def\n"
612 "/BlueValues [] def\n"
613 "/MinFeature {16 16} def\n"
614 "/lenIV 4 def\n"
615 "/password 5839 def\n");
617 status = cairo_type1_font_write_charstrings (font, encrypted_output);
618 if (unlikely (status))
619 goto fail;
621 _cairo_output_stream_printf (encrypted_output,
622 "end\n"
623 "end\n"
624 "readonly put\n"
625 "noaccess put\n"
626 "dup /FontName get exch definefont pop\n"
627 "mark currentfile closefile\n");
629 fail:
630 status2 = _cairo_output_stream_destroy (encrypted_output);
631 if (status == CAIRO_INT_STATUS_SUCCESS)
632 status = status2;
634 return status;
637 static void
638 cairo_type1_font_write_trailer(cairo_type1_font_t *font)
640 int i;
641 static const char zeros[65] =
642 "0000000000000000000000000000000000000000000000000000000000000000\n";
644 for (i = 0; i < 8; i++)
645 _cairo_output_stream_write (font->output, zeros, sizeof zeros);
647 _cairo_output_stream_printf (font->output, "cleartomark\n");
650 static cairo_status_t
651 cairo_type1_write_stream (void *closure,
652 const unsigned char *data,
653 unsigned int length)
655 cairo_type1_font_t *font = closure;
657 return _cairo_array_append_multiple (&font->contents, data, length);
660 static cairo_int_status_t
661 cairo_type1_font_write (cairo_type1_font_t *font,
662 const char *name)
664 cairo_int_status_t status;
666 cairo_type1_font_write_header (font, name);
667 font->header_size = _cairo_output_stream_get_position (font->output);
669 status = cairo_type1_font_write_private_dict (font, name);
670 if (unlikely (status))
671 return status;
673 font->data_size = _cairo_output_stream_get_position (font->output) -
674 font->header_size;
676 cairo_type1_font_write_trailer (font);
677 font->trailer_size =
678 _cairo_output_stream_get_position (font->output) -
679 font->header_size - font->data_size;
681 return CAIRO_STATUS_SUCCESS;
684 static cairo_int_status_t
685 cairo_type1_font_generate (cairo_type1_font_t *font, const char *name)
687 cairo_int_status_t status;
689 status = _cairo_array_grow_by (&font->contents, 4096);
690 if (unlikely (status))
691 return status;
693 font->output = _cairo_output_stream_create (cairo_type1_write_stream, NULL, font);
694 if (_cairo_output_stream_get_status (font->output))
695 return _cairo_output_stream_destroy (font->output);
697 status = cairo_type1_font_write (font, name);
698 if (unlikely (status))
699 return status;
701 font->data = _cairo_array_index (&font->contents, 0);
703 return CAIRO_STATUS_SUCCESS;
706 static cairo_status_t
707 cairo_type1_font_destroy (cairo_type1_font_t *font)
709 cairo_status_t status = CAIRO_STATUS_SUCCESS;
711 free (font->widths);
712 cairo_scaled_font_destroy (font->type1_scaled_font);
713 _cairo_array_fini (&font->contents);
714 if (font->output)
715 status = _cairo_output_stream_destroy (font->output);
716 free (font);
718 return status;
721 static cairo_status_t
722 _cairo_type1_fallback_init_internal (cairo_type1_subset_t *type1_subset,
723 const char *name,
724 cairo_scaled_font_subset_t *scaled_font_subset,
725 cairo_bool_t hex_encode)
727 cairo_type1_font_t *font;
728 cairo_status_t status;
729 unsigned long length;
730 unsigned int i, len;
732 status = cairo_type1_font_create (scaled_font_subset, &font, hex_encode);
733 if (unlikely (status))
734 return status;
736 status = cairo_type1_font_generate (font, name);
737 if (unlikely (status))
738 goto fail1;
740 type1_subset->base_font = strdup (name);
741 if (unlikely (type1_subset->base_font == NULL)) {
742 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
743 goto fail1;
746 type1_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
747 if (unlikely (type1_subset->widths == NULL)) {
748 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
749 goto fail2;
751 for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
752 type1_subset->widths[i] = (double)font->widths[i]/1000;
754 type1_subset->x_min = (double)font->x_min/1000;
755 type1_subset->y_min = (double)font->y_min/1000;
756 type1_subset->x_max = (double)font->x_max/1000;
757 type1_subset->y_max = (double)font->y_max/1000;
758 type1_subset->ascent = (double)font->y_max/1000;
759 type1_subset->descent = (double)font->y_min/1000;
761 length = font->header_size + font->data_size +
762 font->trailer_size;
763 type1_subset->data = malloc (length);
764 if (unlikely (type1_subset->data == NULL)) {
765 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
766 goto fail3;
768 memcpy (type1_subset->data,
769 _cairo_array_index (&font->contents, 0), length);
771 len = snprintf(type1_subset->data + font->bbox_position,
772 font->bbox_max_chars,
773 "%d %d %d %d",
774 (int)font->x_min,
775 (int)font->y_min,
776 (int)font->x_max,
777 (int)font->y_max);
778 type1_subset->data[font->bbox_position + len] = ' ';
780 type1_subset->header_length = font->header_size;
781 type1_subset->data_length = font->data_size;
782 type1_subset->trailer_length = font->trailer_size;
784 return cairo_type1_font_destroy (font);
786 fail3:
787 free (type1_subset->widths);
788 fail2:
789 free (type1_subset->base_font);
790 fail1:
791 /* status is already set, ignore further errors */
792 cairo_type1_font_destroy (font);
794 return status;
797 cairo_status_t
798 _cairo_type1_fallback_init_binary (cairo_type1_subset_t *type1_subset,
799 const char *name,
800 cairo_scaled_font_subset_t *scaled_font_subset)
802 return _cairo_type1_fallback_init_internal (type1_subset,
803 name,
804 scaled_font_subset, FALSE);
807 cairo_status_t
808 _cairo_type1_fallback_init_hex (cairo_type1_subset_t *type1_subset,
809 const char *name,
810 cairo_scaled_font_subset_t *scaled_font_subset)
812 return _cairo_type1_fallback_init_internal (type1_subset,
813 name,
814 scaled_font_subset, TRUE);
817 void
818 _cairo_type1_fallback_fini (cairo_type1_subset_t *subset)
820 free (subset->base_font);
821 free (subset->widths);
822 free (subset->data);
825 cairo_status_t
826 _cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset,
827 cairo_scaled_font_subset_t *scaled_font_subset)
829 cairo_type1_font_t *font;
830 cairo_status_t status;
831 unsigned int i;
832 cairo_array_t charstring;
834 status = cairo_type1_font_create (scaled_font_subset, &font, FALSE);
835 if (unlikely (status))
836 return status;
838 _cairo_array_init (&type2_subset->charstrings, sizeof (cairo_array_t));
840 type2_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
841 if (unlikely (type2_subset->widths == NULL)) {
842 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
843 goto fail1;
846 _cairo_scaled_font_freeze_cache (font->type1_scaled_font);
847 for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
848 _cairo_array_init (&charstring, sizeof (unsigned char));
849 status = _cairo_array_grow_by (&charstring, 32);
850 if (unlikely (status))
851 goto fail2;
853 status = cairo_type1_font_create_charstring (font, i,
854 font->scaled_font_subset->glyphs[i],
855 CAIRO_CHARSTRING_TYPE2,
856 &charstring);
857 if (unlikely (status))
858 goto fail2;
860 status = _cairo_array_append (&type2_subset->charstrings, &charstring);
861 if (unlikely (status))
862 goto fail2;
864 _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
866 for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
867 type2_subset->widths[i] = font->widths[i];
869 type2_subset->x_min = (int) font->x_min;
870 type2_subset->y_min = (int) font->y_min;
871 type2_subset->x_max = (int) font->x_max;
872 type2_subset->y_max = (int) font->y_max;
873 type2_subset->ascent = (int) font->y_max;
874 type2_subset->descent = (int) font->y_min;
876 return cairo_type1_font_destroy (font);
878 fail2:
879 _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
880 _cairo_array_fini (&charstring);
881 _cairo_type2_charstrings_fini (type2_subset);
882 fail1:
883 cairo_type1_font_destroy (font);
884 return status;
887 void
888 _cairo_type2_charstrings_fini (cairo_type2_charstrings_t *type2_subset)
890 unsigned int i, num_charstrings;
891 cairo_array_t *charstring;
893 num_charstrings = _cairo_array_num_elements (&type2_subset->charstrings);
894 for (i = 0; i < num_charstrings; i++) {
895 charstring = _cairo_array_index (&type2_subset->charstrings, i);
896 _cairo_array_fini (charstring);
898 _cairo_array_fini (&type2_subset->charstrings);
900 free (type2_subset->widths);
903 #endif /* CAIRO_HAS_FONT_SUBSET */