1 /* cairo - a vector graphics library with display and print output
3 * Copyright © 2006 Adrian Johnson
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Adrian Johnson.
33 * Adrian Johnson <ajohnson@redneon.com>
34 * Eugeniy Meshcheryakov <eugen@debian.org>
39 * http://www.adobe.com/devnet/font/pdfs/5176.CFF.pdf
42 #define _BSD_SOURCE /* for snprintf(), strdup() */
45 #if CAIRO_HAS_FONT_SUBSET
47 #include "cairo-scaled-font-subsets-private.h"
48 #include "cairo-truetype-subset-private.h"
51 /* CFF Dict Operators. If the high byte is 0 the command is encoded
52 * with a single byte. */
53 #define BASEFONTNAME_OP 0x0c16
54 #define CIDCOUNT_OP 0x0c22
55 #define CHARSET_OP 0x000f
56 #define CHARSTRINGS_OP 0x0011
57 #define COPYRIGHT_OP 0x0c00
58 #define ENCODING_OP 0x0010
59 #define FAMILYNAME_OP 0x0003
60 #define FDARRAY_OP 0x0c24
61 #define FDSELECT_OP 0x0c25
62 #define FONTBBOX_OP 0x0005
63 #define FONTNAME_OP 0x0c26
64 #define FULLNAME_OP 0x0002
65 #define LOCAL_SUB_OP 0x0013
66 #define NOTICE_OP 0x0001
67 #define POSTSCRIPT_OP 0x0c15
68 #define PRIVATE_OP 0x0012
70 #define UNIQUEID_OP 0x000d
71 #define VERSION_OP 0x0000
72 #define WEIGHT_OP 0x0004
73 #define XUID_OP 0x000e
75 #define NUM_STD_STRINGS 391
77 typedef struct _cff_header
{
84 typedef struct _cff_index_element
{
88 } cff_index_element_t
;
90 typedef struct _cff_dict_operator
{
91 cairo_hash_entry_t base
;
93 unsigned short operator;
94 unsigned char *operand
;
97 } cff_dict_operator_t
;
99 typedef struct _cairo_cff_font
{
101 cairo_scaled_font_subset_t
*scaled_font_subset
;
102 const cairo_scaled_font_backend_t
*backend
;
106 unsigned long data_length
;
107 unsigned char *current_ptr
;
108 unsigned char *data_end
;
109 cff_header_t
*header
;
111 cairo_hash_table_t
*top_dict
;
112 cairo_hash_table_t
*private_dict
;
113 cairo_array_t strings_index
;
114 cairo_array_t charstrings_index
;
115 cairo_array_t global_sub_index
;
116 cairo_array_t local_sub_index
;
122 unsigned int num_fontdicts
;
123 cairo_hash_table_t
**fd_dict
;
124 cairo_hash_table_t
**fd_private_dict
;
125 cairo_array_t
*fd_local_sub_index
;
127 /* Subsetted Font Data */
128 char *subset_font_name
;
129 cairo_array_t charstrings_subset_index
;
130 cairo_array_t strings_subset_index
;
131 int *fdselect_subset
;
132 unsigned int num_subset_fontdicts
;
134 int *private_dict_offset
;
135 cairo_array_t output
;
139 int x_min
, y_min
, x_max
, y_max
;
144 /* Encoded integer using maximum sized encoding. This is required for
145 * operands that are later modified after encoding. */
146 static unsigned char *
147 encode_integer_max (unsigned char *p
, int i
)
151 *p
++ = (i
>> 16) & 0xff;
152 *p
++ = (i
>> 8) & 0xff;
157 static unsigned char *
158 encode_integer (unsigned char *p
, int i
)
160 if (i
>= -107 && i
<= 107) {
162 } else if (i
>= 108 && i
<= 1131) {
164 *p
++ = (i
>> 8)+ 247;
166 } else if (i
>= -1131 && i
<= -108) {
168 *p
++ = (i
>> 8)+ 251;
170 } else if (i
>= -32768 && i
<= 32767) {
172 *p
++ = (i
>> 8) & 0xff;
175 p
= encode_integer_max (p
, i
);
180 static unsigned char *
181 decode_integer (unsigned char *p
, int *integer
)
184 *integer
= (int)(p
[1]<<8 | p
[2]);
186 } else if (*p
== 29) {
187 *integer
= (int)((p
[1] << 24) | (p
[2] << 16) | (p
[3] << 8) | p
[4]);
189 } else if (*p
>= 32 && *p
<= 246) {
190 *integer
= *p
++ - 139;
191 } else if (*p
<= 250) {
192 *integer
= (p
[0] - 247) * 256 + p
[1] + 108;
194 } else if (*p
<= 254) {
195 *integer
= -(p
[0] - 251) * 256 - p
[1] - 108;
204 static unsigned char *
205 decode_operator (unsigned char *p
, unsigned short *operator)
207 unsigned short op
= 0;
218 /* return 0 if not an operand */
220 operand_length (unsigned char *p
)
222 unsigned char *begin
= p
;
230 if (*p
>= 32 && *p
<= 246)
233 if (*p
>= 247 && *p
<= 254)
237 while ((*p
& 0x0f) != 0x0f)
239 return p
- begin
+ 1;
245 static unsigned char *
246 encode_index_offset (unsigned char *p
, int offset_size
, unsigned long offset
)
248 while (--offset_size
>= 0) {
249 p
[offset_size
] = (unsigned char) (offset
& 0xff);
252 return p
+ offset_size
;
256 decode_index_offset(unsigned char *p
, int off_size
)
258 unsigned long offset
= 0;
260 while (off_size
-- > 0)
261 offset
= offset
*256 + *p
++;
266 cff_index_init (cairo_array_t
*index
)
268 _cairo_array_init (index
, sizeof (cff_index_element_t
));
271 static cairo_int_status_t
272 cff_index_read (cairo_array_t
*index
, unsigned char **ptr
, unsigned char *end_ptr
)
274 cff_index_element_t element
;
275 unsigned char *data
, *p
;
276 cairo_status_t status
;
277 int offset_size
, count
, start
, i
;
282 return CAIRO_INT_STATUS_UNSUPPORTED
;
283 count
= be16_to_cpu( *((uint16_t *)p
) );
287 if (p
+ (count
+ 1)*offset_size
> end_ptr
)
288 return CAIRO_INT_STATUS_UNSUPPORTED
;
289 data
= p
+ offset_size
*(count
+ 1) - 1;
290 start
= decode_index_offset (p
, offset_size
);
292 for (i
= 0; i
< count
; i
++) {
293 end
= decode_index_offset (p
, offset_size
);
296 return CAIRO_INT_STATUS_UNSUPPORTED
;
297 element
.length
= end
- start
;
298 element
.is_copy
= FALSE
;
299 element
.data
= data
+ start
;
300 status
= _cairo_array_append (index
, &element
);
309 return CAIRO_STATUS_SUCCESS
;
312 static cairo_status_t
313 cff_index_write (cairo_array_t
*index
, cairo_array_t
*output
)
319 cff_index_element_t
*element
;
321 unsigned char buf
[5];
322 cairo_status_t status
;
324 num_elem
= _cairo_array_num_elements (index
);
325 count
= cpu_to_be16 ((uint16_t) num_elem
);
326 status
= _cairo_array_append_multiple (output
, &count
, 2);
331 return CAIRO_STATUS_SUCCESS
;
333 /* Find maximum offset to determine offset size */
335 for (i
= 0; i
< num_elem
; i
++) {
336 element
= _cairo_array_index (index
, i
);
337 offset
+= element
->length
;
341 else if (offset
< 0x10000)
343 else if (offset
< 0x1000000)
348 buf
[0] = (unsigned char) offset_size
;
349 status
= _cairo_array_append (output
, buf
);
354 encode_index_offset (buf
, offset_size
, offset
);
355 status
= _cairo_array_append_multiple (output
, buf
, offset_size
);
359 for (i
= 0; i
< num_elem
; i
++) {
360 element
= _cairo_array_index (index
, i
);
361 offset
+= element
->length
;
362 encode_index_offset (buf
, offset_size
, offset
);
363 status
= _cairo_array_append_multiple (output
, buf
, offset_size
);
368 for (i
= 0; i
< num_elem
; i
++) {
369 element
= _cairo_array_index (index
, i
);
370 status
= _cairo_array_append_multiple (output
,
376 return CAIRO_STATUS_SUCCESS
;
379 static cairo_status_t
380 cff_index_append (cairo_array_t
*index
, unsigned char *object
, int length
)
382 cff_index_element_t element
;
384 element
.length
= length
;
385 element
.is_copy
= FALSE
;
386 element
.data
= object
;
388 return _cairo_array_append (index
, &element
);
391 static cairo_status_t
392 cff_index_append_copy (cairo_array_t
*index
,
393 const unsigned char *object
,
396 cff_index_element_t element
;
397 cairo_status_t status
;
399 element
.length
= length
;
400 element
.is_copy
= TRUE
;
401 element
.data
= malloc (element
.length
);
402 if (element
.data
== NULL
)
403 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
405 memcpy (element
.data
, object
, element
.length
);
407 status
= _cairo_array_append (index
, &element
);
413 return CAIRO_STATUS_SUCCESS
;
417 cff_index_fini (cairo_array_t
*index
)
419 cff_index_element_t
*element
;
422 for (i
= 0; i
< _cairo_array_num_elements (index
); i
++) {
423 element
= _cairo_array_index (index
, i
);
424 if (element
->is_copy
)
425 free (element
->data
);
427 _cairo_array_fini (index
);
431 _cairo_cff_dict_equal (const void *key_a
, const void *key_b
)
433 const cff_dict_operator_t
*op_a
= key_a
;
434 const cff_dict_operator_t
*op_b
= key_b
;
436 return op_a
->operator == op_b
->operator;
439 static cairo_status_t
440 cff_dict_init (cairo_hash_table_t
**dict
)
442 *dict
= _cairo_hash_table_create (_cairo_cff_dict_equal
);
444 return CAIRO_STATUS_NO_MEMORY
;
446 return CAIRO_STATUS_SUCCESS
;
450 _cairo_dict_init_key (cff_dict_operator_t
*key
, int operator)
452 key
->base
.hash
= (unsigned long) operator;
453 key
->operator = operator;
456 static cairo_status_t
457 cff_dict_create_operator (int operator,
458 unsigned char *operand
,
460 cff_dict_operator_t
**out
)
462 cff_dict_operator_t
*op
;
464 op
= malloc (sizeof (cff_dict_operator_t
));
466 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
468 _cairo_dict_init_key (op
, operator);
469 op
->operand
= malloc (operand_length
);
470 if (op
->operand
== NULL
) {
472 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
475 memcpy (op
->operand
, operand
, operand_length
);
476 op
->operand_length
= operand_length
;
477 op
->operand_offset
= -1;
480 return CAIRO_STATUS_SUCCESS
;
483 static cairo_status_t
484 cff_dict_read (cairo_hash_table_t
*dict
, unsigned char *p
, int dict_size
)
487 cairo_array_t operands
;
488 cff_dict_operator_t
*op
;
489 unsigned short operator;
490 cairo_status_t status
= CAIRO_STATUS_SUCCESS
;
494 _cairo_array_init (&operands
, 1);
496 size
= operand_length (p
);
498 status
= _cairo_array_append_multiple (&operands
, p
, size
);
504 p
= decode_operator (p
, &operator);
505 status
= cff_dict_create_operator (operator,
506 _cairo_array_index (&operands
, 0),
507 _cairo_array_num_elements (&operands
),
512 status
= _cairo_hash_table_insert (dict
, &op
->base
);
516 _cairo_array_truncate (&operands
, 0);
521 _cairo_array_fini (&operands
);
527 cff_dict_remove (cairo_hash_table_t
*dict
, unsigned short operator)
529 cff_dict_operator_t key
, *op
;
531 _cairo_dict_init_key (&key
, operator);
532 if (_cairo_hash_table_lookup (dict
, &key
.base
,
533 (cairo_hash_entry_t
**) &op
))
536 _cairo_hash_table_remove (dict
, (cairo_hash_entry_t
*) op
);
541 static unsigned char *
542 cff_dict_get_operands (cairo_hash_table_t
*dict
,
543 unsigned short operator,
546 cff_dict_operator_t key
, *op
;
548 _cairo_dict_init_key (&key
, operator);
549 if (_cairo_hash_table_lookup (dict
, &key
.base
,
550 (cairo_hash_entry_t
**) &op
))
552 *size
= op
->operand_length
;
559 static cairo_status_t
560 cff_dict_set_operands (cairo_hash_table_t
*dict
,
561 unsigned short operator,
562 unsigned char *operand
,
565 cff_dict_operator_t key
, *op
;
566 cairo_status_t status
;
568 _cairo_dict_init_key (&key
, operator);
569 if (_cairo_hash_table_lookup (dict
, &key
.base
,
570 (cairo_hash_entry_t
**) &op
))
573 op
->operand
= malloc (size
);
574 if (op
->operand
== NULL
)
575 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
577 memcpy (op
->operand
, operand
, size
);
578 op
->operand_length
= size
;
582 status
= cff_dict_create_operator (operator, operand
, size
, &op
);
586 status
= _cairo_hash_table_insert (dict
, &op
->base
);
591 return CAIRO_STATUS_SUCCESS
;
595 cff_dict_get_location (cairo_hash_table_t
*dict
,
596 unsigned short operator,
599 cff_dict_operator_t key
, *op
;
601 _cairo_dict_init_key (&key
, operator);
602 if (_cairo_hash_table_lookup (dict
, &key
.base
,
603 (cairo_hash_entry_t
**) &op
))
605 *size
= op
->operand_length
;
606 return op
->operand_offset
;
612 typedef struct _dict_write_info
{
613 cairo_array_t
*output
;
614 cairo_status_t status
;
618 cairo_dict_write_operator (cff_dict_operator_t
*op
, dict_write_info_t
*write_info
)
622 op
->operand_offset
= _cairo_array_num_elements (write_info
->output
);
623 write_info
->status
= _cairo_array_append_multiple (write_info
->output
, op
->operand
, op
->operand_length
);
624 if (write_info
->status
)
627 if (op
->operator & 0xff00) {
628 data
= op
->operator >> 8;
629 write_info
->status
= _cairo_array_append (write_info
->output
, &data
);
630 if (write_info
->status
)
633 data
= op
->operator & 0xff;
634 write_info
->status
= _cairo_array_append (write_info
->output
, &data
);
638 _cairo_dict_collect (void *entry
, void *closure
)
640 dict_write_info_t
*write_info
= closure
;
641 cff_dict_operator_t
*op
= entry
;
643 if (write_info
->status
)
646 /* The ROS operator is handled separately in cff_dict_write() */
647 if (op
->operator != ROS_OP
)
648 cairo_dict_write_operator (op
, write_info
);
651 static cairo_status_t
652 cff_dict_write (cairo_hash_table_t
*dict
, cairo_array_t
*output
)
654 dict_write_info_t write_info
;
655 cff_dict_operator_t key
, *op
;
657 write_info
.output
= output
;
658 write_info
.status
= CAIRO_STATUS_SUCCESS
;
660 /* The CFF specification requires that the Top Dict of CID fonts
661 * begin with the ROS operator. */
662 _cairo_dict_init_key (&key
, ROS_OP
);
663 if (_cairo_hash_table_lookup (dict
, &key
.base
,
664 (cairo_hash_entry_t
**) &op
))
665 cairo_dict_write_operator (op
, &write_info
);
667 _cairo_hash_table_foreach (dict
, _cairo_dict_collect
, &write_info
);
669 return write_info
.status
;
673 cff_dict_fini (cairo_hash_table_t
*dict
)
675 cff_dict_operator_t
*entry
;
678 entry
= _cairo_hash_table_random_entry (dict
, NULL
);
681 free (entry
->operand
);
682 _cairo_hash_table_remove (dict
, (cairo_hash_entry_t
*) entry
);
685 _cairo_hash_table_destroy (dict
);
688 static cairo_int_status_t
689 cairo_cff_font_read_header (cairo_cff_font_t
*font
)
691 if (font
->data_length
< sizeof (cff_header_t
))
692 return CAIRO_INT_STATUS_UNSUPPORTED
;
694 font
->header
= (cff_header_t
*) font
->data
;
695 font
->current_ptr
= font
->data
+ font
->header
->header_size
;
697 return CAIRO_STATUS_SUCCESS
;
700 static cairo_int_status_t
701 cairo_cff_font_read_name (cairo_cff_font_t
*font
)
704 cairo_int_status_t status
;
706 /* The original font name is not used in the subset. Read the name
707 * index to skip over it. */
708 cff_index_init (&index
);
709 status
= cff_index_read (&index
, &font
->current_ptr
, font
->data_end
);
710 cff_index_fini (&index
);
715 static cairo_int_status_t
716 cairo_cff_font_read_private_dict (cairo_cff_font_t
*font
,
717 cairo_hash_table_t
*private_dict
,
718 cairo_array_t
*local_sub_index
,
722 cairo_int_status_t status
;
723 unsigned char buf
[10];
724 unsigned char *end_buf
;
727 unsigned char *operand
;
730 status
= cff_dict_read (private_dict
, ptr
, size
);
734 operand
= cff_dict_get_operands (private_dict
, LOCAL_SUB_OP
, &i
);
736 decode_integer (operand
, &offset
);
738 status
= cff_index_read (local_sub_index
, &p
, font
->data_end
);
742 /* Use maximum sized encoding to reserve space for later modification. */
743 end_buf
= encode_integer_max (buf
, 0);
744 status
= cff_dict_set_operands (private_dict
, LOCAL_SUB_OP
, buf
, end_buf
- buf
);
749 return CAIRO_STATUS_SUCCESS
;
752 static cairo_int_status_t
753 cairo_cff_font_read_fdselect (cairo_cff_font_t
*font
, unsigned char *p
)
755 int type
, num_ranges
, first
, last
, fd
, i
, j
;
757 font
->fdselect
= calloc (font
->num_glyphs
, sizeof (int));
758 if (font
->fdselect
== NULL
)
759 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
764 for (i
= 0; i
< font
->num_glyphs
; i
++)
765 font
->fdselect
[i
] = *p
++;
766 } else if (type
== 3) {
767 num_ranges
= be16_to_cpu( *((uint16_t *)p
) );
769 for (i
= 0; i
< num_ranges
; i
++)
771 first
= be16_to_cpu( *((uint16_t *)p
) );
774 last
= be16_to_cpu( *((uint16_t *)p
) );
775 for (j
= first
; j
< last
; j
++)
776 font
->fdselect
[j
] = fd
;
779 return CAIRO_INT_STATUS_UNSUPPORTED
;
782 return CAIRO_STATUS_SUCCESS
;
785 static cairo_int_status_t
786 cairo_cff_font_read_cid_fontdict (cairo_cff_font_t
*font
, unsigned char *ptr
)
789 cff_index_element_t
*element
;
792 unsigned char *operand
;
794 cairo_int_status_t status
;
795 unsigned char buf
[100];
796 unsigned char *end_buf
;
798 cff_index_init (&index
);
799 status
= cff_index_read (&index
, &ptr
, font
->data_end
);
803 font
->num_fontdicts
= _cairo_array_num_elements (&index
);
805 font
->fd_dict
= calloc (sizeof (cairo_hash_table_t
*), font
->num_fontdicts
);
806 if (font
->fd_dict
== NULL
) {
807 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
811 font
->fd_private_dict
= calloc (sizeof (cairo_hash_table_t
*), font
->num_fontdicts
);
812 if (font
->fd_private_dict
== NULL
) {
813 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
817 font
->fd_local_sub_index
= calloc (sizeof (cairo_array_t
), font
->num_fontdicts
);
818 if (font
->fd_local_sub_index
== NULL
) {
819 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
823 for (i
= 0; i
< font
->num_fontdicts
; i
++) {
824 status
= cff_dict_init (&font
->fd_dict
[i
]);
828 element
= _cairo_array_index (&index
, i
);
829 status
= cff_dict_read (font
->fd_dict
[i
], element
->data
, element
->length
);
833 operand
= cff_dict_get_operands (font
->fd_dict
[i
], PRIVATE_OP
, &size
);
834 if (operand
== NULL
) {
835 status
= CAIRO_INT_STATUS_UNSUPPORTED
;
838 operand
= decode_integer (operand
, &size
);
839 decode_integer (operand
, &offset
);
840 status
= cff_dict_init (&font
->fd_private_dict
[i
]);
844 cff_index_init (&font
->fd_local_sub_index
[i
]);
845 status
= cairo_cff_font_read_private_dict (font
,
846 font
->fd_private_dict
[i
],
847 &font
->fd_local_sub_index
[i
],
853 /* Set integer operand to max value to use max size encoding to reserve
854 * space for any value later */
855 end_buf
= encode_integer_max (buf
, 0);
856 end_buf
= encode_integer_max (end_buf
, 0);
857 status
= cff_dict_set_operands (font
->fd_dict
[i
], PRIVATE_OP
, buf
, end_buf
- buf
);
862 return CAIRO_STATUS_SUCCESS
;
865 cff_index_fini (&index
);
870 static cairo_int_status_t
871 cairo_cff_font_read_top_dict (cairo_cff_font_t
*font
)
874 cff_index_element_t
*element
;
875 unsigned char buf
[20];
876 unsigned char *end_buf
;
877 unsigned char *operand
;
878 cairo_int_status_t status
;
883 cff_index_init (&index
);
884 status
= cff_index_read (&index
, &font
->current_ptr
, font
->data_end
);
888 element
= _cairo_array_index (&index
, 0);
889 status
= cff_dict_read (font
->top_dict
, element
->data
, element
->length
);
893 if (cff_dict_get_operands (font
->top_dict
, ROS_OP
, &size
) != NULL
)
896 font
->is_cid
= FALSE
;
898 operand
= cff_dict_get_operands (font
->top_dict
, CHARSTRINGS_OP
, &size
);
899 decode_integer (operand
, &offset
);
900 p
= font
->data
+ offset
;
901 status
= cff_index_read (&font
->charstrings_index
, &p
, font
->data_end
);
904 font
->num_glyphs
= _cairo_array_num_elements (&font
->charstrings_index
);
907 operand
= cff_dict_get_operands (font
->top_dict
, FDSELECT_OP
, &size
);
908 decode_integer (operand
, &offset
);
909 status
= cairo_cff_font_read_fdselect (font
, font
->data
+ offset
);
913 operand
= cff_dict_get_operands (font
->top_dict
, FDARRAY_OP
, &size
);
914 decode_integer (operand
, &offset
);
915 status
= cairo_cff_font_read_cid_fontdict (font
, font
->data
+ offset
);
919 operand
= cff_dict_get_operands (font
->top_dict
, PRIVATE_OP
, &size
);
920 operand
= decode_integer (operand
, &size
);
921 decode_integer (operand
, &offset
);
922 status
= cairo_cff_font_read_private_dict (font
,
924 &font
->local_sub_index
,
931 /* Use maximum sized encoding to reserve space for later modification. */
932 end_buf
= encode_integer_max (buf
, 0);
933 status
= cff_dict_set_operands (font
->top_dict
,
934 CHARSTRINGS_OP
, buf
, end_buf
- buf
);
938 status
= cff_dict_set_operands (font
->top_dict
,
939 FDSELECT_OP
, buf
, end_buf
- buf
);
943 status
= cff_dict_set_operands (font
->top_dict
,
944 FDARRAY_OP
, buf
, end_buf
- buf
);
948 status
= cff_dict_set_operands (font
->top_dict
,
949 CHARSET_OP
, buf
, end_buf
- buf
);
953 cff_dict_remove (font
->top_dict
, ENCODING_OP
);
954 cff_dict_remove (font
->top_dict
, PRIVATE_OP
);
956 /* Remove the unique identifier operators as the subsetted font is
957 * not the same is the original font. */
958 cff_dict_remove (font
->top_dict
, UNIQUEID_OP
);
959 cff_dict_remove (font
->top_dict
, XUID_OP
);
962 cff_index_fini (&index
);
967 static cairo_int_status_t
968 cairo_cff_font_read_strings (cairo_cff_font_t
*font
)
970 return cff_index_read (&font
->strings_index
, &font
->current_ptr
, font
->data_end
);
973 static cairo_int_status_t
974 cairo_cff_font_read_global_subroutines (cairo_cff_font_t
*font
)
976 return cff_index_read (&font
->global_sub_index
, &font
->current_ptr
, font
->data_end
);
979 typedef cairo_int_status_t
980 (*font_read_t
) (cairo_cff_font_t
*font
);
982 static const font_read_t font_read_funcs
[] = {
983 cairo_cff_font_read_header
,
984 cairo_cff_font_read_name
,
985 cairo_cff_font_read_top_dict
,
986 cairo_cff_font_read_strings
,
987 cairo_cff_font_read_global_subroutines
,
990 static cairo_int_status_t
991 cairo_cff_font_read_font (cairo_cff_font_t
*font
)
993 cairo_int_status_t status
;
996 for (i
= 0; i
< ARRAY_LENGTH (font_read_funcs
); i
++) {
997 status
= font_read_funcs
[i
] (font
);
1002 return CAIRO_STATUS_SUCCESS
;
1005 static cairo_status_t
1006 cairo_cff_font_set_ros_strings (cairo_cff_font_t
*font
)
1008 cairo_status_t status
;
1009 unsigned char buf
[30];
1012 const char *registry
= "Adobe";
1013 const char *ordering
= "Identity";
1015 sid1
= NUM_STD_STRINGS
+ _cairo_array_num_elements (&font
->strings_subset_index
);
1016 status
= cff_index_append_copy (&font
->strings_subset_index
,
1017 (unsigned char *)registry
,
1022 sid2
= NUM_STD_STRINGS
+ _cairo_array_num_elements (&font
->strings_subset_index
);
1023 status
= cff_index_append_copy (&font
->strings_subset_index
,
1024 (unsigned char *)ordering
,
1029 p
= encode_integer (buf
, sid1
);
1030 p
= encode_integer (p
, sid2
);
1031 p
= encode_integer (p
, 0);
1032 status
= cff_dict_set_operands (font
->top_dict
, ROS_OP
, buf
, p
- buf
);
1036 p
= encode_integer (buf
, font
->scaled_font_subset
->num_glyphs
);
1037 status
= cff_dict_set_operands (font
->top_dict
, CIDCOUNT_OP
, buf
, p
- buf
);
1041 return CAIRO_STATUS_SUCCESS
;
1044 static cairo_status_t
1045 cairo_cff_font_subset_dict_string(cairo_cff_font_t
*font
,
1046 cairo_hash_table_t
*dict
,
1052 unsigned char buf
[100];
1053 cff_index_element_t
*element
;
1054 cairo_status_t status
;
1056 p
= cff_dict_get_operands (dict
, operator, &size
);
1058 return CAIRO_STATUS_SUCCESS
;
1060 decode_integer (p
, &sid
);
1061 if (sid
< NUM_STD_STRINGS
)
1062 return CAIRO_STATUS_SUCCESS
;
1064 element
= _cairo_array_index (&font
->strings_index
, sid
- NUM_STD_STRINGS
);
1065 sid
= NUM_STD_STRINGS
+ _cairo_array_num_elements (&font
->strings_subset_index
);
1066 status
= cff_index_append (&font
->strings_subset_index
, element
->data
, element
->length
);
1070 p
= encode_integer (buf
, sid
);
1071 status
= cff_dict_set_operands (dict
, operator, buf
, p
- buf
);
1075 return CAIRO_STATUS_SUCCESS
;
1078 static const int dict_strings
[] = {
1090 static cairo_status_t
1091 cairo_cff_font_subset_dict_strings (cairo_cff_font_t
*font
,
1092 cairo_hash_table_t
*dict
)
1094 cairo_status_t status
;
1097 for (i
= 0; i
< ARRAY_LENGTH (dict_strings
); i
++) {
1098 status
= cairo_cff_font_subset_dict_string (font
, dict
, dict_strings
[i
]);
1103 return CAIRO_STATUS_SUCCESS
;
1106 static cairo_status_t
1107 cairo_cff_font_subset_charstrings (cairo_cff_font_t
*font
)
1109 cff_index_element_t
*element
;
1111 cairo_status_t status
;
1113 for (i
= 0; i
< font
->scaled_font_subset
->num_glyphs
; i
++) {
1114 element
= _cairo_array_index (&font
->charstrings_index
,
1115 font
->scaled_font_subset
->glyphs
[i
]);
1116 status
= cff_index_append (&font
->charstrings_subset_index
,
1123 return CAIRO_STATUS_SUCCESS
;
1126 static cairo_status_t
1127 cairo_cff_font_subset_fontdict (cairo_cff_font_t
*font
)
1133 font
->fdselect_subset
= calloc (font
->scaled_font_subset
->num_glyphs
,
1135 if (font
->fdselect_subset
== NULL
)
1136 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1138 font
->fd_subset_map
= calloc (font
->num_fontdicts
, sizeof (int));
1139 if (font
->fd_subset_map
== NULL
)
1140 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1142 font
->private_dict_offset
= calloc (font
->num_fontdicts
, sizeof (int));
1143 if (font
->private_dict_offset
== NULL
)
1144 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1146 reverse_map
= calloc (font
->num_fontdicts
, sizeof (int));
1147 if (reverse_map
== NULL
)
1148 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1150 for (i
= 0; i
< font
->num_fontdicts
; i
++)
1151 reverse_map
[i
] = -1;
1153 font
->num_subset_fontdicts
= 0;
1154 for (i
= 0; i
< font
->scaled_font_subset
->num_glyphs
; i
++) {
1155 fd
= font
->fdselect
[font
->scaled_font_subset
->glyphs
[i
]];
1156 if (reverse_map
[fd
] < 0) {
1157 font
->fd_subset_map
[font
->num_subset_fontdicts
] = fd
;
1158 reverse_map
[fd
] = font
->num_subset_fontdicts
++;
1160 font
->fdselect_subset
[i
] = reverse_map
[fd
];
1165 return CAIRO_STATUS_SUCCESS
;
1168 static cairo_status_t
1169 cairo_cff_font_create_cid_fontdict (cairo_cff_font_t
*font
)
1171 unsigned char buf
[100];
1172 unsigned char *end_buf
;
1173 cairo_status_t status
;
1175 font
->num_fontdicts
= 1;
1176 font
->fd_dict
= malloc (sizeof (cairo_hash_table_t
*));
1177 if (font
->fd_dict
== NULL
)
1178 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1180 if (cff_dict_init (&font
->fd_dict
[0])) {
1181 free (font
->fd_dict
);
1182 font
->fd_dict
= NULL
;
1183 font
->num_fontdicts
= 0;
1184 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1187 font
->fd_subset_map
= malloc (sizeof (int));
1188 if (font
->fd_subset_map
== NULL
)
1189 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1191 font
->private_dict_offset
= malloc (sizeof (int));
1192 if (font
->private_dict_offset
== NULL
)
1193 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1195 font
->fd_subset_map
[0] = 0;
1196 font
->num_subset_fontdicts
= 1;
1198 /* Set integer operand to max value to use max size encoding to reserve
1199 * space for any value later */
1200 end_buf
= encode_integer_max (buf
, 0);
1201 end_buf
= encode_integer_max (end_buf
, 0);
1202 status
= cff_dict_set_operands (font
->fd_dict
[0], PRIVATE_OP
, buf
, end_buf
- buf
);
1206 return CAIRO_STATUS_SUCCESS
;
1209 static cairo_status_t
1210 cairo_cff_font_subset_strings (cairo_cff_font_t
*font
)
1212 cairo_status_t status
;
1215 status
= cairo_cff_font_subset_dict_strings (font
, font
->top_dict
);
1220 for (i
= 0; i
< font
->num_subset_fontdicts
; i
++) {
1221 status
= cairo_cff_font_subset_dict_strings (font
, font
->fd_dict
[font
->fd_subset_map
[i
]]);
1225 status
= cairo_cff_font_subset_dict_strings (font
, font
->fd_private_dict
[font
->fd_subset_map
[i
]]);
1230 status
= cairo_cff_font_subset_dict_strings (font
, font
->private_dict
);
1236 static cairo_status_t
1237 cairo_cff_font_subset_font (cairo_cff_font_t
*font
)
1239 cairo_status_t status
;
1241 status
= cairo_cff_font_set_ros_strings (font
);
1245 status
= cairo_cff_font_subset_charstrings (font
);
1250 status
= cairo_cff_font_subset_fontdict (font
);
1252 status
= cairo_cff_font_create_cid_fontdict (font
);
1256 status
= cairo_cff_font_subset_strings (font
);
1263 /* Set the operand of the specified operator in the (already written)
1264 * top dict to point to the current position in the output
1265 * array. Operands updated with this function must have previously
1266 * been encoded with the 5-byte (max) integer encoding. */
1268 cairo_cff_font_set_topdict_operator_to_cur_pos (cairo_cff_font_t
*font
,
1274 unsigned char buf
[10];
1275 unsigned char *buf_end
;
1276 unsigned char *op_ptr
;
1278 cur_pos
= _cairo_array_num_elements (&font
->output
);
1279 buf_end
= encode_integer_max (buf
, cur_pos
);
1280 offset
= cff_dict_get_location (font
->top_dict
, operator, &size
);
1281 assert (offset
> 0);
1282 op_ptr
= _cairo_array_index (&font
->output
, offset
);
1283 memcpy (op_ptr
, buf
, buf_end
- buf
);
1286 static cairo_status_t
1287 cairo_cff_font_write_header (cairo_cff_font_t
*font
)
1289 return _cairo_array_append_multiple (&font
->output
,
1291 font
->header
->header_size
);
1294 static cairo_status_t
1295 cairo_cff_font_write_name (cairo_cff_font_t
*font
)
1297 cairo_status_t status
= CAIRO_STATUS_SUCCESS
;
1298 cairo_array_t index
;
1300 cff_index_init (&index
);
1302 status
= cff_index_append_copy (&index
,
1303 (unsigned char *) font
->subset_font_name
,
1304 strlen(font
->subset_font_name
));
1308 status
= cff_index_write (&index
, &font
->output
);
1313 cff_index_fini (&index
);
1318 static cairo_status_t
1319 cairo_cff_font_write_top_dict (cairo_cff_font_t
*font
)
1322 unsigned char buf
[10];
1325 int dict_start
, dict_size
;
1326 int offset_size
= 4;
1327 cairo_status_t status
;
1329 /* Write an index containing the top dict */
1331 count
= cpu_to_be16 (1);
1332 status
= _cairo_array_append_multiple (&font
->output
, &count
, 2);
1335 buf
[0] = offset_size
;
1336 status
= _cairo_array_append (&font
->output
, buf
);
1339 encode_index_offset (buf
, offset_size
, 1);
1340 status
= _cairo_array_append_multiple (&font
->output
, buf
, offset_size
);
1344 /* Reserve space for last element of offset array and update after
1345 * dict is written */
1346 offset_index
= _cairo_array_num_elements (&font
->output
);
1347 status
= _cairo_array_append_multiple (&font
->output
, buf
, offset_size
);
1351 dict_start
= _cairo_array_num_elements (&font
->output
);
1352 status
= cff_dict_write (font
->top_dict
, &font
->output
);
1355 dict_size
= _cairo_array_num_elements (&font
->output
) - dict_start
;
1357 encode_index_offset (buf
, offset_size
, dict_size
+ 1);
1358 p
= _cairo_array_index (&font
->output
, offset_index
);
1359 memcpy (p
, buf
, offset_size
);
1361 return CAIRO_STATUS_SUCCESS
;
1364 static cairo_status_t
1365 cairo_cff_font_write_strings (cairo_cff_font_t
*font
)
1367 return cff_index_write (&font
->strings_subset_index
, &font
->output
);
1370 static cairo_status_t
1371 cairo_cff_font_write_global_subrs (cairo_cff_font_t
*font
)
1373 return cff_index_write (&font
->global_sub_index
, &font
->output
);
1376 static cairo_status_t
1377 cairo_cff_font_write_fdselect (cairo_cff_font_t
*font
)
1381 cairo_int_status_t status
;
1383 cairo_cff_font_set_topdict_operator_to_cur_pos (font
, FDSELECT_OP
);
1387 status
= _cairo_array_append (&font
->output
, &data
);
1391 for (i
= 0; i
< font
->scaled_font_subset
->num_glyphs
; i
++) {
1392 data
= font
->fdselect_subset
[i
];
1393 status
= _cairo_array_append (&font
->output
, &data
);
1401 status
= _cairo_array_grow_by (&font
->output
, 9);
1406 status
= _cairo_array_append (&font
->output
, &byte
);
1407 assert (status
== CAIRO_STATUS_SUCCESS
);
1409 word
= cpu_to_be16 (1);
1410 status
= _cairo_array_append_multiple (&font
->output
, &word
, 2);
1411 assert (status
== CAIRO_STATUS_SUCCESS
);
1413 word
= cpu_to_be16 (0);
1414 status
= _cairo_array_append_multiple (&font
->output
, &word
, 2);
1415 assert (status
== CAIRO_STATUS_SUCCESS
);
1418 status
= _cairo_array_append (&font
->output
, &byte
);
1419 assert (status
== CAIRO_STATUS_SUCCESS
);
1421 word
= cpu_to_be16 (font
->scaled_font_subset
->num_glyphs
);
1422 status
= _cairo_array_append_multiple (&font
->output
, &word
, 2);
1423 assert (status
== CAIRO_STATUS_SUCCESS
);
1426 return CAIRO_STATUS_SUCCESS
;
1429 static cairo_status_t
1430 cairo_cff_font_write_charset (cairo_cff_font_t
*font
)
1434 cairo_status_t status
;
1436 cairo_cff_font_set_topdict_operator_to_cur_pos (font
, CHARSET_OP
);
1437 status
= _cairo_array_grow_by (&font
->output
, 5);
1442 status
= _cairo_array_append (&font
->output
, &byte
);
1443 assert (status
== CAIRO_STATUS_SUCCESS
);
1445 word
= cpu_to_be16 (1);
1446 status
= _cairo_array_append_multiple (&font
->output
, &word
, 2);
1447 assert (status
== CAIRO_STATUS_SUCCESS
);
1449 word
= cpu_to_be16 (font
->scaled_font_subset
->num_glyphs
- 2);
1450 status
= _cairo_array_append_multiple (&font
->output
, &word
, 2);
1451 assert (status
== CAIRO_STATUS_SUCCESS
);
1453 return CAIRO_STATUS_SUCCESS
;
1456 static cairo_status_t
1457 cairo_cff_font_write_charstrings (cairo_cff_font_t
*font
)
1459 cairo_cff_font_set_topdict_operator_to_cur_pos (font
, CHARSTRINGS_OP
);
1461 return cff_index_write (&font
->charstrings_subset_index
, &font
->output
);
1464 static cairo_status_t
1465 cairo_cff_font_write_cid_fontdict (cairo_cff_font_t
*font
)
1468 cairo_int_status_t status
;
1469 uint32_t *offset_array
;
1472 uint8_t offset_size
= 4;
1474 cairo_cff_font_set_topdict_operator_to_cur_pos (font
, FDARRAY_OP
);
1475 count
= cpu_to_be16 (font
->num_subset_fontdicts
);
1476 status
= _cairo_array_append_multiple (&font
->output
, &count
, sizeof (uint16_t));
1479 status
= _cairo_array_append (&font
->output
, &offset_size
);
1482 status
= _cairo_array_allocate (&font
->output
,
1483 (font
->num_subset_fontdicts
+ 1)*offset_size
,
1484 (void **) &offset_array
);
1487 offset_base
= _cairo_array_num_elements (&font
->output
) - 1;
1488 *offset_array
++ = cpu_to_be32(1);
1489 for (i
= 0; i
< font
->num_subset_fontdicts
; i
++) {
1490 status
= cff_dict_write (font
->fd_dict
[font
->fd_subset_map
[i
]],
1494 *offset_array
++ = cpu_to_be32(_cairo_array_num_elements (&font
->output
) - offset_base
);
1497 return CAIRO_STATUS_SUCCESS
;
1500 static cairo_status_t
1501 cairo_cff_font_write_private_dict (cairo_cff_font_t
*font
,
1503 cairo_hash_table_t
*parent_dict
,
1504 cairo_hash_table_t
*private_dict
)
1508 unsigned char buf
[10];
1509 unsigned char *buf_end
;
1511 cairo_status_t status
;
1513 /* Write private dict and update offset and size in top dict */
1514 font
->private_dict_offset
[dict_num
] = _cairo_array_num_elements (&font
->output
);
1515 status
= cff_dict_write (private_dict
, &font
->output
);
1519 size
= _cairo_array_num_elements (&font
->output
) - font
->private_dict_offset
[dict_num
];
1520 /* private entry has two operands - size and offset */
1521 buf_end
= encode_integer_max (buf
, size
);
1522 buf_end
= encode_integer_max (buf_end
, font
->private_dict_offset
[dict_num
]);
1523 offset
= cff_dict_get_location (parent_dict
, PRIVATE_OP
, &size
);
1524 assert (offset
> 0);
1525 p
= _cairo_array_index (&font
->output
, offset
);
1526 memcpy (p
, buf
, buf_end
- buf
);
1528 return CAIRO_STATUS_SUCCESS
;
1531 static cairo_status_t
1532 cairo_cff_font_write_local_sub (cairo_cff_font_t
*font
,
1534 cairo_hash_table_t
*private_dict
,
1535 cairo_array_t
*local_sub_index
)
1539 unsigned char buf
[10];
1540 unsigned char *buf_end
;
1542 cairo_status_t status
;
1544 if (_cairo_array_num_elements (local_sub_index
) > 0) {
1545 /* Write local subroutines and update offset in private
1546 * dict. Local subroutines offset is relative to start of
1548 offset
= _cairo_array_num_elements (&font
->output
) - font
->private_dict_offset
[dict_num
];
1549 buf_end
= encode_integer_max (buf
, offset
);
1550 offset
= cff_dict_get_location (private_dict
, LOCAL_SUB_OP
, &size
);
1551 assert (offset
> 0);
1552 p
= _cairo_array_index (&font
->output
, offset
);
1553 memcpy (p
, buf
, buf_end
- buf
);
1554 status
= cff_index_write (local_sub_index
, &font
->output
);
1559 return CAIRO_STATUS_SUCCESS
;
1563 static cairo_status_t
1564 cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t
*font
)
1567 cairo_int_status_t status
;
1570 for (i
= 0; i
< font
->num_subset_fontdicts
; i
++) {
1571 status
= cairo_cff_font_write_private_dict (
1574 font
->fd_dict
[font
->fd_subset_map
[i
]],
1575 font
->fd_private_dict
[font
->fd_subset_map
[i
]]);
1580 for (i
= 0; i
< font
->num_subset_fontdicts
; i
++) {
1581 status
= cairo_cff_font_write_local_sub (
1584 font
->fd_private_dict
[font
->fd_subset_map
[i
]],
1585 &font
->fd_local_sub_index
[font
->fd_subset_map
[i
]]);
1590 status
= cairo_cff_font_write_private_dict (font
,
1593 font
->private_dict
);
1597 status
= cairo_cff_font_write_local_sub (font
,
1600 &font
->local_sub_index
);
1605 return CAIRO_STATUS_SUCCESS
;
1608 typedef cairo_status_t
1609 (*font_write_t
) (cairo_cff_font_t
*font
);
1611 static const font_write_t font_write_funcs
[] = {
1612 cairo_cff_font_write_header
,
1613 cairo_cff_font_write_name
,
1614 cairo_cff_font_write_top_dict
,
1615 cairo_cff_font_write_strings
,
1616 cairo_cff_font_write_global_subrs
,
1617 cairo_cff_font_write_charset
,
1618 cairo_cff_font_write_fdselect
,
1619 cairo_cff_font_write_charstrings
,
1620 cairo_cff_font_write_cid_fontdict
,
1621 cairo_cff_font_write_cid_private_dict_and_local_sub
,
1624 static cairo_status_t
1625 cairo_cff_font_write_subset (cairo_cff_font_t
*font
)
1627 cairo_int_status_t status
;
1630 for (i
= 0; i
< ARRAY_LENGTH (font_write_funcs
); i
++) {
1631 status
= font_write_funcs
[i
] (font
);
1636 return CAIRO_STATUS_SUCCESS
;
1639 static cairo_int_status_t
1640 cairo_cff_font_generate (cairo_cff_font_t
*font
,
1642 unsigned long *length
)
1644 cairo_int_status_t status
;
1646 status
= cairo_cff_font_read_font (font
);
1650 status
= cairo_cff_font_subset_font (font
);
1654 status
= cairo_cff_font_write_subset (font
);
1658 *data
= _cairo_array_index (&font
->output
, 0);
1659 *length
= _cairo_array_num_elements (&font
->output
);
1661 return CAIRO_STATUS_SUCCESS
;
1664 static cairo_int_status_t
1665 cairo_cff_font_create_set_widths (cairo_cff_font_t
*font
)
1668 unsigned long long_entry_size
;
1669 unsigned long short_entry_size
;
1673 unsigned char buf
[10];
1675 cairo_int_status_t status
;
1677 size
= sizeof (tt_hhea_t
);
1678 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
1680 (unsigned char*) &hhea
, &size
);
1683 num_hmetrics
= be16_to_cpu (hhea
.num_hmetrics
);
1685 for (i
= 1; i
< font
->scaled_font_subset
->num_glyphs
; i
++) {
1686 glyph_index
= font
->scaled_font_subset
->glyphs
[i
];
1687 long_entry_size
= 2 * sizeof (int16_t);
1688 short_entry_size
= sizeof (int16_t);
1689 if (glyph_index
< num_hmetrics
) {
1690 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
1692 glyph_index
* long_entry_size
,
1693 buf
, &short_entry_size
);
1699 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
1701 (num_hmetrics
- 1) * long_entry_size
,
1702 buf
, &short_entry_size
);
1706 font
->widths
[i
] = be16_to_cpu (*((int16_t*)buf
));
1709 return CAIRO_STATUS_SUCCESS
;
1712 static cairo_int_status_t
1713 _cairo_cff_font_create (cairo_scaled_font_subset_t
*scaled_font_subset
,
1714 cairo_cff_font_t
**font_return
,
1715 const char *subset_name
)
1717 const cairo_scaled_font_backend_t
*backend
;
1718 cairo_status_t status
;
1719 cairo_cff_font_t
*font
;
1723 tt_name_record_t
*record
;
1724 unsigned long size
, data_length
;
1727 backend
= scaled_font_subset
->scaled_font
->backend
;
1728 if (!backend
->load_truetype_table
)
1729 return CAIRO_INT_STATUS_UNSUPPORTED
;
1732 status
= backend
->load_truetype_table( scaled_font_subset
->scaled_font
,
1733 TT_TAG_CFF
, 0, NULL
, &data_length
);
1737 size
= sizeof (tt_head_t
);
1738 status
= backend
->load_truetype_table (scaled_font_subset
->scaled_font
,
1740 (unsigned char *) &head
, &size
);
1744 size
= sizeof (tt_hhea_t
);
1745 status
= backend
->load_truetype_table (scaled_font_subset
->scaled_font
,
1747 (unsigned char *) &hhea
, &size
);
1752 status
= backend
->load_truetype_table (scaled_font_subset
->scaled_font
,
1753 TT_TAG_hmtx
, 0, NULL
, &size
);
1758 status
= backend
->load_truetype_table (scaled_font_subset
->scaled_font
,
1759 TT_TAG_name
, 0, NULL
, &size
);
1763 name
= malloc (size
);
1765 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1767 status
= backend
->load_truetype_table (scaled_font_subset
->scaled_font
,
1769 (unsigned char *) name
, &size
);
1773 font
= malloc (sizeof (cairo_cff_font_t
));
1775 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1779 font
->backend
= backend
;
1780 font
->scaled_font_subset
= scaled_font_subset
;
1782 _cairo_array_init (&font
->output
, sizeof (char));
1783 status
= _cairo_array_grow_by (&font
->output
, 4096);
1787 font
->subset_font_name
= strdup (subset_name
);
1788 if (font
->subset_font_name
== NULL
) {
1789 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1792 font
->x_min
= (int16_t) be16_to_cpu (head
.x_min
);
1793 font
->y_min
= (int16_t) be16_to_cpu (head
.y_min
);
1794 font
->x_max
= (int16_t) be16_to_cpu (head
.x_max
);
1795 font
->y_max
= (int16_t) be16_to_cpu (head
.y_max
);
1796 font
->ascent
= (int16_t) be16_to_cpu (hhea
.ascender
);
1797 font
->descent
= (int16_t) be16_to_cpu (hhea
.descender
);
1799 /* Extract the font name from the name table. At present this
1800 * just looks for the Mac platform/Roman encoded font name. It
1801 * should be extended to use any suitable font name in the
1802 * name table. If the mac/roman font name is not found a
1803 * CairoFont-x-y name is created.
1805 font
->font_name
= NULL
;
1806 for (i
= 0; i
< be16_to_cpu(name
->num_records
); i
++) {
1807 record
= &(name
->records
[i
]);
1808 if ((be16_to_cpu (record
->platform
) == 1) &&
1809 (be16_to_cpu (record
->encoding
) == 0) &&
1810 (be16_to_cpu (record
->name
) == 4)) {
1811 font
->font_name
= malloc (be16_to_cpu(record
->length
) + 1);
1812 if (font
->font_name
) {
1813 strncpy(font
->font_name
,
1814 ((char*)name
) + be16_to_cpu (name
->strings_offset
) + be16_to_cpu (record
->offset
),
1815 be16_to_cpu (record
->length
));
1816 font
->font_name
[be16_to_cpu (record
->length
)] = 0;
1822 if (font
->font_name
== NULL
) {
1823 font
->font_name
= malloc (30);
1824 if (font
->font_name
== NULL
) {
1825 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1828 snprintf(font
->font_name
, 30, "CairoFont-%u-%u",
1829 scaled_font_subset
->font_id
,
1830 scaled_font_subset
->subset_id
);
1833 for (i
= 0, j
= 0; font
->font_name
[j
]; j
++) {
1834 if (font
->font_name
[j
] == ' ')
1836 font
->font_name
[i
++] = font
->font_name
[j
];
1838 font
->font_name
[i
] = '\0';
1840 font
->widths
= calloc (font
->scaled_font_subset
->num_glyphs
, sizeof (int));
1841 if (font
->widths
== NULL
) {
1842 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1846 status
= cairo_cff_font_create_set_widths (font
);
1850 font
->data_length
= data_length
;
1851 font
->data
= malloc (data_length
);
1852 if (font
->data
== NULL
) {
1853 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1856 status
= font
->backend
->load_truetype_table ( font
->scaled_font_subset
->scaled_font
,
1857 TT_TAG_CFF
, 0, font
->data
,
1858 &font
->data_length
);
1862 font
->data_end
= font
->data
+ font
->data_length
;
1864 status
= cff_dict_init (&font
->top_dict
);
1868 status
= cff_dict_init (&font
->private_dict
);
1872 cff_index_init (&font
->strings_index
);
1873 cff_index_init (&font
->charstrings_index
);
1874 cff_index_init (&font
->global_sub_index
);
1875 cff_index_init (&font
->local_sub_index
);
1876 cff_index_init (&font
->charstrings_subset_index
);
1877 cff_index_init (&font
->strings_subset_index
);
1878 font
->fdselect
= NULL
;
1879 font
->fd_dict
= NULL
;
1880 font
->fd_private_dict
= NULL
;
1881 font
->fd_local_sub_index
= NULL
;
1882 font
->fdselect_subset
= NULL
;
1883 font
->fd_subset_map
= NULL
;
1884 font
->private_dict_offset
= NULL
;
1887 *font_return
= font
;
1889 return CAIRO_STATUS_SUCCESS
;
1892 _cairo_hash_table_destroy (font
->top_dict
);
1896 free (font
->widths
);
1898 free (font
->font_name
);
1900 free (font
->subset_font_name
);
1902 _cairo_array_fini (&font
->output
);
1910 cairo_cff_font_destroy (cairo_cff_font_t
*font
)
1914 free (font
->widths
);
1915 free (font
->font_name
);
1916 free (font
->subset_font_name
);
1917 _cairo_array_fini (&font
->output
);
1918 cff_dict_fini (font
->top_dict
);
1919 cff_dict_fini (font
->private_dict
);
1920 cff_index_fini (&font
->strings_index
);
1921 cff_index_fini (&font
->charstrings_index
);
1922 cff_index_fini (&font
->global_sub_index
);
1923 cff_index_fini (&font
->local_sub_index
);
1924 cff_index_fini (&font
->charstrings_subset_index
);
1925 cff_index_fini (&font
->strings_subset_index
);
1927 /* If we bailed out early as a result of an error some of the
1928 * following cairo_cff_font_t members may still be NULL */
1929 if (font
->fd_dict
) {
1930 for (i
= 0; i
< font
->num_fontdicts
; i
++) {
1931 if (font
->fd_dict
[i
])
1932 cff_dict_fini (font
->fd_dict
[i
]);
1934 free (font
->fd_dict
);
1936 if (font
->fd_subset_map
)
1937 free (font
->fd_subset_map
);
1938 if (font
->private_dict_offset
)
1939 free (font
->private_dict_offset
);
1943 free (font
->fdselect
);
1944 if (font
->fdselect_subset
)
1945 free (font
->fdselect_subset
);
1946 if (font
->fd_private_dict
) {
1947 for (i
= 0; i
< font
->num_fontdicts
; i
++) {
1948 if (font
->fd_private_dict
[i
])
1949 cff_dict_fini (font
->fd_private_dict
[i
]);
1951 free (font
->fd_private_dict
);
1953 if (font
->fd_local_sub_index
) {
1954 for (i
= 0; i
< font
->num_fontdicts
; i
++)
1955 cff_index_fini (&font
->fd_local_sub_index
[i
]);
1956 free (font
->fd_local_sub_index
);
1967 _cairo_cff_subset_init (cairo_cff_subset_t
*cff_subset
,
1968 const char *subset_name
,
1969 cairo_scaled_font_subset_t
*font_subset
)
1971 cairo_cff_font_t
*font
= NULL
; /* squelch bogus compiler warning */
1972 cairo_status_t status
;
1973 const char *data
= NULL
; /* squelch bogus compiler warning */
1974 unsigned long length
= 0; /* squelch bogus compiler warning */
1977 status
= _cairo_cff_font_create (font_subset
, &font
, subset_name
);
1981 status
= cairo_cff_font_generate (font
, &data
, &length
);
1985 cff_subset
->base_font
= strdup (font
->font_name
);
1986 if (cff_subset
->base_font
== NULL
) {
1987 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1991 cff_subset
->widths
= calloc (sizeof (int), font
->scaled_font_subset
->num_glyphs
);
1992 if (cff_subset
->widths
== NULL
) {
1993 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1996 for (i
= 0; i
< font
->scaled_font_subset
->num_glyphs
; i
++)
1997 cff_subset
->widths
[i
] = font
->widths
[i
];
1999 cff_subset
->x_min
= font
->x_min
;
2000 cff_subset
->y_min
= font
->y_min
;
2001 cff_subset
->x_max
= font
->x_max
;
2002 cff_subset
->y_max
= font
->y_max
;
2003 cff_subset
->ascent
= font
->ascent
;
2004 cff_subset
->descent
= font
->descent
;
2006 cff_subset
->data
= malloc (length
);
2007 if (cff_subset
->data
== NULL
) {
2008 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2012 memcpy (cff_subset
->data
, data
, length
);
2013 cff_subset
->data_length
= length
;
2015 cairo_cff_font_destroy (font
);
2017 return CAIRO_STATUS_SUCCESS
;
2020 free (cff_subset
->widths
);
2022 free (cff_subset
->base_font
);
2024 cairo_cff_font_destroy (font
);
2030 _cairo_cff_subset_fini (cairo_cff_subset_t
*subset
)
2032 free (subset
->base_font
);
2033 free (subset
->widths
);
2034 free (subset
->data
);
2037 static cairo_int_status_t
2038 _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t
*scaled_font_subset
,
2039 cairo_cff_font_t
**font_return
,
2040 const char *subset_name
)
2042 cairo_status_t status
;
2043 cairo_cff_font_t
*font
;
2045 font
= malloc (sizeof (cairo_cff_font_t
));
2047 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2049 font
->backend
= NULL
;
2050 font
->scaled_font_subset
= scaled_font_subset
;
2052 _cairo_array_init (&font
->output
, sizeof (char));
2053 status
= _cairo_array_grow_by (&font
->output
, 4096);
2057 font
->subset_font_name
= strdup (subset_name
);
2058 if (font
->subset_font_name
== NULL
) {
2059 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2063 font
->font_name
= strdup (subset_name
);
2064 if (font
->subset_font_name
== NULL
) {
2065 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2076 font
->widths
= calloc (font
->scaled_font_subset
->num_glyphs
, sizeof (int));
2077 if (font
->widths
== NULL
) {
2078 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2082 font
->data_length
= 0;
2084 font
->data_end
= NULL
;
2086 status
= cff_dict_init (&font
->top_dict
);
2090 status
= cff_dict_init (&font
->private_dict
);
2094 cff_index_init (&font
->strings_index
);
2095 cff_index_init (&font
->charstrings_index
);
2096 cff_index_init (&font
->global_sub_index
);
2097 cff_index_init (&font
->local_sub_index
);
2098 cff_index_init (&font
->charstrings_subset_index
);
2099 cff_index_init (&font
->strings_subset_index
);
2100 font
->fdselect
= NULL
;
2101 font
->fd_dict
= NULL
;
2102 font
->fd_private_dict
= NULL
;
2103 font
->fd_local_sub_index
= NULL
;
2104 font
->fdselect_subset
= NULL
;
2105 font
->fd_subset_map
= NULL
;
2106 font
->private_dict_offset
= NULL
;
2108 *font_return
= font
;
2110 return CAIRO_STATUS_SUCCESS
;
2113 _cairo_hash_table_destroy (font
->top_dict
);
2115 free (font
->widths
);
2117 free (font
->font_name
);
2119 free (font
->subset_font_name
);
2121 _cairo_array_fini (&font
->output
);
2126 static cairo_int_status_t
2127 cairo_cff_font_fallback_generate (cairo_cff_font_t
*font
,
2128 cairo_type2_charstrings_t
*type2_subset
,
2130 unsigned long *length
)
2132 cairo_int_status_t status
;
2133 cff_header_t header
;
2134 cairo_array_t
*charstring
;
2135 unsigned char buf
[40];
2136 unsigned char *end_buf
;
2142 header
.header_size
= 4;
2143 header
.offset_size
= 4;
2144 font
->header
= &header
;
2146 /* Create Top Dict */
2147 font
->is_cid
= FALSE
;
2148 end_buf
= encode_integer (buf
, type2_subset
->x_min
);
2149 end_buf
= encode_integer (end_buf
, type2_subset
->y_min
);
2150 end_buf
= encode_integer (end_buf
, type2_subset
->x_max
);
2151 end_buf
= encode_integer (end_buf
, type2_subset
->y_max
);
2152 status
= cff_dict_set_operands (font
->top_dict
,
2153 FONTBBOX_OP
, buf
, end_buf
- buf
);
2157 end_buf
= encode_integer_max (buf
, 0);
2158 status
= cff_dict_set_operands (font
->top_dict
,
2159 CHARSTRINGS_OP
, buf
, end_buf
- buf
);
2163 status
= cff_dict_set_operands (font
->top_dict
,
2164 FDSELECT_OP
, buf
, end_buf
- buf
);
2168 status
= cff_dict_set_operands (font
->top_dict
,
2169 FDARRAY_OP
, buf
, end_buf
- buf
);
2173 status
= cff_dict_set_operands (font
->top_dict
,
2174 CHARSET_OP
, buf
, end_buf
- buf
);
2178 status
= cairo_cff_font_set_ros_strings (font
);
2182 /* Create CID FD dictionary */
2183 status
= cairo_cff_font_create_cid_fontdict (font
);
2187 /* Create charstrings */
2188 for (i
= 0; i
< font
->scaled_font_subset
->num_glyphs
; i
++) {
2189 charstring
= _cairo_array_index(&type2_subset
->charstrings
, i
);
2191 status
= cff_index_append (&font
->charstrings_subset_index
,
2192 _cairo_array_index (charstring
, 0),
2193 _cairo_array_num_elements (charstring
));
2199 status
= cairo_cff_font_write_subset (font
);
2203 *data
= _cairo_array_index (&font
->output
, 0);
2204 *length
= _cairo_array_num_elements (&font
->output
);
2206 return CAIRO_STATUS_SUCCESS
;
2210 _cairo_cff_fallback_init (cairo_cff_subset_t
*cff_subset
,
2211 const char *subset_name
,
2212 cairo_scaled_font_subset_t
*font_subset
)
2214 cairo_cff_font_t
*font
= NULL
; /* squelch bogus compiler warning */
2215 cairo_status_t status
;
2216 const char *data
= NULL
; /* squelch bogus compiler warning */
2217 unsigned long length
= 0; /* squelch bogus compiler warning */
2219 cairo_type2_charstrings_t type2_subset
;
2221 status
= _cairo_cff_font_fallback_create (font_subset
, &font
, subset_name
);
2225 status
= _cairo_type2_charstrings_init (&type2_subset
, font_subset
);
2229 status
= cairo_cff_font_fallback_generate (font
, &type2_subset
, &data
, &length
);
2233 cff_subset
->base_font
= strdup (font
->font_name
);
2234 if (cff_subset
->base_font
== NULL
) {
2235 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2239 cff_subset
->widths
= calloc (sizeof (int), font
->scaled_font_subset
->num_glyphs
);
2240 if (cff_subset
->widths
== NULL
) {
2241 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2244 for (i
= 0; i
< font
->scaled_font_subset
->num_glyphs
; i
++)
2245 cff_subset
->widths
[i
] = type2_subset
.widths
[i
];
2247 cff_subset
->x_min
= type2_subset
.x_min
;
2248 cff_subset
->y_min
= type2_subset
.y_min
;
2249 cff_subset
->x_max
= type2_subset
.x_max
;
2250 cff_subset
->y_max
= type2_subset
.y_max
;
2251 cff_subset
->ascent
= type2_subset
.y_max
;
2252 cff_subset
->descent
= type2_subset
.y_min
;
2254 cff_subset
->data
= malloc (length
);
2255 if (cff_subset
->data
== NULL
) {
2256 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
2260 memcpy (cff_subset
->data
, data
, length
);
2261 cff_subset
->data_length
= length
;
2262 cff_subset
->data_length
= length
;
2264 _cairo_type2_charstrings_fini (&type2_subset
);
2265 cairo_cff_font_destroy (font
);
2267 return CAIRO_STATUS_SUCCESS
;
2270 free (cff_subset
->widths
);
2272 free (cff_subset
->base_font
);
2274 _cairo_type2_charstrings_fini (&type2_subset
);
2276 cairo_cff_font_destroy (font
);
2282 _cairo_cff_fallback_fini (cairo_cff_subset_t
*subset
)
2284 free (subset
->base_font
);
2285 free (subset
->widths
);
2286 free (subset
->data
);
2289 #endif /* CAIRO_HAS_FONT_SUBSET */