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.
33 * Adrian Johnson <ajohnson@redneon.com>
36 #define _BSD_SOURCE /* for snprintf(), strdup() */
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"
50 CAIRO_CHARSTRING_TYPE1
,
51 CAIRO_CHARSTRING_TYPE2
52 } cairo_charstring_type_t
;
54 typedef struct _cairo_type1_font
{
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
;
65 unsigned long header_size
;
66 unsigned long data_size
;
67 unsigned long trailer_size
;
71 cairo_output_stream_t
*output
;
73 unsigned short eexec_key
;
74 cairo_bool_t hex_encode
;
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
;
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
)) {
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
,
116 status
= font
->type1_scaled_font
->status
;
117 if (unlikely (status
))
120 _cairo_array_init (&font
->contents
, sizeof (unsigned char));
123 *subset_return
= font
;
125 return CAIRO_STATUS_SUCCESS
;
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.
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)
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.
173 charstring_encode_integer (cairo_array_t
*data
,
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) {
184 } else if (i
>= 108 && i
<= 1131) {
186 *p
++ = (i
>> 8)+ 247;
188 } else if (i
>= -1131 && i
<= -108) {
190 *p
++ = (i
>> 8)+ 251;
193 if (type
== CAIRO_CHARSTRING_TYPE1
) {
196 *p
++ = (i
>> 16) & 0xff;
197 *p
++ = (i
>> 8) & 0xff;
201 *p
++ = (i
>> 8) & 0xff;
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
{
219 int current_x
, current_y
;
220 cairo_charstring_type_t type
;
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
;
229 cairo_status_t status
;
231 status
= _cairo_array_grow_by (path_info
->data
, 12);
232 if (unlikely (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
;
253 cairo_status_t status
;
255 status
= _cairo_array_grow_by (path_info
->data
, 12);
256 if (unlikely (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
))
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
))
317 charstring_encode_command (path_info
->data
, CHARSTRING_closepath
);
319 return CAIRO_STATUS_SUCCESS
;
323 charstring_encrypt (cairo_array_t
*data
)
325 unsigned char *d
, *end
;
328 r
= CAIRO_TYPE1_CHARSTRING_KEY
;
329 d
= (unsigned char *) _cairo_array_index (data
, 0);
330 end
= d
+ _cairo_array_num_elements (data
);
334 r
= (c
+ r
) * CAIRO_TYPE1_ENCRYPT_C1
+ CAIRO_TYPE1_ENCRYPT_C2
;
339 static cairo_int_status_t
340 cairo_type1_font_create_charstring (cairo_type1_font_t
*font
,
343 cairo_charstring_type_t type
,
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
,
355 CAIRO_SCALED_GLYPH_INFO_METRICS
|
356 CAIRO_SCALED_GLYPH_INFO_PATH
,
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
) {
363 status
= _cairo_scaled_glyph_lookup (font
->type1_scaled_font
,
365 CAIRO_SCALED_GLYPH_INFO_METRICS
,
368 if (unlikely (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
;
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
))
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
;
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
;
411 status
= _cairo_path_fixed_interpret (scaled_glyph
->path
,
414 _charstring_curve_to
,
415 _charstring_close_path
,
417 if (unlikely (status
))
421 status
= _cairo_array_grow_by (data
, 1);
422 if (unlikely (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 };
439 _cairo_array_init (&data
, sizeof (unsigned char));
440 status
= _cairo_array_grow_by (&data
, 1024);
441 if (unlikely (status
))
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
))
456 status
= cairo_type1_font_create_charstring (font
, i
,
457 font
->scaled_font_subset
->glyphs
[i
],
458 CAIRO_CHARSTRING_TYPE1
,
460 if (unlikely (status
))
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
],
470 _cairo_output_stream_printf (encrypted_output
, "/.notdef %d RD ", length
);
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),
477 _cairo_output_stream_printf (encrypted_output
, " ND\n");
479 _cairo_scaled_font_thaw_cache (font
->type1_scaled_font
);
482 _cairo_array_fini (&data
);
487 cairo_type1_font_write_header (cairo_type1_font_t
*font
,
491 const char spaces
[50] = " ";
493 _cairo_output_stream_printf (font
->output
,
494 "%%!FontType1-1.1 %s 1.0\n"
496 "/FontName /%s def\n"
499 "/FontMatrix [0.001 0 0 0.001 0 0] readonly def\n",
503 /* We don't know the bbox values until after the charstrings have
504 * been generated. Reserve some space and fill in the bbox
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
,
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
]);
527 _cairo_output_stream_printf (font
->output
, "dup %d /g%d put\n", i
, subset_glyph
);
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
]);
537 _cairo_output_stream_printf (font
->output
, "dup %d /g%d put\n", i
, i
);
541 _cairo_output_stream_printf (font
->output
,
544 "currentfile eexec\n");
547 static cairo_status_t
548 cairo_type1_write_stream_encrypted (void *closure
,
549 const unsigned char *data
,
552 const unsigned char *in
, *end
;
554 static const char hex_digits
[16] = "0123456789abcdef";
556 cairo_type1_font_t
*font
= closure
;
558 in
= (const unsigned char *) data
;
559 end
= (const unsigned char *) data
+ length
;
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];
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;
575 _cairo_output_stream_write (font
->output
, digits
, 2);
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
,
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
,
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"
615 "/password 5839 def\n");
617 status
= cairo_type1_font_write_charstrings (font
, encrypted_output
);
618 if (unlikely (status
))
621 _cairo_output_stream_printf (encrypted_output
,
626 "dup /FontName get exch definefont pop\n"
627 "mark currentfile closefile\n");
630 status2
= _cairo_output_stream_destroy (encrypted_output
);
631 if (status
== CAIRO_INT_STATUS_SUCCESS
)
638 cairo_type1_font_write_trailer(cairo_type1_font_t
*font
)
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
,
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
,
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
))
673 font
->data_size
= _cairo_output_stream_get_position (font
->output
) -
676 cairo_type1_font_write_trailer (font
);
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
))
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
))
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
;
712 cairo_scaled_font_destroy (font
->type1_scaled_font
);
713 _cairo_array_fini (&font
->contents
);
715 status
= _cairo_output_stream_destroy (font
->output
);
721 static cairo_status_t
722 _cairo_type1_fallback_init_internal (cairo_type1_subset_t
*type1_subset
,
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
;
732 status
= cairo_type1_font_create (scaled_font_subset
, &font
, hex_encode
);
733 if (unlikely (status
))
736 status
= cairo_type1_font_generate (font
, name
);
737 if (unlikely (status
))
740 type1_subset
->base_font
= strdup (name
);
741 if (unlikely (type1_subset
->base_font
== NULL
)) {
742 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
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
);
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
+
763 type1_subset
->data
= malloc (length
);
764 if (unlikely (type1_subset
->data
== NULL
)) {
765 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
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
,
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
);
787 free (type1_subset
->widths
);
789 free (type1_subset
->base_font
);
791 /* status is already set, ignore further errors */
792 cairo_type1_font_destroy (font
);
798 _cairo_type1_fallback_init_binary (cairo_type1_subset_t
*type1_subset
,
800 cairo_scaled_font_subset_t
*scaled_font_subset
)
802 return _cairo_type1_fallback_init_internal (type1_subset
,
804 scaled_font_subset
, FALSE
);
808 _cairo_type1_fallback_init_hex (cairo_type1_subset_t
*type1_subset
,
810 cairo_scaled_font_subset_t
*scaled_font_subset
)
812 return _cairo_type1_fallback_init_internal (type1_subset
,
814 scaled_font_subset
, TRUE
);
818 _cairo_type1_fallback_fini (cairo_type1_subset_t
*subset
)
820 free (subset
->base_font
);
821 free (subset
->widths
);
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
;
832 cairo_array_t charstring
;
834 status
= cairo_type1_font_create (scaled_font_subset
, &font
, FALSE
);
835 if (unlikely (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
);
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
))
853 status
= cairo_type1_font_create_charstring (font
, i
,
854 font
->scaled_font_subset
->glyphs
[i
],
855 CAIRO_CHARSTRING_TYPE2
,
857 if (unlikely (status
))
860 status
= _cairo_array_append (&type2_subset
->charstrings
, &charstring
);
861 if (unlikely (status
))
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
);
879 _cairo_scaled_font_thaw_cache (font
->type1_scaled_font
);
880 _cairo_array_fini (&charstring
);
881 _cairo_type2_charstrings_fini (type2_subset
);
883 cairo_type1_font_destroy (font
);
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 */