1 /* cairo - a vector graphics library with display and print output
3 * Copyright © 2004 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 * Kristian Høgsberg <krh@redhat.com>
34 * Adrian Johnson <ajohnson@redneon.com>
39 * http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6.html
40 * http://www.microsoft.com/typography/specs/default.htm
43 #define _BSD_SOURCE /* for snprintf(), strdup() */
46 #include "cairo-array-private.h"
47 #include "cairo-error-private.h"
49 #if CAIRO_HAS_FONT_SUBSET
51 #include "cairo-scaled-font-subsets-private.h"
52 #include "cairo-truetype-subset-private.h"
55 typedef struct subset_glyph subset_glyph_t
;
58 unsigned long location
;
61 typedef struct _cairo_truetype_font cairo_truetype_font_t
;
63 typedef struct table table_t
;
66 cairo_status_t (*write
) (cairo_truetype_font_t
*font
, unsigned long tag
);
67 int pos
; /* position in the font directory */
70 struct _cairo_truetype_font
{
72 cairo_scaled_font_subset_t
*scaled_font_subset
;
74 table_t truetype_tables
[10];
80 unsigned int num_glyphs
;
82 long x_min
, y_min
, x_max
, y_max
;
87 subset_glyph_t
*glyphs
;
88 const cairo_scaled_font_backend_t
*backend
;
89 int num_glyphs_in_face
;
92 cairo_array_t string_offsets
;
93 unsigned long last_offset
;
94 unsigned long last_boundary
;
95 int *parent_to_subset
;
96 cairo_status_t status
;
101 * Test that the structs we define for TrueType tables have the
102 * correct size, ie. they are not padded.
104 #define check(T, S) COMPILE_TIME_ASSERT (sizeof (T) == (S))
105 check (tt_head_t
, 54);
106 check (tt_hhea_t
, 36);
107 check (tt_maxp_t
, 32);
108 check (tt_name_record_t
, 12);
109 check (tt_name_t
, 18);
110 check (tt_name_t
, 18);
111 check (tt_composite_glyph_t
, 16);
112 check (tt_glyph_data_t
, 26);
115 static cairo_status_t
116 cairo_truetype_font_use_glyph (cairo_truetype_font_t
*font
,
117 unsigned short glyph
,
118 unsigned short *out
);
120 #define SFNT_VERSION 0x00010000
121 #define SFNT_STRING_MAX_LENGTH 65535
123 static cairo_status_t
124 _cairo_truetype_font_set_error (cairo_truetype_font_t
*font
,
125 cairo_status_t status
)
127 if (status
== CAIRO_STATUS_SUCCESS
||
128 status
== (int)CAIRO_INT_STATUS_UNSUPPORTED
)
131 _cairo_status_set_error (&font
->status
, status
);
133 return _cairo_error (status
);
136 static cairo_status_t
137 _cairo_truetype_font_create (cairo_scaled_font_subset_t
*scaled_font_subset
,
139 cairo_truetype_font_t
**font_return
)
141 cairo_status_t status
;
142 cairo_truetype_font_t
*font
;
143 const cairo_scaled_font_backend_t
*backend
;
149 backend
= scaled_font_subset
->scaled_font
->backend
;
150 if (!backend
->load_truetype_table
)
151 return CAIRO_INT_STATUS_UNSUPPORTED
;
153 /* FIXME: We should either support subsetting vertical fonts, or fail on
154 * vertical. Currently font_options_t doesn't have vertical flag, but
155 * it should be added in the future. For now, the freetype backend
156 * returns UNSUPPORTED in load_truetype_table if the font is vertical.
158 * if (cairo_font_options_get_vertical_layout (scaled_font_subset->scaled_font))
159 * return CAIRO_INT_STATUS_UNSUPPORTED;
162 /* We need to use a fallback font generated from the synthesized outlines. */
163 if (backend
->is_synthetic
&& backend
->is_synthetic (scaled_font_subset
->scaled_font
))
164 return CAIRO_INT_STATUS_UNSUPPORTED
;
166 size
= sizeof (tt_head_t
);
167 status
= backend
->load_truetype_table (scaled_font_subset
->scaled_font
,
169 (unsigned char *) &head
,
171 if (unlikely (status
))
174 size
= sizeof (tt_maxp_t
);
175 status
= backend
->load_truetype_table (scaled_font_subset
->scaled_font
,
177 (unsigned char *) &maxp
,
179 if (unlikely (status
))
182 size
= sizeof (tt_hhea_t
);
183 status
= backend
->load_truetype_table (scaled_font_subset
->scaled_font
,
185 (unsigned char *) &hhea
,
187 if (unlikely (status
))
190 font
= malloc (sizeof (cairo_truetype_font_t
));
191 if (unlikely (font
== NULL
))
192 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
194 font
->backend
= backend
;
195 font
->num_glyphs_in_face
= be16_to_cpu (maxp
.num_glyphs
);
196 font
->scaled_font_subset
= scaled_font_subset
;
198 font
->last_offset
= 0;
199 font
->last_boundary
= 0;
200 _cairo_array_init (&font
->output
, sizeof (char));
201 status
= _cairo_array_grow_by (&font
->output
, 4096);
202 if (unlikely (status
))
205 font
->glyphs
= calloc (font
->num_glyphs_in_face
+ 1, sizeof (subset_glyph_t
));
206 if (unlikely (font
->glyphs
== NULL
)) {
207 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
211 font
->parent_to_subset
= calloc (font
->num_glyphs_in_face
, sizeof (int));
212 if (unlikely (font
->parent_to_subset
== NULL
)) {
213 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
217 font
->is_pdf
= is_pdf
;
218 font
->base
.num_glyphs
= 0;
219 font
->base
.x_min
= (int16_t) be16_to_cpu (head
.x_min
);
220 font
->base
.y_min
= (int16_t) be16_to_cpu (head
.y_min
);
221 font
->base
.x_max
= (int16_t) be16_to_cpu (head
.x_max
);
222 font
->base
.y_max
= (int16_t) be16_to_cpu (head
.y_max
);
223 font
->base
.ascent
= (int16_t) be16_to_cpu (hhea
.ascender
);
224 font
->base
.descent
= (int16_t) be16_to_cpu (hhea
.descender
);
225 font
->base
.units_per_em
= (int16_t) be16_to_cpu (head
.units_per_em
);
226 if (font
->base
.units_per_em
== 0)
227 font
->base
.units_per_em
= 2048;
229 font
->base
.ps_name
= NULL
;
230 font
->base
.font_name
= NULL
;
231 status
= _cairo_truetype_read_font_name (scaled_font_subset
->scaled_font
,
233 &font
->base
.font_name
);
234 if (_cairo_status_is_error (status
))
237 /* If the PS name is not found, create a CairoFont-x-y name. */
238 if (font
->base
.ps_name
== NULL
) {
239 font
->base
.ps_name
= malloc (30);
240 if (unlikely (font
->base
.ps_name
== NULL
)) {
241 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
245 snprintf(font
->base
.ps_name
, 30, "CairoFont-%u-%u",
246 scaled_font_subset
->font_id
,
247 scaled_font_subset
->subset_id
);
250 font
->base
.widths
= calloc (font
->num_glyphs_in_face
, sizeof (int));
251 if (unlikely (font
->base
.widths
== NULL
)) {
252 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
256 _cairo_array_init (&font
->string_offsets
, sizeof (unsigned long));
257 status
= _cairo_array_grow_by (&font
->string_offsets
, 10);
258 if (unlikely (status
))
261 font
->status
= CAIRO_STATUS_SUCCESS
;
265 return CAIRO_STATUS_SUCCESS
;
268 _cairo_array_fini (&font
->string_offsets
);
269 free (font
->base
.widths
);
271 free (font
->base
.ps_name
);
273 free (font
->parent_to_subset
);
274 free (font
->base
.font_name
);
278 _cairo_array_fini (&font
->output
);
285 cairo_truetype_font_destroy (cairo_truetype_font_t
*font
)
287 _cairo_array_fini (&font
->string_offsets
);
288 free (font
->base
.widths
);
289 free (font
->base
.ps_name
);
290 free (font
->base
.font_name
);
291 free (font
->parent_to_subset
);
293 _cairo_array_fini (&font
->output
);
297 static cairo_status_t
298 cairo_truetype_font_allocate_write_buffer (cairo_truetype_font_t
*font
,
300 unsigned char **buffer
)
302 cairo_status_t status
;
307 status
= _cairo_array_allocate (&font
->output
, length
, (void **) buffer
);
308 if (unlikely (status
))
309 return _cairo_truetype_font_set_error (font
, status
);
311 return CAIRO_STATUS_SUCCESS
;
315 cairo_truetype_font_write (cairo_truetype_font_t
*font
,
319 cairo_status_t status
;
324 status
= _cairo_array_append_multiple (&font
->output
, data
, length
);
325 if (unlikely (status
))
326 status
= _cairo_truetype_font_set_error (font
, status
);
330 cairo_truetype_font_write_be16 (cairo_truetype_font_t
*font
,
338 be16_value
= cpu_to_be16 (value
);
339 cairo_truetype_font_write (font
, &be16_value
, sizeof be16_value
);
343 cairo_truetype_font_write_be32 (cairo_truetype_font_t
*font
,
351 be32_value
= cpu_to_be32 (value
);
352 cairo_truetype_font_write (font
, &be32_value
, sizeof be32_value
);
355 static cairo_status_t
356 cairo_truetype_font_align_output (cairo_truetype_font_t
*font
,
357 unsigned long *aligned
)
360 unsigned char *padding
;
362 length
= _cairo_array_num_elements (&font
->output
);
363 *aligned
= (length
+ 3) & ~3;
364 pad
= *aligned
- length
;
367 cairo_status_t status
;
369 status
= cairo_truetype_font_allocate_write_buffer (font
, pad
,
371 if (unlikely (status
))
374 memset (padding
, 0, pad
);
377 return CAIRO_STATUS_SUCCESS
;
380 static cairo_status_t
381 cairo_truetype_font_check_boundary (cairo_truetype_font_t
*font
,
382 unsigned long boundary
)
384 cairo_status_t status
;
389 if (boundary
- font
->last_offset
> SFNT_STRING_MAX_LENGTH
)
391 status
= _cairo_array_append (&font
->string_offsets
,
392 &font
->last_boundary
);
393 if (unlikely (status
))
394 return _cairo_truetype_font_set_error (font
, status
);
396 font
->last_offset
= font
->last_boundary
;
398 font
->last_boundary
= boundary
;
400 return CAIRO_STATUS_SUCCESS
;
403 typedef struct _cmap_unicode_range
{
406 } cmap_unicode_range_t
;
408 static cmap_unicode_range_t winansi_unicode_ranges
[] = {
425 static cairo_status_t
426 cairo_truetype_font_write_cmap_table (cairo_truetype_font_t
*font
,
436 num_ranges
= ARRAY_LENGTH (winansi_unicode_ranges
);
438 length
= 16 + (num_ranges
+ 1)*8;
439 for (i
= 0; i
< num_ranges
; i
++)
440 length
+= (winansi_unicode_ranges
[i
].end
- winansi_unicode_ranges
[i
].start
+ 1)*2;
443 while ((1 << entry_selector
) <= (num_ranges
+ 1))
448 cairo_truetype_font_write_be16 (font
, 0); /* Table version */
449 cairo_truetype_font_write_be16 (font
, 1); /* Num tables */
451 cairo_truetype_font_write_be16 (font
, 3); /* Platform */
452 cairo_truetype_font_write_be16 (font
, 1); /* Encoding */
453 cairo_truetype_font_write_be32 (font
, 12); /* Offset to start of table */
455 /* Output a format 4 encoding table for the winansi encoding */
457 cairo_truetype_font_write_be16 (font
, 4); /* Format */
458 cairo_truetype_font_write_be16 (font
, length
); /* Length */
459 cairo_truetype_font_write_be16 (font
, 0); /* Version */
460 cairo_truetype_font_write_be16 (font
, num_ranges
*2 + 2); /* 2*segcount */
461 cairo_truetype_font_write_be16 (font
, (1 << (entry_selector
+ 1))); /* searchrange */
462 cairo_truetype_font_write_be16 (font
, entry_selector
); /* entry selector */
463 cairo_truetype_font_write_be16 (font
, num_ranges
*2 + 2 - (1 << (entry_selector
+ 1))); /* rangeshift */
464 for (i
= 0; i
< num_ranges
; i
++)
465 cairo_truetype_font_write_be16 (font
, winansi_unicode_ranges
[i
].end
); /* end count[] */
466 cairo_truetype_font_write_be16 (font
, 0xffff); /* end count[] */
468 cairo_truetype_font_write_be16 (font
, 0); /* reserved */
470 for (i
= 0; i
< num_ranges
; i
++)
471 cairo_truetype_font_write_be16 (font
, winansi_unicode_ranges
[i
].start
); /* startCode[] */
472 cairo_truetype_font_write_be16 (font
, 0xffff); /* startCode[] */
474 for (i
= 0; i
< num_ranges
; i
++)
475 cairo_truetype_font_write_be16 (font
, 0x0000); /* delta[] */
476 cairo_truetype_font_write_be16 (font
, 1); /* delta[] */
478 range_offset
= num_ranges
*2 + 2;
479 for (i
= 0; i
< num_ranges
; i
++) {
480 cairo_truetype_font_write_be16 (font
, range_offset
); /* rangeOffset[] */
481 range_offset
+= (winansi_unicode_ranges
[i
].end
- winansi_unicode_ranges
[i
].start
+ 1)*2 - 2;
483 cairo_truetype_font_write_be16 (font
, 0); /* rangeOffset[] */
485 for (i
= 0; i
< num_ranges
; i
++) {
486 for (j
= winansi_unicode_ranges
[i
].start
; j
< winansi_unicode_ranges
[i
].end
+ 1; j
++) {
487 int ch
= _cairo_unicode_to_winansi (j
);
491 glyph
= font
->scaled_font_subset
->latin_to_subset_glyph_index
[ch
];
494 cairo_truetype_font_write_be16 (font
, glyph
);
501 static cairo_status_t
502 cairo_truetype_font_write_generic_table (cairo_truetype_font_t
*font
,
505 cairo_status_t status
;
506 unsigned char *buffer
;
513 status
= font
->backend
->load_truetype_table(font
->scaled_font_subset
->scaled_font
,
514 tag
, 0, NULL
, &size
);
515 if (unlikely (status
))
516 return _cairo_truetype_font_set_error (font
, status
);
518 status
= cairo_truetype_font_allocate_write_buffer (font
, size
, &buffer
);
519 if (unlikely (status
))
520 return _cairo_truetype_font_set_error (font
, status
);
522 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
523 tag
, 0, buffer
, &size
);
524 if (unlikely (status
))
525 return _cairo_truetype_font_set_error (font
, status
);
527 return CAIRO_STATUS_SUCCESS
;
530 static cairo_status_t
531 cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t
*font
,
532 unsigned char *buffer
,
535 tt_glyph_data_t
*glyph_data
;
536 tt_composite_glyph_t
*composite_glyph
;
538 int has_more_components
;
539 unsigned short flags
;
540 unsigned short index
;
541 cairo_status_t status
;
542 unsigned char *end
= buffer
+ size
;
547 glyph_data
= (tt_glyph_data_t
*) buffer
;
548 if ((unsigned char *)(&glyph_data
->data
) >= end
)
549 return CAIRO_INT_STATUS_UNSUPPORTED
;
551 if ((int16_t)be16_to_cpu (glyph_data
->num_contours
) >= 0)
552 return CAIRO_STATUS_SUCCESS
;
554 composite_glyph
= &glyph_data
->glyph
;
556 if ((unsigned char *)(&composite_glyph
->args
[1]) > end
)
557 return CAIRO_INT_STATUS_UNSUPPORTED
;
559 flags
= be16_to_cpu (composite_glyph
->flags
);
560 has_more_components
= flags
& TT_MORE_COMPONENTS
;
561 status
= cairo_truetype_font_use_glyph (font
, be16_to_cpu (composite_glyph
->index
), &index
);
562 if (unlikely (status
))
565 composite_glyph
->index
= cpu_to_be16 (index
);
567 if (flags
& TT_ARG_1_AND_2_ARE_WORDS
)
570 if (flags
& TT_WE_HAVE_A_SCALE
)
572 else if (flags
& TT_WE_HAVE_AN_X_AND_Y_SCALE
)
574 else if (flags
& TT_WE_HAVE_A_TWO_BY_TWO
)
577 composite_glyph
= (tt_composite_glyph_t
*) &(composite_glyph
->args
[num_args
]);
578 } while (has_more_components
);
580 return CAIRO_STATUS_SUCCESS
;
583 static cairo_status_t
584 cairo_truetype_font_write_glyf_table (cairo_truetype_font_t
*font
,
587 unsigned long start_offset
, index
, size
, next
;
589 unsigned long begin
, end
;
590 unsigned char *buffer
;
593 unsigned char *bytes
;
594 uint16_t *short_offsets
;
595 uint32_t *long_offsets
;
597 cairo_status_t status
;
602 size
= sizeof (tt_head_t
);
603 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
605 (unsigned char*) &header
, &size
);
606 if (unlikely (status
))
607 return _cairo_truetype_font_set_error (font
, status
);
609 if (be16_to_cpu (header
.index_to_loc_format
) == 0)
610 size
= sizeof (int16_t) * (font
->num_glyphs_in_face
+ 1);
612 size
= sizeof (int32_t) * (font
->num_glyphs_in_face
+ 1);
614 u
.bytes
= malloc (size
);
615 if (unlikely (u
.bytes
== NULL
))
616 return _cairo_truetype_font_set_error (font
, CAIRO_STATUS_NO_MEMORY
);
618 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
619 TT_TAG_loca
, 0, u
.bytes
, &size
);
620 if (unlikely (status
))
621 return _cairo_truetype_font_set_error (font
, status
);
623 start_offset
= _cairo_array_num_elements (&font
->output
);
624 for (i
= 0; i
< font
->base
.num_glyphs
; i
++) {
625 index
= font
->glyphs
[i
].parent_index
;
626 if (be16_to_cpu (header
.index_to_loc_format
) == 0) {
627 begin
= be16_to_cpu (u
.short_offsets
[index
]) * 2;
628 end
= be16_to_cpu (u
.short_offsets
[index
+ 1]) * 2;
631 begin
= be32_to_cpu (u
.long_offsets
[index
]);
632 end
= be32_to_cpu (u
.long_offsets
[index
+ 1]);
635 /* quick sanity check... */
637 status
= CAIRO_INT_STATUS_UNSUPPORTED
;
642 status
= cairo_truetype_font_align_output (font
, &next
);
643 if (unlikely (status
))
646 status
= cairo_truetype_font_check_boundary (font
, next
);
647 if (unlikely (status
))
650 font
->glyphs
[i
].location
= next
- start_offset
;
652 status
= cairo_truetype_font_allocate_write_buffer (font
, size
, &buffer
);
653 if (unlikely (status
))
657 tt_glyph_data_t
*glyph_data
;
660 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
661 TT_TAG_glyf
, begin
, buffer
, &size
);
662 if (unlikely (status
))
665 glyph_data
= (tt_glyph_data_t
*) buffer
;
666 num_contours
= (int16_t)be16_to_cpu (glyph_data
->num_contours
);
667 if (num_contours
< 0) {
668 status
= cairo_truetype_font_remap_composite_glyph (font
, buffer
, size
);
669 if (unlikely (status
))
671 } else if (num_contours
== 0) {
672 /* num_contours == 0 is undefined in the Opentype
673 * spec. There are some embedded fonts that have a
674 * space glyph with num_contours = 0 that fails on
675 * some printers. The spec requires glyphs without
676 * contours to have a 0 size glyph entry in the loca
679 * If num_contours == 0, truncate the glyph to 0 size.
681 _cairo_array_truncate (&font
->output
, _cairo_array_num_elements (&font
->output
) - size
);
686 status
= cairo_truetype_font_align_output (font
, &next
);
687 if (unlikely (status
))
690 font
->glyphs
[i
].location
= next
- start_offset
;
692 status
= font
->status
;
696 return _cairo_truetype_font_set_error (font
, status
);
699 static cairo_status_t
700 cairo_truetype_font_write_head_table (cairo_truetype_font_t
*font
,
703 unsigned char *buffer
;
705 cairo_status_t status
;
711 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
712 tag
, 0, NULL
, &size
);
713 if (unlikely (status
))
714 return _cairo_truetype_font_set_error (font
, status
);
716 font
->checksum_index
= _cairo_array_num_elements (&font
->output
) + 8;
717 status
= cairo_truetype_font_allocate_write_buffer (font
, size
, &buffer
);
718 if (unlikely (status
))
719 return _cairo_truetype_font_set_error (font
, status
);
721 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
722 tag
, 0, buffer
, &size
);
723 if (unlikely (status
))
724 return _cairo_truetype_font_set_error (font
, status
);
726 /* set checkSumAdjustment to 0 for table checksum calculation */
727 *(uint32_t *)(buffer
+ 8) = 0;
729 return CAIRO_STATUS_SUCCESS
;
732 static cairo_status_t
733 cairo_truetype_font_write_hhea_table (cairo_truetype_font_t
*font
, unsigned long tag
)
737 cairo_status_t status
;
742 size
= sizeof (tt_hhea_t
);
743 status
= cairo_truetype_font_allocate_write_buffer (font
, size
, (unsigned char **) &hhea
);
744 if (unlikely (status
))
745 return _cairo_truetype_font_set_error (font
, status
);
747 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
748 tag
, 0, (unsigned char *) hhea
, &size
);
749 if (unlikely (status
))
750 return _cairo_truetype_font_set_error (font
, status
);
752 hhea
->num_hmetrics
= cpu_to_be16 ((uint16_t)(font
->base
.num_glyphs
));
754 return CAIRO_STATUS_SUCCESS
;
757 static cairo_status_t
758 cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t
*font
,
762 unsigned long long_entry_size
;
763 unsigned long short_entry_size
;
768 cairo_status_t status
;
773 size
= sizeof (tt_hhea_t
);
774 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
776 (unsigned char*) &hhea
, &size
);
777 if (unlikely (status
))
778 return _cairo_truetype_font_set_error (font
, status
);
780 num_hmetrics
= be16_to_cpu(hhea
.num_hmetrics
);
782 for (i
= 0; i
< font
->base
.num_glyphs
; i
++) {
783 long_entry_size
= 2 * sizeof (int16_t);
784 short_entry_size
= sizeof (int16_t);
785 status
= cairo_truetype_font_allocate_write_buffer (font
,
787 (unsigned char **) &p
);
788 if (unlikely (status
))
789 return _cairo_truetype_font_set_error (font
, status
);
791 if (font
->glyphs
[i
].parent_index
< num_hmetrics
) {
792 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
794 font
->glyphs
[i
].parent_index
* long_entry_size
,
795 (unsigned char *) p
, &long_entry_size
);
796 if (unlikely (status
))
797 return _cairo_truetype_font_set_error (font
, status
);
801 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
803 (num_hmetrics
- 1) * long_entry_size
,
804 (unsigned char *) p
, &short_entry_size
);
805 if (unlikely (status
))
806 return _cairo_truetype_font_set_error (font
, status
);
808 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
810 num_hmetrics
* long_entry_size
+
811 (font
->glyphs
[i
].parent_index
- num_hmetrics
) * short_entry_size
,
812 (unsigned char *) (p
+ 1), &short_entry_size
);
813 if (unlikely (status
))
814 return _cairo_truetype_font_set_error (font
, status
);
816 font
->base
.widths
[i
] = be16_to_cpu (p
[0]);
819 return CAIRO_STATUS_SUCCESS
;
822 static cairo_status_t
823 cairo_truetype_font_write_loca_table (cairo_truetype_font_t
*font
,
829 cairo_status_t status
;
834 size
= sizeof(tt_head_t
);
835 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
837 (unsigned char*) &header
, &size
);
838 if (unlikely (status
))
839 return _cairo_truetype_font_set_error (font
, status
);
841 if (be16_to_cpu (header
.index_to_loc_format
) == 0)
843 for (i
= 0; i
< font
->base
.num_glyphs
+ 1; i
++)
844 cairo_truetype_font_write_be16 (font
, font
->glyphs
[i
].location
/ 2);
846 for (i
= 0; i
< font
->base
.num_glyphs
+ 1; i
++)
847 cairo_truetype_font_write_be32 (font
, font
->glyphs
[i
].location
);
853 static cairo_status_t
854 cairo_truetype_font_write_maxp_table (cairo_truetype_font_t
*font
,
859 cairo_status_t status
;
864 size
= sizeof (tt_maxp_t
);
865 status
= cairo_truetype_font_allocate_write_buffer (font
, size
, (unsigned char **) &maxp
);
866 if (unlikely (status
))
867 return _cairo_truetype_font_set_error (font
, status
);
869 status
= font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
870 tag
, 0, (unsigned char *) maxp
, &size
);
871 if (unlikely (status
))
872 return _cairo_truetype_font_set_error (font
, status
);
874 maxp
->num_glyphs
= cpu_to_be16 (font
->base
.num_glyphs
);
876 return CAIRO_STATUS_SUCCESS
;
879 static cairo_status_t
880 cairo_truetype_font_write_offset_table (cairo_truetype_font_t
*font
)
882 cairo_status_t status
;
883 unsigned char *table_buffer
;
884 size_t table_buffer_length
;
885 unsigned short search_range
, entry_selector
, range_shift
;
892 while (search_range
* 2 <= font
->num_tables
) {
897 range_shift
= font
->num_tables
* 16 - search_range
;
899 cairo_truetype_font_write_be32 (font
, SFNT_VERSION
);
900 cairo_truetype_font_write_be16 (font
, font
->num_tables
);
901 cairo_truetype_font_write_be16 (font
, search_range
);
902 cairo_truetype_font_write_be16 (font
, entry_selector
);
903 cairo_truetype_font_write_be16 (font
, range_shift
);
905 /* Allocate space for the table directory. Each directory entry
906 * will be filled in by cairo_truetype_font_update_entry() after
907 * the table is written. */
908 table_buffer_length
= font
->num_tables
* 16;
909 status
= cairo_truetype_font_allocate_write_buffer (font
, table_buffer_length
,
911 if (unlikely (status
))
912 return _cairo_truetype_font_set_error (font
, status
);
914 return CAIRO_STATUS_SUCCESS
;
918 cairo_truetype_font_calculate_checksum (cairo_truetype_font_t
*font
,
922 uint32_t *padded_end
;
928 data
= _cairo_array_index (&font
->output
, 0);
929 p
= (uint32_t *) (data
+ start
);
930 padded_end
= (uint32_t *) (data
+ ((end
+ 3) & ~3));
931 while (p
< padded_end
)
932 checksum
+= be32_to_cpu(*p
++);
938 cairo_truetype_font_update_entry (cairo_truetype_font_t
*font
,
946 entry
= _cairo_array_index (&font
->output
, 12 + 16 * index
);
947 entry
[0] = cpu_to_be32 ((uint32_t)tag
);
948 entry
[1] = cpu_to_be32 (cairo_truetype_font_calculate_checksum (font
, start
, end
));
949 entry
[2] = cpu_to_be32 ((uint32_t)start
);
950 entry
[3] = cpu_to_be32 ((uint32_t)(end
- start
));
953 static cairo_status_t
954 cairo_truetype_font_generate (cairo_truetype_font_t
*font
,
956 unsigned long *length
,
957 const unsigned long **string_offsets
,
958 unsigned long *num_strings
)
960 cairo_status_t status
;
961 unsigned long start
, end
, next
;
962 uint32_t checksum
, *checksum_location
;
968 status
= cairo_truetype_font_write_offset_table (font
);
969 if (unlikely (status
))
972 status
= cairo_truetype_font_align_output (font
, &start
);
973 if (unlikely (status
))
977 for (i
= 0; i
< font
->num_tables
; i
++) {
978 status
= font
->truetype_tables
[i
].write (font
, font
->truetype_tables
[i
].tag
);
979 if (unlikely (status
))
982 end
= _cairo_array_num_elements (&font
->output
);
983 status
= cairo_truetype_font_align_output (font
, &next
);
984 if (unlikely (status
))
987 cairo_truetype_font_update_entry (font
, font
->truetype_tables
[i
].pos
,
988 font
->truetype_tables
[i
].tag
, start
, end
);
989 status
= cairo_truetype_font_check_boundary (font
, next
);
990 if (unlikely (status
))
997 0xb1b0afba - cairo_truetype_font_calculate_checksum (font
, 0, end
);
998 checksum_location
= _cairo_array_index (&font
->output
, font
->checksum_index
);
999 *checksum_location
= cpu_to_be32 (checksum
);
1001 *data
= _cairo_array_index (&font
->output
, 0);
1002 *length
= _cairo_array_num_elements (&font
->output
);
1003 *num_strings
= _cairo_array_num_elements (&font
->string_offsets
);
1004 if (*num_strings
!= 0)
1005 *string_offsets
= _cairo_array_index (&font
->string_offsets
, 0);
1007 *string_offsets
= NULL
;
1010 return _cairo_truetype_font_set_error (font
, status
);
1013 static cairo_status_t
1014 cairo_truetype_font_use_glyph (cairo_truetype_font_t
*font
,
1015 unsigned short glyph
,
1016 unsigned short *out
)
1018 if (glyph
>= font
->num_glyphs_in_face
)
1019 return CAIRO_INT_STATUS_UNSUPPORTED
;
1021 if (font
->parent_to_subset
[glyph
] == 0) {
1022 font
->parent_to_subset
[glyph
] = font
->base
.num_glyphs
;
1023 font
->glyphs
[font
->base
.num_glyphs
].parent_index
= glyph
;
1024 font
->base
.num_glyphs
++;
1027 *out
= font
->parent_to_subset
[glyph
];
1028 return CAIRO_STATUS_SUCCESS
;
1032 cairo_truetype_font_add_truetype_table (cairo_truetype_font_t
*font
,
1034 cairo_status_t (*write
) (cairo_truetype_font_t
*font
, unsigned long tag
),
1037 font
->truetype_tables
[font
->num_tables
].tag
= tag
;
1038 font
->truetype_tables
[font
->num_tables
].write
= write
;
1039 font
->truetype_tables
[font
->num_tables
].pos
= pos
;
1043 /* cairo_truetype_font_create_truetype_table_list() builds the list of
1044 * truetype tables to be embedded in the subsetted font. Each call to
1045 * cairo_truetype_font_add_truetype_table() adds a table, the callback
1046 * for generating the table, and the position in the table directory
1047 * to the truetype_tables array.
1049 * As we write out the glyf table we remap composite glyphs.
1050 * Remapping composite glyphs will reference the sub glyphs the
1051 * composite glyph is made up of. The "glyf" table callback needs to
1052 * be called first so we have all the glyphs in the subset before
1055 * The order in which tables are added to the truetype_table array
1056 * using cairo_truetype_font_add_truetype_table() specifies the order
1057 * in which the callback functions will be called.
1059 * The tables in the table directory must be listed in alphabetical
1060 * order. The "cvt", "fpgm", and "prep" are optional tables. They
1061 * will only be embedded in the subset if they exist in the source
1062 * font. "cmap" is only embedded for latin fonts. The pos parameter of
1063 * cairo_truetype_font_add_truetype_table() specifies the position of
1064 * the table in the table directory.
1067 cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t
*font
)
1069 cairo_bool_t has_cvt
= FALSE
;
1070 cairo_bool_t has_fpgm
= FALSE
;
1071 cairo_bool_t has_prep
= FALSE
;
1076 if (font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
1077 TT_TAG_cvt
, 0, NULL
,
1078 &size
) == CAIRO_INT_STATUS_SUCCESS
)
1082 if (font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
1083 TT_TAG_fpgm
, 0, NULL
,
1084 &size
) == CAIRO_INT_STATUS_SUCCESS
)
1088 if (font
->backend
->load_truetype_table (font
->scaled_font_subset
->scaled_font
,
1089 TT_TAG_prep
, 0, NULL
,
1090 &size
) == CAIRO_INT_STATUS_SUCCESS
)
1093 font
->num_tables
= 0;
1095 if (font
->is_pdf
&& font
->scaled_font_subset
->is_latin
)
1101 cairo_truetype_font_add_truetype_table (font
, TT_TAG_glyf
, cairo_truetype_font_write_glyf_table
, pos
);
1104 if (font
->is_pdf
&& font
->scaled_font_subset
->is_latin
)
1105 cairo_truetype_font_add_truetype_table (font
, TT_TAG_cmap
, cairo_truetype_font_write_cmap_table
, pos
++);
1107 cairo_truetype_font_add_truetype_table (font
, TT_TAG_cvt
, cairo_truetype_font_write_generic_table
, pos
++);
1109 cairo_truetype_font_add_truetype_table (font
, TT_TAG_fpgm
, cairo_truetype_font_write_generic_table
, pos
++);
1111 cairo_truetype_font_add_truetype_table (font
, TT_TAG_head
, cairo_truetype_font_write_head_table
, pos
++);
1112 cairo_truetype_font_add_truetype_table (font
, TT_TAG_hhea
, cairo_truetype_font_write_hhea_table
, pos
++);
1113 cairo_truetype_font_add_truetype_table (font
, TT_TAG_hmtx
, cairo_truetype_font_write_hmtx_table
, pos
++);
1114 cairo_truetype_font_add_truetype_table (font
, TT_TAG_loca
, cairo_truetype_font_write_loca_table
, pos
++);
1115 cairo_truetype_font_add_truetype_table (font
, TT_TAG_maxp
, cairo_truetype_font_write_maxp_table
, pos
++);
1117 cairo_truetype_font_add_truetype_table (font
, TT_TAG_prep
, cairo_truetype_font_write_generic_table
, pos
);
1120 static cairo_status_t
1121 cairo_truetype_subset_init_internal (cairo_truetype_subset_t
*truetype_subset
,
1122 cairo_scaled_font_subset_t
*font_subset
,
1123 cairo_bool_t is_pdf
)
1125 cairo_truetype_font_t
*font
= NULL
;
1126 cairo_status_t status
;
1127 const char *data
= NULL
; /* squelch bogus compiler warning */
1128 unsigned long length
= 0; /* squelch bogus compiler warning */
1129 unsigned long offsets_length
;
1131 const unsigned long *string_offsets
= NULL
;
1132 unsigned long num_strings
= 0;
1134 status
= _cairo_truetype_font_create (font_subset
, is_pdf
, &font
);
1135 if (unlikely (status
))
1138 for (i
= 0; i
< font
->scaled_font_subset
->num_glyphs
; i
++) {
1139 unsigned short parent_glyph
= font
->scaled_font_subset
->glyphs
[i
];
1140 status
= cairo_truetype_font_use_glyph (font
, parent_glyph
, &parent_glyph
);
1141 if (unlikely (status
))
1145 cairo_truetype_font_create_truetype_table_list (font
);
1146 status
= cairo_truetype_font_generate (font
, &data
, &length
,
1147 &string_offsets
, &num_strings
);
1148 if (unlikely (status
))
1151 truetype_subset
->ps_name
= strdup (font
->base
.ps_name
);
1152 if (unlikely (truetype_subset
->ps_name
== NULL
)) {
1153 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1157 if (font
->base
.font_name
!= NULL
) {
1158 truetype_subset
->family_name_utf8
= strdup (font
->base
.font_name
);
1159 if (unlikely (truetype_subset
->family_name_utf8
== NULL
)) {
1160 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1164 truetype_subset
->family_name_utf8
= NULL
;
1167 /* The widths array returned must contain only widths for the
1168 * glyphs in font_subset. Any subglyphs appended after
1169 * font_subset->num_glyphs are omitted. */
1170 truetype_subset
->widths
= calloc (sizeof (double),
1171 font
->scaled_font_subset
->num_glyphs
);
1172 if (unlikely (truetype_subset
->widths
== NULL
)) {
1173 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1176 for (i
= 0; i
< font
->scaled_font_subset
->num_glyphs
; i
++)
1177 truetype_subset
->widths
[i
] = (double)font
->base
.widths
[i
]/font
->base
.units_per_em
;
1179 truetype_subset
->x_min
= (double)font
->base
.x_min
/font
->base
.units_per_em
;
1180 truetype_subset
->y_min
= (double)font
->base
.y_min
/font
->base
.units_per_em
;
1181 truetype_subset
->x_max
= (double)font
->base
.x_max
/font
->base
.units_per_em
;
1182 truetype_subset
->y_max
= (double)font
->base
.y_max
/font
->base
.units_per_em
;
1183 truetype_subset
->ascent
= (double)font
->base
.ascent
/font
->base
.units_per_em
;
1184 truetype_subset
->descent
= (double)font
->base
.descent
/font
->base
.units_per_em
;
1187 truetype_subset
->data
= malloc (length
);
1188 if (unlikely (truetype_subset
->data
== NULL
)) {
1189 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1193 memcpy (truetype_subset
->data
, data
, length
);
1195 truetype_subset
->data
= NULL
;
1196 truetype_subset
->data_length
= length
;
1199 offsets_length
= num_strings
* sizeof (unsigned long);
1200 truetype_subset
->string_offsets
= malloc (offsets_length
);
1201 if (unlikely (truetype_subset
->string_offsets
== NULL
)) {
1202 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1206 memcpy (truetype_subset
->string_offsets
, string_offsets
, offsets_length
);
1207 truetype_subset
->num_string_offsets
= num_strings
;
1209 truetype_subset
->string_offsets
= NULL
;
1210 truetype_subset
->num_string_offsets
= 0;
1213 cairo_truetype_font_destroy (font
);
1215 return CAIRO_STATUS_SUCCESS
;
1218 free (truetype_subset
->data
);
1220 free (truetype_subset
->widths
);
1222 free (truetype_subset
->family_name_utf8
);
1224 free (truetype_subset
->ps_name
);
1226 cairo_truetype_font_destroy (font
);
1232 _cairo_truetype_subset_init_ps (cairo_truetype_subset_t
*truetype_subset
,
1233 cairo_scaled_font_subset_t
*font_subset
)
1235 return cairo_truetype_subset_init_internal (truetype_subset
, font_subset
, FALSE
);
1239 _cairo_truetype_subset_init_pdf (cairo_truetype_subset_t
*truetype_subset
,
1240 cairo_scaled_font_subset_t
*font_subset
)
1242 return cairo_truetype_subset_init_internal (truetype_subset
, font_subset
, TRUE
);
1246 _cairo_truetype_subset_fini (cairo_truetype_subset_t
*subset
)
1248 free (subset
->ps_name
);
1249 free (subset
->family_name_utf8
);
1250 free (subset
->widths
);
1251 free (subset
->data
);
1252 free (subset
->string_offsets
);
1255 static cairo_int_status_t
1256 _cairo_truetype_reverse_cmap (cairo_scaled_font_t
*scaled_font
,
1257 unsigned long table_offset
,
1258 unsigned long index
,
1261 cairo_status_t status
;
1262 const cairo_scaled_font_backend_t
*backend
;
1263 tt_segment_map_t
*map
;
1265 unsigned int num_segments
, i
;
1267 uint16_t *start_code
;
1270 uint16_t *range_offset
;
1273 backend
= scaled_font
->backend
;
1275 status
= backend
->load_truetype_table (scaled_font
,
1276 TT_TAG_cmap
, table_offset
,
1277 (unsigned char *) &buf
,
1279 if (unlikely (status
))
1282 /* All table formats have the same first two words */
1283 map
= (tt_segment_map_t
*) buf
;
1284 if (be16_to_cpu (map
->format
) != 4)
1285 return CAIRO_INT_STATUS_UNSUPPORTED
;
1287 size
= be16_to_cpu (map
->length
);
1288 map
= malloc (size
);
1289 if (unlikely (map
== NULL
))
1290 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1292 status
= backend
->load_truetype_table (scaled_font
,
1293 TT_TAG_cmap
, table_offset
,
1294 (unsigned char *) map
,
1296 if (unlikely (status
))
1299 num_segments
= be16_to_cpu (map
->segCountX2
)/2;
1301 /* A Format 4 cmap contains 8 uint16_t numbers and 4 arrays of
1302 * uint16_t each num_segments long. */
1303 if (size
< (8 + 4*num_segments
)*sizeof(uint16_t))
1304 return CAIRO_INT_STATUS_UNSUPPORTED
;
1306 end_code
= map
->endCount
;
1307 start_code
= &(end_code
[num_segments
+ 1]);
1308 delta
= &(start_code
[num_segments
]);
1309 range_offset
= &(delta
[num_segments
]);
1311 /* search for glyph in segments with rangeOffset=0 */
1312 for (i
= 0; i
< num_segments
; i
++) {
1313 c
= index
- be16_to_cpu (delta
[i
]);
1314 if (range_offset
[i
] == 0 &&
1315 c
>= be16_to_cpu (start_code
[i
]) &&
1316 c
<= be16_to_cpu (end_code
[i
]))
1323 /* search for glyph in segments with rangeOffset=1 */
1324 for (i
= 0; i
< num_segments
; i
++) {
1325 if (range_offset
[i
] != 0) {
1326 uint16_t *glyph_ids
= &range_offset
[i
] + be16_to_cpu (range_offset
[i
])/2;
1327 int range_size
= be16_to_cpu (end_code
[i
]) - be16_to_cpu (start_code
[i
]) + 1;
1328 uint16_t g_id_be
= cpu_to_be16 (index
);
1331 if (range_size
> 0) {
1332 if ((char*)glyph_ids
+ 2*range_size
> (char*)map
+ size
)
1333 return CAIRO_INT_STATUS_UNSUPPORTED
;
1335 for (j
= 0; j
< range_size
; j
++) {
1336 if (glyph_ids
[j
] == g_id_be
) {
1337 *ucs4
= be16_to_cpu (start_code
[i
]) + j
;
1345 /* glyph not found */
1349 status
= CAIRO_STATUS_SUCCESS
;
1358 _cairo_truetype_index_to_ucs4 (cairo_scaled_font_t
*scaled_font
,
1359 unsigned long index
,
1362 cairo_int_status_t status
= CAIRO_INT_STATUS_UNSUPPORTED
;
1363 const cairo_scaled_font_backend_t
*backend
;
1369 backend
= scaled_font
->backend
;
1370 if (!backend
->load_truetype_table
)
1371 return CAIRO_INT_STATUS_UNSUPPORTED
;
1374 status
= backend
->load_truetype_table (scaled_font
,
1376 (unsigned char *) &buf
,
1378 if (unlikely (status
))
1381 cmap
= (tt_cmap_t
*) buf
;
1382 num_tables
= be16_to_cpu (cmap
->num_tables
);
1383 size
= 4 + num_tables
*sizeof(tt_cmap_index_t
);
1384 cmap
= _cairo_malloc_ab_plus_c (num_tables
, sizeof (tt_cmap_index_t
), 4);
1385 if (unlikely (cmap
== NULL
))
1386 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1388 status
= backend
->load_truetype_table (scaled_font
,
1390 (unsigned char *) cmap
,
1392 if (unlikely (status
))
1395 /* Find a table with Unicode mapping */
1396 for (i
= 0; i
< num_tables
; i
++) {
1397 if (be16_to_cpu (cmap
->index
[i
].platform
) == 3 &&
1398 be16_to_cpu (cmap
->index
[i
].encoding
) == 1) {
1399 status
= _cairo_truetype_reverse_cmap (scaled_font
,
1400 be32_to_cpu (cmap
->index
[i
].offset
),
1403 if (status
!= CAIRO_INT_STATUS_UNSUPPORTED
)
1414 static cairo_status_t
1415 find_name (tt_name_t
*name
, int name_id
, int platform
, int encoding
, int language
, char **str_out
)
1417 tt_name_record_t
*record
;
1421 cairo_bool_t has_tag
;
1422 cairo_status_t status
;
1425 for (i
= 0; i
< be16_to_cpu (name
->num_records
); i
++) {
1426 record
= &(name
->records
[i
]);
1427 if (be16_to_cpu (record
->name
) == name_id
&&
1428 be16_to_cpu (record
->platform
) == platform
&&
1429 be16_to_cpu (record
->encoding
) == encoding
&&
1430 (language
== -1 || be16_to_cpu (record
->language
) == language
)) {
1432 str
= malloc (be16_to_cpu (record
->length
) + 1);
1434 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1436 len
= be16_to_cpu (record
->length
);
1438 ((char*)name
) + be16_to_cpu (name
->strings_offset
) + be16_to_cpu (record
->offset
),
1440 str
[be16_to_cpu (record
->length
)] = 0;
1446 return CAIRO_STATUS_SUCCESS
;
1449 if (platform
== 3) { /* Win platform, unicode encoding */
1450 /* convert to utf8 */
1453 uint16_t *u
= (uint16_t *) str
;
1456 for (i
= 0; i
< u_len
; i
++)
1457 size
+= _cairo_ucs4_to_utf8 (be16_to_cpu(u
[i
]), NULL
);
1459 utf8
= malloc (size
+ 1);
1461 status
=_cairo_error (CAIRO_STATUS_NO_MEMORY
);
1465 for (i
= 0; i
< u_len
; i
++)
1466 p
+= _cairo_ucs4_to_utf8 (be16_to_cpu(u
[i
]), p
);
1470 } else if (platform
== 1) { /* Mac platform, Mac Roman encoding */
1471 /* Replace characters above 127 with underscores. We could use
1472 * a lookup table to convert to unicode but since most fonts
1473 * include a unicode name this is just a rarely used fallback. */
1474 for (i
= 0; i
< len
; i
++) {
1475 if ((unsigned char)str
[i
] > 127)
1480 /* If font name is prefixed with a PDF subset tag, strip it off. */
1484 if (len
> 7 && p
[6] == '+') {
1486 for (i
= 0; i
< 6; i
++) {
1487 if (p
[i
] < 'A' || p
[i
] > 'Z') {
1494 p
= malloc (len
- 6);
1495 if (unlikely (p
== NULL
)) {
1496 status
=_cairo_error (CAIRO_STATUS_NO_MEMORY
);
1499 memcpy (p
, str
+ 7, len
- 7);
1507 return CAIRO_STATUS_SUCCESS
;
1516 _cairo_truetype_read_font_name (cairo_scaled_font_t
*scaled_font
,
1518 char **font_name_out
)
1520 cairo_status_t status
;
1521 const cairo_scaled_font_backend_t
*backend
;
1524 char *ps_name
= NULL
;
1525 char *family_name
= NULL
;
1527 backend
= scaled_font
->backend
;
1528 if (!backend
->load_truetype_table
)
1529 return CAIRO_INT_STATUS_UNSUPPORTED
;
1532 status
= backend
->load_truetype_table (scaled_font
,
1539 name
= malloc (size
);
1541 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1543 status
= backend
->load_truetype_table (scaled_font
,
1545 (unsigned char *) name
,
1550 /* Find PS Name (name_id = 6). OT spec says PS name must be one of
1551 * the following two encodings */
1552 status
= find_name (name
, 6, 3, 1, 0x409, &ps_name
); /* win, unicode, english-us */
1553 if (unlikely(status
))
1557 status
= find_name (name
, 6, 1, 0, 0, &ps_name
); /* mac, roman, english */
1558 if (unlikely(status
))
1562 /* Find Family name (name_id = 1) */
1563 status
= find_name (name
, 1, 3, 1, 0x409, &family_name
); /* win, unicode, english-us */
1564 if (unlikely(status
))
1568 status
= find_name (name
, 1, 3, 0, 0x409, &family_name
); /* win, symbol, english-us */
1569 if (unlikely(status
))
1574 status
= find_name (name
, 1, 1, 0, 0, &family_name
); /* mac, roman, english */
1575 if (unlikely(status
))
1580 status
= find_name (name
, 1, 3, 1, -1, &family_name
); /* win, unicode, any language */
1581 if (unlikely(status
))
1585 status
= _cairo_escape_ps_name (&ps_name
);
1586 if (unlikely(status
))
1591 *ps_name_out
= ps_name
;
1592 *font_name_out
= family_name
;
1594 return CAIRO_STATUS_SUCCESS
;
1600 *ps_name_out
= NULL
;
1601 *font_name_out
= NULL
;
1607 _cairo_truetype_get_style (cairo_scaled_font_t
*scaled_font
,
1610 cairo_bool_t
*italic
)
1612 cairo_status_t status
;
1613 const cairo_scaled_font_backend_t
*backend
;
1618 backend
= scaled_font
->backend
;
1619 if (!backend
->load_truetype_table
)
1620 return CAIRO_INT_STATUS_UNSUPPORTED
;
1623 status
= backend
->load_truetype_table (scaled_font
,
1630 if (size
< sizeof(os2
))
1631 return CAIRO_INT_STATUS_UNSUPPORTED
;
1633 size
= sizeof (os2
);
1634 status
= backend
->load_truetype_table (scaled_font
,
1636 (unsigned char *) &os2
,
1641 *weight
= be16_to_cpu (os2
.usWeightClass
);
1642 selection
= be16_to_cpu (os2
.fsSelection
);
1643 *bold
= (selection
& TT_FS_SELECTION_BOLD
) ? TRUE
: FALSE
;
1644 *italic
= (selection
& TT_FS_SELECTION_ITALIC
) ? TRUE
: FALSE
;
1646 return CAIRO_STATUS_SUCCESS
;
1649 #endif /* CAIRO_HAS_FONT_SUBSET */