1
/* cairo - a vector graphics library with display and print output
3
* Copyright © 2006 Red Hat, Inc
5
* This library is free software; you can redistribute it and/or
6
* modify it either under the terms of the GNU Lesser General Public
7
* License version 2.1 as published by the Free Software Foundation
8
* (the "LGPL") or, at your option, under the terms of the Mozilla
9
* Public License Version 1.1 (the "MPL"). If you do not alter this
10
* notice, a recipient may use your version of this file under either
11
* the MPL or the LGPL.
13
* You should have received a copy of the LGPL along with this library
14
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
15
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16
* You should have received a copy of the MPL along with this library
17
* in the file COPYING-MPL-1.1
19
* The contents of this file are subject to the Mozilla Public License
20
* Version 1.1 (the "License"); you may not use this file except in
21
* compliance with the License. You may obtain a copy of the License at
22
* http://www.mozilla.org/MPL/
24
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
26
* the specific language governing rights and limitations.
28
* The Original Code is the cairo graphics library.
30
* The Initial Developer of the Original Code is Red Hat, Inc.
33
* Kristian Høgsberg <krh@redhat.com>
38
* http://partners.adobe.com/public/developer/en/font/T1_SPEC.PDF
42
#define _BSD_SOURCE /* for snprintf(), strdup() */
44
#include "cairo-error-private.h"
46
#if CAIRO_HAS_FONT_SUBSET
48
#include "cairo-type1-private.h"
49
#include "cairo-scaled-font-subsets-private.h"
50
#include "cairo-output-stream-private.h"
52
/* XXX: Eventually, we need to handle other font backends */
55
#include "cairo-ft-private.h"
58
#include FT_FREETYPE_H
60
#include FT_TYPE1_TABLES_H
64
typedef struct _cairo_type1_font_subset {
65
cairo_scaled_font_subset_t *scaled_font_subset;
68
cairo_unscaled_font_t *unscaled_font;
71
unsigned int num_glyphs;
72
long x_min, y_min, x_max, y_max;
76
unsigned long header_size;
77
unsigned long data_size;
78
unsigned long trailer_size;
90
cairo_output_stream_t *output;
91
cairo_array_t contents;
96
unsigned int type1_length;
100
int header_segment_size;
102
int eexec_segment_size;
103
cairo_bool_t eexec_segment_is_ascii;
110
unsigned short eexec_key;
111
cairo_bool_t hex_encode;
113
} cairo_type1_font_subset_t;
116
static cairo_status_t
117
_cairo_type1_font_subset_init (cairo_type1_font_subset_t *font,
118
cairo_unscaled_font_t *unscaled_font,
119
cairo_bool_t hex_encode)
121
cairo_ft_unscaled_font_t *ft_unscaled_font;
122
cairo_status_t status;
124
PS_FontInfoRec font_info;
127
ft_unscaled_font = (cairo_ft_unscaled_font_t *) unscaled_font;
129
face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
130
if (unlikely (face == NULL))
131
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
133
if (FT_Get_PS_Font_Info(face, &font_info) != 0) {
134
status = CAIRO_INT_STATUS_UNSUPPORTED;
138
/* OpenType/CFF fonts also have a PS_FontInfoRec */
139
#if HAVE_FT_LOAD_SFNT_TABLE
140
if (FT_IS_SFNT (face)) {
141
status = CAIRO_INT_STATUS_UNSUPPORTED;
146
memset (font, 0, sizeof (*font));
147
font->base.unscaled_font = _cairo_unscaled_font_reference (unscaled_font);
148
font->base.num_glyphs = face->num_glyphs;
149
font->base.x_min = face->bbox.xMin;
150
font->base.y_min = face->bbox.yMin;
151
font->base.x_max = face->bbox.xMax;
152
font->base.y_max = face->bbox.yMax;
153
font->base.ascent = face->ascender;
154
font->base.descent = face->descender;
156
if (face->family_name) {
157
font->base.base_font = strdup (face->family_name);
158
if (unlikely (font->base.base_font == NULL)) {
159
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
162
for (i = 0, j = 0; font->base.base_font[j]; j++) {
163
if (font->base.base_font[j] == ' ')
165
font->base.base_font[i++] = font->base.base_font[j];
167
font->base.base_font[i] = '\0';
170
font->glyphs = calloc (face->num_glyphs, sizeof font->glyphs[0]);
171
if (unlikely (font->glyphs == NULL)) {
172
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
176
font->hex_encode = hex_encode;
177
font->num_glyphs = 0;
178
for (i = 0; i < face->num_glyphs; i++)
179
font->glyphs[i].subset_index = -1;
181
_cairo_array_init (&font->contents, sizeof (char));
183
_cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
185
return CAIRO_STATUS_SUCCESS;
188
if (font->base.base_font)
189
free (font->base.base_font);
191
_cairo_unscaled_font_destroy (unscaled_font);
193
_cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
199
cairo_type1_font_subset_use_glyph (cairo_type1_font_subset_t *font, int glyph)
201
if (font->glyphs[glyph].subset_index >= 0)
204
font->glyphs[glyph].subset_index = font->num_glyphs++;
208
is_ps_delimiter(int c)
210
static const char delimiters[] = "()[]{}<>/% \t\r\n";
212
return strchr (delimiters, c) != NULL;
216
find_token (const char *buffer, const char *end, const char *token)
219
/* FIXME: find substring really must be find_token */
224
length = strlen (token);
225
for (i = 0; buffer + i < end - length + 1; i++)
226
if (memcmp (buffer + i, token, length) == 0)
227
if ((i == 0 || token[0] == '/' || is_ps_delimiter(buffer[i - 1])) &&
228
(buffer + i == end - length || is_ps_delimiter(buffer[i + length])))
234
static cairo_status_t
235
cairo_type1_font_subset_find_segments (cairo_type1_font_subset_t *font)
238
const char *eexec_token;
241
p = (unsigned char *) font->type1_data;
242
font->type1_end = font->type1_data + font->type1_length;
243
if (p[0] == 0x80 && p[1] == 0x01) {
244
font->header_segment_size =
245
p[2] | (p[3] << 8) | (p[4] << 16) | (p[5] << 24);
246
font->header_segment = (char *) p + 6;
248
p += 6 + font->header_segment_size;
249
font->eexec_segment_size =
250
p[2] | (p[3] << 8) | (p[4] << 16) | (p[5] << 24);
251
font->eexec_segment = (char *) p + 6;
252
font->eexec_segment_is_ascii = (p[1] == 1);
254
p += 6 + font->eexec_segment_size;
255
while (p < (unsigned char *) (font->type1_end) && p[1] != 0x03) {
256
size = p[2] | (p[3] << 8) | (p[4] << 16) | (p[5] << 24);
259
font->type1_end = (char *) p;
261
eexec_token = find_token ((char *) p, font->type1_end, "eexec");
262
if (eexec_token == NULL)
263
return CAIRO_INT_STATUS_UNSUPPORTED;
265
font->header_segment_size = eexec_token - (char *) p + strlen ("eexec\n");
266
font->header_segment = (char *) p;
267
font->eexec_segment_size = font->type1_length - font->header_segment_size;
268
font->eexec_segment = (char *) p + font->header_segment_size;
269
font->eexec_segment_is_ascii = TRUE;
270
for (i = 0; i < 4; i++) {
271
if (!isxdigit(font->eexec_segment[i]))
272
font->eexec_segment_is_ascii = FALSE;
276
return CAIRO_STATUS_SUCCESS;
279
/* Search for the definition of key and erase it by overwriting with spaces.
280
* This function is looks for definitions of the form:
283
* /key2 [12 34 56] def
285
* ie a key defined as an integer or array of integers.
289
cairo_type1_font_erase_dict_key (cairo_type1_font_subset_t *font,
292
const char *start, *p, *segment_end;
294
segment_end = font->header_segment + font->header_segment_size;
296
start = font->header_segment;
298
start = find_token (start, segment_end, key);
300
p = start + strlen(key);
301
/* skip integers or array of integers */
302
while (p < segment_end &&
303
(_cairo_isspace(*p) ||
304
_cairo_isdigit(*p) ||
311
if (p + 3 < segment_end && memcmp(p, "def", 3) == 0) {
312
/* erase definition of the key */
313
memset((char *) start, ' ', p + 3 - start);
315
start += strlen(key);
320
static cairo_status_t
321
cairo_type1_font_subset_write_header (cairo_type1_font_subset_t *font,
324
const char *start, *end, *segment_end;
328
* This function assumes that /FontName always appears
329
* before /Encoding. This appears to always be the case with Type1
332
* The more recently added code for removing the UniqueID and XUID
333
* keys can not make any assumptions about the position of the
334
* keys in the dictionary so it is implemented by overwriting the
335
* key definition with spaces before we start copying the font to
338
* This code should be rewritten to not make any assumptions about
339
* the order of dictionary keys. This will allow UniqueID to be
340
* stripped out instead of leaving a bunch of spaces in the
343
cairo_type1_font_erase_dict_key (font, "/UniqueID");
344
cairo_type1_font_erase_dict_key (font, "/XUID");
346
segment_end = font->header_segment + font->header_segment_size;
348
/* Type 1 fonts created by Fontforge have some PostScript code at
349
* the start of the font that skips the font if the printer has a
350
* cached copy of the font with the same unique id. This breaks
351
* our subsetted font so we disable it by searching for the
352
* PostScript operator "known" when used to check for the
353
* "/UniqueID" dictionary key. We append " pop false " after it to
354
* pop the result of this check off the stack and replace it with
355
* "false" to make the PostScript code think "/UniqueID" does not
358
end = font->header_segment;
359
start = find_token (font->header_segment, segment_end, "/UniqueID");
362
while (start < segment_end && _cairo_isspace (*start))
364
if (start + 5 < segment_end && memcmp(start, "known", 5) == 0) {
365
_cairo_output_stream_write (font->output, font->header_segment,
366
start + 5 - font->header_segment);
367
_cairo_output_stream_printf (font->output, " pop false ");
372
start = find_token (end, segment_end, "/FontName");
374
return CAIRO_INT_STATUS_UNSUPPORTED;
376
_cairo_output_stream_write (font->output, end,
379
_cairo_output_stream_printf (font->output, "/FontName /%s def", name);
381
end = find_token (start, segment_end, "def");
383
return CAIRO_INT_STATUS_UNSUPPORTED;
386
start = find_token (end, segment_end, "/Encoding");
388
return CAIRO_INT_STATUS_UNSUPPORTED;
389
_cairo_output_stream_write (font->output, end, start - end);
391
_cairo_output_stream_printf (font->output,
392
"/Encoding 256 array\n"
393
"0 1 255 {1 index exch /.notdef put} for\n");
394
for (i = 1; i < font->base.num_glyphs; i++) {
395
if (font->glyphs[i].subset_index < 0)
397
_cairo_output_stream_printf (font->output,
399
font->glyphs[i].subset_index,
400
font->glyphs[i].name);
402
_cairo_output_stream_printf (font->output, "readonly def");
404
end = find_token (start, segment_end, "def");
406
return CAIRO_INT_STATUS_UNSUPPORTED;
409
_cairo_output_stream_write (font->output, end, segment_end - end);
411
return font->output->status;
420
return ch - 'A' + 10;
422
return ch - 'a' + 10;
425
static cairo_status_t
426
cairo_type1_font_subset_write_encrypted (cairo_type1_font_subset_t *font,
427
const char *data, unsigned int length)
429
const unsigned char *in, *end;
431
static const char hex_digits[16] = "0123456789abcdef";
434
in = (const unsigned char *) data;
435
end = (const unsigned char *) data + length;
438
c = p ^ (font->eexec_key >> 8);
439
font->eexec_key = (c + font->eexec_key) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
441
if (font->hex_encode) {
442
digits[0] = hex_digits[c >> 4];
443
digits[1] = hex_digits[c & 0x0f];
445
font->hex_column += 2;
447
if (font->hex_column == 78) {
448
_cairo_output_stream_write (font->output, digits, 3);
449
font->hex_column = 0;
451
_cairo_output_stream_write (font->output, digits, 2);
455
_cairo_output_stream_write (font->output, digits, 1);
459
return font->output->status;
462
static cairo_status_t
463
cairo_type1_font_subset_decrypt_eexec_segment (cairo_type1_font_subset_t *font)
465
unsigned short r = CAIRO_TYPE1_PRIVATE_DICT_KEY;
466
unsigned char *in, *end;
471
in = (unsigned char *) font->eexec_segment;
472
end = (unsigned char *) in + font->eexec_segment_size;
474
font->cleartext = malloc (font->eexec_segment_size);
475
if (unlikely (font->cleartext == NULL))
476
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
478
out = font->cleartext;
480
if (font->eexec_segment_is_ascii) {
482
if (_cairo_isspace (c))
484
c = (hex_to_int (c) << 4) | hex_to_int (*in++);
489
r = (c + r) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
493
font->cleartext_end = out;
495
/* Overwrite random bytes with spaces.
497
* The first 4 bytes of the cleartext are the random bytes
498
* required by the encryption algorithm. When encrypting the
499
* cleartext, the first ciphertext byte must not be a white space
500
* character and the first 4 bytes must not be an ASCII Hex
501
* character. Some fonts do not check that their randomly chosen
502
* bytes results in ciphertext that complies with this
503
* restriction. This may cause problems for some PDF consumers. By
504
* replacing the random bytes with spaces, the first four bytes of
505
* ciphertext will always be 0xf9, 0x83, 0xef, 0x00 which complies
506
* with this restriction. Using spaces also means we don't have to
507
* skip over the random bytes when parsing the cleartext.
509
for (i = 0; i < 4 && i < font->eexec_segment_size; i++)
510
font->cleartext[i] = ' ';
512
return CAIRO_STATUS_SUCCESS;
516
skip_token (const char *p, const char *end)
518
while (p < end && _cairo_isspace(*p))
521
while (p < end && !_cairo_isspace(*p))
531
cairo_type1_font_subset_lookup_glyph (cairo_type1_font_subset_t *font,
532
const char *glyph_name, int length)
536
for (i = 0; i < font->base.num_glyphs; i++) {
537
if (font->glyphs[i].name &&
538
strncmp (font->glyphs[i].name, glyph_name, length) == 0 &&
539
font->glyphs[i].name[length] == '\0')
546
static cairo_status_t
547
cairo_type1_font_subset_get_glyph_names_and_widths (cairo_type1_font_subset_t *font)
553
/* Get glyph names and width using the freetype API */
554
for (i = 0; i < font->base.num_glyphs; i++) {
555
if (font->glyphs[i].name != NULL)
558
error = FT_Load_Glyph (font->face, i,
559
FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING |
560
FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
561
if (error != FT_Err_Ok) {
562
/* propagate fatal errors from FreeType */
563
if (error == FT_Err_Out_Of_Memory)
564
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
566
return CAIRO_INT_STATUS_UNSUPPORTED;
569
font->glyphs[i].width = font->face->glyph->linearHoriAdvance / 65536.0; /* 16.16 format */
571
error = FT_Get_Glyph_Name(font->face, i, buffer, sizeof buffer);
572
if (error != FT_Err_Ok) {
573
/* propagate fatal errors from FreeType */
574
if (error == FT_Err_Out_Of_Memory)
575
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
577
return CAIRO_INT_STATUS_UNSUPPORTED;
580
font->glyphs[i].name = strdup (buffer);
581
if (unlikely (font->glyphs[i].name == NULL))
582
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
585
return CAIRO_STATUS_SUCCESS;
589
cairo_type1_font_subset_decrypt_charstring (const unsigned char *in, int size, unsigned char *out)
591
unsigned short r = CAIRO_TYPE1_CHARSTRING_KEY;
594
for (i = 0; i < size; i++) {
597
r = (c + r) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
602
static const unsigned char *
603
cairo_type1_font_subset_decode_integer (const unsigned char *p, int *integer)
606
*integer = *p++ - 139;
607
} else if (*p <= 250) {
608
*integer = (p[0] - 247) * 256 + p[1] + 108;
610
} else if (*p <= 254) {
611
*integer = -(p[0] - 251) * 256 - p[1] - 108;
614
*integer = (p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4];
623
* The two tables that follow are generated using this perl code:
628
NULL, NULL, NULL, NULL,
629
NULL, NULL, NULL, NULL,
630
NULL, NULL, NULL, NULL,
631
NULL, NULL, NULL, NULL,
633
NULL, NULL, NULL, NULL,
634
NULL, NULL, NULL, NULL,
635
NULL, NULL, NULL, NULL,
636
NULL, NULL, NULL, NULL,
638
"space", "exclam", "quotedbl", "numbersign",
639
"dollar", "percent", "ampersand", "quoteright",
640
"parenleft", "parenright", "asterisk", "plus",
641
"comma", "hyphen", "period", "slash",
643
"zero", "one", "two", "three",
644
"four", "five", "six", "seven",
645
"eight", "nine", "colon", "semicolon",
646
"less", "equal", "greater", "question",
655
"X", "Y", "Z", "bracketleft",
656
"backslash", "bracketright", "asciicircum", "underscore",
658
"quoteleft", "a", "b", "c",
665
"x", "y", "z", "braceleft",
666
"bar", "braceright", "asciitilde", NULL,
668
NULL, NULL, NULL, NULL,
669
NULL, NULL, NULL, NULL,
670
NULL, NULL, NULL, NULL,
671
NULL, NULL, NULL, NULL,
673
NULL, NULL, NULL, NULL,
674
NULL, NULL, NULL, NULL,
675
NULL, NULL, NULL, NULL,
676
NULL, NULL, NULL, NULL,
678
NULL, "exclamdown", "cent", "sterling",
679
"fraction", "yen", "florin", "section",
680
"currency", "quotesingle", "quotedblleft", "guillemotleft",
681
"guilsinglleft","guilsinglright","fi", "fl",
683
NULL, "endash", "dagger", "daggerdbl",
684
"periodcentered",NULL, "paragraph", "bullet",
685
"quotesinglbase","quotedblbase","quotedblright","guillemotright",
686
"ellipsis", "perthousand", NULL, "questiondown",
688
NULL, "grave", "acute", "circumflex",
689
"tilde", "macron", "breve", "dotaccent",
690
"dieresis", NULL, "ring", "cedilla",
691
NULL, "hungarumlaut", "ogonek", "caron",
693
"emdash", NULL, NULL, NULL,
694
NULL, NULL, NULL, NULL,
695
NULL, NULL, NULL, NULL,
696
NULL, NULL, NULL, NULL,
698
NULL, "AE", NULL, "ordfeminine",
699
NULL, NULL, NULL, NULL,
700
"Lslash", "Oslash", "OE", "ordmasculine",
701
NULL, NULL, NULL, NULL,
703
NULL, "ae", NULL, NULL,
704
NULL, "dotlessi", NULL, NULL,
705
"lslash", "oslash", "oe", "germandbls",
706
NULL, NULL, NULL, NULL
709
print "static const char ps_standard_encoding_symbol[] = {\n";
711
for $sym (@encoding) {
712
if (! ($sym eq NULL)) {
713
$ss = qq( "$sym\\0");
714
if (length($s) + length($ss) > 78) {
723
print "static const int16_t ps_standard_encoding_offset[256] = {\n";
726
for $sym (@encoding) {
727
if (! ($sym eq NULL)) {
728
$ss = qq( $offset/*$sym*/,);
729
$offset += length($sym) + 1;
733
if (length($s) + length($ss) > 78) {
744
static const char ps_standard_encoding_symbol[] = {
745
"\0" "space\0" "exclam\0" "quotedbl\0" "numbersign\0" "dollar\0" "percent\0"
746
"ampersand\0" "quoteright\0" "parenleft\0" "parenright\0" "asterisk\0"
747
"plus\0" "comma\0" "hyphen\0" "period\0" "slash\0" "zero\0" "one\0" "two\0"
748
"three\0" "four\0" "five\0" "six\0" "seven\0" "eight\0" "nine\0" "colon\0"
749
"semicolon\0" "less\0" "equal\0" "greater\0" "question\0" "at\0" "A\0" "B\0"
750
"C\0" "D\0" "E\0" "F\0" "G\0" "H\0" "I\0" "J\0" "K\0" "L\0" "M\0" "N\0" "O\0"
751
"P\0" "Q\0" "R\0" "S\0" "T\0" "U\0" "V\0" "W\0" "X\0" "Y\0" "Z\0"
752
"bracketleft\0" "backslash\0" "bracketright\0" "asciicircum\0" "underscore\0"
753
"quoteleft\0" "a\0" "b\0" "c\0" "d\0" "e\0" "f\0" "g\0" "h\0" "i\0" "j\0"
754
"k\0" "l\0" "m\0" "n\0" "o\0" "p\0" "q\0" "r\0" "s\0" "t\0" "u\0" "v\0" "w\0"
755
"x\0" "y\0" "z\0" "braceleft\0" "bar\0" "braceright\0" "asciitilde\0"
756
"exclamdown\0" "cent\0" "sterling\0" "fraction\0" "yen\0" "florin\0"
757
"section\0" "currency\0" "quotesingle\0" "quotedblleft\0" "guillemotleft\0"
758
"guilsinglleft\0" "guilsinglright\0" "fi\0" "fl\0" "endash\0" "dagger\0"
759
"daggerdbl\0" "periodcentered\0" "paragraph\0" "bullet\0" "quotesinglbase\0"
760
"quotedblbase\0" "quotedblright\0" "guillemotright\0" "ellipsis\0"
761
"perthousand\0" "questiondown\0" "grave\0" "acute\0" "circumflex\0" "tilde\0"
762
"macron\0" "breve\0" "dotaccent\0" "dieresis\0" "ring\0" "cedilla\0"
763
"hungarumlaut\0" "ogonek\0" "caron\0" "emdash\0" "AE\0" "ordfeminine\0"
764
"Lslash\0" "Oslash\0" "OE\0" "ordmasculine\0" "ae\0" "dotlessi\0" "lslash\0"
765
"oslash\0" "oe\0" "germandbls\0"
768
static const int16_t ps_standard_encoding_offset[256] = {
769
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
770
0, 0, 0, 0, 0, 0, 1/*space*/, 7/*exclam*/, 14/*quotedbl*/, 23/*numbersign*/,
771
34/*dollar*/, 41/*percent*/, 49/*ampersand*/, 59/*quoteright*/,
772
70/*parenleft*/, 80/*parenright*/, 91/*asterisk*/, 100/*plus*/, 105/*comma*/,
773
111/*hyphen*/, 118/*period*/, 125/*slash*/, 131/*zero*/, 136/*one*/,
774
140/*two*/, 144/*three*/, 150/*four*/, 155/*five*/, 160/*six*/, 164/*seven*/,
775
170/*eight*/, 176/*nine*/, 181/*colon*/, 187/*semicolon*/, 197/*less*/,
776
202/*equal*/, 208/*greater*/, 216/*question*/, 225/*at*/, 228/*A*/, 230/*B*/,
777
232/*C*/, 234/*D*/, 236/*E*/, 238/*F*/, 240/*G*/, 242/*H*/, 244/*I*/,
778
246/*J*/, 248/*K*/, 250/*L*/, 252/*M*/, 254/*N*/, 256/*O*/, 258/*P*/,
779
260/*Q*/, 262/*R*/, 264/*S*/, 266/*T*/, 268/*U*/, 270/*V*/, 272/*W*/,
780
274/*X*/, 276/*Y*/, 278/*Z*/, 280/*bracketleft*/, 292/*backslash*/,
781
302/*bracketright*/, 315/*asciicircum*/, 327/*underscore*/, 338/*quoteleft*/,
782
348/*a*/, 350/*b*/, 352/*c*/, 354/*d*/, 356/*e*/, 358/*f*/, 360/*g*/,
783
362/*h*/, 364/*i*/, 366/*j*/, 368/*k*/, 370/*l*/, 372/*m*/, 374/*n*/,
784
376/*o*/, 378/*p*/, 380/*q*/, 382/*r*/, 384/*s*/, 386/*t*/, 388/*u*/,
785
390/*v*/, 392/*w*/, 394/*x*/, 396/*y*/, 398/*z*/, 400/*braceleft*/,
786
410/*bar*/, 414/*braceright*/, 425/*asciitilde*/, 0, 0, 0, 0, 0, 0, 0, 0, 0,
787
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
788
436/*exclamdown*/, 447/*cent*/, 452/*sterling*/, 461/*fraction*/, 470/*yen*/,
789
474/*florin*/, 481/*section*/, 489/*currency*/, 498/*quotesingle*/,
790
510/*quotedblleft*/, 523/*guillemotleft*/, 537/*guilsinglleft*/,
791
551/*guilsinglright*/, 566/*fi*/, 569/*fl*/, 0, 572/*endash*/, 579/*dagger*/,
792
586/*daggerdbl*/, 596/*periodcentered*/, 0, 611/*paragraph*/, 621/*bullet*/,
793
628/*quotesinglbase*/, 643/*quotedblbase*/, 656/*quotedblright*/,
794
670/*guillemotright*/, 685/*ellipsis*/, 694/*perthousand*/, 0,
795
706/*questiondown*/, 0, 719/*grave*/, 725/*acute*/, 731/*circumflex*/,
796
742/*tilde*/, 748/*macron*/, 755/*breve*/, 761/*dotaccent*/, 771/*dieresis*/,
797
0, 780/*ring*/, 785/*cedilla*/, 0, 793/*hungarumlaut*/, 806/*ogonek*/,
798
813/*caron*/, 819/*emdash*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
799
826/*AE*/, 0, 829/*ordfeminine*/, 0, 0, 0, 0, 841/*Lslash*/, 848/*Oslash*/,
800
855/*OE*/, 858/*ordmasculine*/, 0, 0, 0, 0, 0, 871/*ae*/, 0, 0, 0,
801
874/*dotlessi*/, 0, 0, 883/*lslash*/, 890/*oslash*/, 897/*oe*/,
802
900/*germandbls*/, 0, 0, 0, 0,
805
#define ps_standard_encoding(index) ((index) ? ps_standard_encoding_symbol+ps_standard_encoding_offset[(index)] : NULL)
807
static cairo_status_t
808
use_standard_encoding_glyph (cairo_type1_font_subset_t *font, int index)
810
const char *glyph_name;
812
if (index < 0 || index > 255)
813
return CAIRO_STATUS_SUCCESS;
815
glyph_name = ps_standard_encoding(index);
816
if (glyph_name == NULL)
817
return CAIRO_STATUS_SUCCESS;
819
index = cairo_type1_font_subset_lookup_glyph (font,
823
return CAIRO_INT_STATUS_UNSUPPORTED;
825
cairo_type1_font_subset_use_glyph (font, index);
827
return CAIRO_STATUS_SUCCESS;
830
#define TYPE1_CHARSTRING_COMMAND_ESCAPE (12)
831
#define TYPE1_CHARSTRING_COMMAND_SEAC (32 + 6)
833
static cairo_status_t
834
cairo_type1_font_subset_look_for_seac(cairo_type1_font_subset_t *font,
835
const char *name, int name_length,
836
const char *encrypted_charstring, int encrypted_charstring_length)
838
cairo_status_t status;
839
unsigned char *charstring;
840
const unsigned char *end;
841
const unsigned char *p;
842
int stack[5], sp, value;
845
charstring = malloc (encrypted_charstring_length);
846
if (unlikely (charstring == NULL))
847
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
849
cairo_type1_font_subset_decrypt_charstring ((const unsigned char *)
850
encrypted_charstring,
851
encrypted_charstring_length,
853
end = charstring + encrypted_charstring_length;
862
if (command == TYPE1_CHARSTRING_COMMAND_ESCAPE)
866
case TYPE1_CHARSTRING_COMMAND_SEAC:
867
/* The seac command takes five integer arguments. The
868
* last two are glyph indices into the PS standard
869
* encoding give the names of the glyphs that this
870
* glyph is composed from. All we need to do is to
871
* make sure those glyphs are present in the subset
872
* under their standard names. */
873
status = use_standard_encoding_glyph (font, stack[3]);
874
if (unlikely (status))
877
status = use_standard_encoding_glyph (font, stack[4]);
878
if (unlikely (status))
889
/* integer argument */
890
p = cairo_type1_font_subset_decode_integer (p, &value);
898
return CAIRO_STATUS_SUCCESS;
901
static cairo_status_t
902
write_used_glyphs (cairo_type1_font_subset_t *font,
903
const char *name, int name_length,
904
const char *charstring, int charstring_length)
906
cairo_status_t status;
910
length = snprintf (buffer, sizeof buffer,
912
name_length, name, charstring_length, font->rd);
913
status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
914
if (unlikely (status))
917
status = cairo_type1_font_subset_write_encrypted (font,
920
if (unlikely (status))
923
length = snprintf (buffer, sizeof buffer, "%s\n", font->nd);
924
status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
925
if (unlikely (status))
928
return CAIRO_STATUS_SUCCESS;
931
typedef cairo_status_t (*glyph_func_t) (cairo_type1_font_subset_t *font,
932
const char *name, int name_length,
933
const char *charstring, int charstring_length);
935
static cairo_status_t
936
cairo_type1_font_subset_for_each_glyph (cairo_type1_font_subset_t *font,
937
const char *dict_start,
938
const char *dict_end,
940
const char **dict_out)
942
int charstring_length, name_length, glyph_index;
943
const char *p, *charstring, *name;
946
/* We're looking at '/' in the name of the first glyph. The glyph
947
* definitions are on the form:
949
* /name 23 RD <23 binary bytes> ND
951
* or alternatively using -| and |- instead of RD and ND.
953
* We parse the glyph name and see if it is in the subset. If it
954
* is, we call the specified callback with the glyph name and
955
* glyph data, otherwise we just skip it. We need to parse
956
* through a glyph definition; we can't just find the next '/',
957
* since the binary data could contain a '/'.
964
p = skip_token (p, dict_end);
965
name_length = p - name;
967
charstring_length = strtol (p, &end, 10);
969
return CAIRO_INT_STATUS_UNSUPPORTED;
971
/* Skip past -| or RD to binary data. There is exactly one space
972
* between the -| or RD token and the encrypted data, thus '+ 1'. */
973
charstring = skip_token (end, dict_end) + 1;
975
/* Skip binary data and |- or ND token. */
976
p = skip_token (charstring + charstring_length, dict_end);
977
while (p < dict_end && _cairo_isspace(*p))
980
/* In case any of the skip_token() calls above reached EOF, p will
981
* be equal to dict_end. */
983
return CAIRO_INT_STATUS_UNSUPPORTED;
985
glyph_index = cairo_type1_font_subset_lookup_glyph (font,
987
if (font->glyphs[glyph_index].subset_index >= 0) {
988
cairo_status_t status = func (font,
990
charstring, charstring_length);
991
if (unlikely (status))
998
return CAIRO_STATUS_SUCCESS;
1002
static cairo_status_t
1003
cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
1006
cairo_status_t status;
1007
const char *p, *charstrings, *dict_start;
1008
const char *closefile_token;
1009
char buffer[32], *glyph_count_end;
1010
int num_charstrings, length;
1012
/* The private dict holds hint information, common subroutines and
1013
* the actual glyph definitions (charstrings).
1015
* FIXME: update this comment.
1017
* What we do here is scan directly the /CharString token, which
1018
* marks the beginning of the glyph definitions. Then we parse
1019
* through the glyph definitions and weed out the glyphs not in
1020
* our subset. Everything else before and after the glyph
1021
* definitions is copied verbatim to the output. It might be
1022
* worthwile to figure out which of the common subroutines are
1023
* used by the glyphs in the subset and get rid of the rest. */
1025
/* FIXME: The /Subrs array contains binary data and could
1026
* conceivably have "/CharStrings" in it, so we might need to skip
1027
* this more cleverly. */
1028
charstrings = find_token (font->cleartext, font->cleartext_end, "/CharStrings");
1029
if (charstrings == NULL)
1030
return CAIRO_INT_STATUS_UNSUPPORTED;
1032
/* Scan past /CharStrings and the integer following it. */
1033
p = charstrings + strlen ("/CharStrings");
1034
num_charstrings = strtol (p, &glyph_count_end, 10);
1035
if (p == glyph_count_end)
1036
return CAIRO_INT_STATUS_UNSUPPORTED;
1038
/* Look for a '/' which marks the beginning of the first glyph
1040
for (p = glyph_count_end; p < font->cleartext_end; p++)
1043
if (p == font->cleartext_end)
1044
return CAIRO_INT_STATUS_UNSUPPORTED;
1047
status = cairo_type1_font_subset_get_glyph_names_and_widths (font);
1048
if (unlikely (status))
1051
/* Now that we have the private dictionary broken down in
1052
* sections, do the first pass through the glyph definitions to
1053
* figure out which subrs and othersubrs are use and which extra
1054
* glyphs may be required by the seac operator. */
1055
status = cairo_type1_font_subset_for_each_glyph (font,
1057
font->cleartext_end,
1058
cairo_type1_font_subset_look_for_seac,
1060
if (unlikely (status))
1063
closefile_token = find_token (p, font->cleartext_end, "closefile");
1064
if (closefile_token == NULL)
1065
return CAIRO_INT_STATUS_UNSUPPORTED;
1067
status = cairo_type1_font_subset_get_glyph_names_and_widths (font);
1068
if (unlikely (status))
1071
/* We're ready to start outputting. First write the header,
1072
* i.e. the public part of the font dict.*/
1073
status = cairo_type1_font_subset_write_header (font, name);
1074
if (unlikely (status))
1077
font->base.header_size = _cairo_output_stream_get_position (font->output);
1080
/* Start outputting the private dict. First output everything up
1081
* to the /CharStrings token. */
1082
status = cairo_type1_font_subset_write_encrypted (font, font->cleartext,
1083
charstrings - font->cleartext);
1084
if (unlikely (status))
1087
/* Write out new charstring count */
1088
length = snprintf (buffer, sizeof buffer,
1089
"/CharStrings %d", font->num_glyphs);
1090
status = cairo_type1_font_subset_write_encrypted (font, buffer, length);
1091
if (unlikely (status))
1094
/* Write out text between the charstring count and the first
1095
* charstring definition */
1096
status = cairo_type1_font_subset_write_encrypted (font, glyph_count_end,
1097
dict_start - glyph_count_end);
1098
if (unlikely (status))
1101
/* Write out the charstring definitions for each of the glyphs in
1103
status = cairo_type1_font_subset_for_each_glyph (font,
1105
font->cleartext_end,
1108
if (unlikely (status))
1111
/* Output what's left between the end of the glyph definitions and
1112
* the end of the private dict to the output. */
1113
status = cairo_type1_font_subset_write_encrypted (font, p,
1114
closefile_token - p + strlen ("closefile") + 1);
1115
if (unlikely (status))
1118
if (font->hex_encode)
1119
_cairo_output_stream_write (font->output, "\n", 1);
1121
return CAIRO_STATUS_SUCCESS;
1124
static cairo_status_t
1125
cairo_type1_font_subset_write_trailer(cairo_type1_font_subset_t *font)
1127
const char *cleartomark_token;
1129
static const char zeros[65] =
1130
"0000000000000000000000000000000000000000000000000000000000000000\n";
1133
for (i = 0; i < 8; i++)
1134
_cairo_output_stream_write (font->output, zeros, sizeof zeros);
1136
cleartomark_token = find_token (font->type1_data, font->type1_end, "cleartomark");
1137
if (cleartomark_token) {
1138
/* Some fonts have conditional save/restore around the entire
1139
* font dict, so we need to retain whatever postscript code
1140
* that may come after 'cleartomark'. */
1142
_cairo_output_stream_write (font->output, cleartomark_token,
1143
font->type1_end - cleartomark_token);
1144
} else if (!font->eexec_segment_is_ascii) {
1145
/* Fonts embedded in PDF may omit the fixed-content portion
1146
* that includes the 'cleartomark' operator. Type 1 in PDF is
1149
_cairo_output_stream_printf (font->output, "cleartomark");
1151
return CAIRO_INT_STATUS_UNSUPPORTED;
1154
/* some fonts do not have a newline at the end of the last line */
1155
_cairo_output_stream_printf (font->output, "\n");
1157
return CAIRO_STATUS_SUCCESS;
1160
static cairo_status_t
1161
type1_font_write (void *closure, const unsigned char *data, unsigned int length)
1163
cairo_type1_font_subset_t *font = closure;
1165
return _cairo_array_append_multiple (&font->contents, data, length);
1168
static cairo_status_t
1169
cairo_type1_font_subset_write (cairo_type1_font_subset_t *font,
1172
cairo_status_t status;
1174
status = cairo_type1_font_subset_find_segments (font);
1175
if (unlikely (status))
1178
status = cairo_type1_font_subset_decrypt_eexec_segment (font);
1179
if (unlikely (status))
1182
/* Determine which glyph definition delimiters to use. */
1183
if (find_token (font->cleartext, font->cleartext_end, "/-|") != NULL) {
1186
} else if (find_token (font->cleartext, font->cleartext_end, "/RD") != NULL) {
1190
/* Don't know *what* kind of font this is... */
1191
return CAIRO_INT_STATUS_UNSUPPORTED;
1194
font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY;
1195
font->hex_column = 0;
1197
status = cairo_type1_font_subset_write_private_dict (font, name);
1198
if (unlikely (status))
1201
font->base.data_size = _cairo_output_stream_get_position (font->output) -
1202
font->base.header_size;
1204
status = cairo_type1_font_subset_write_trailer (font);
1205
if (unlikely (status))
1208
font->base.trailer_size =
1209
_cairo_output_stream_get_position (font->output) -
1210
font->base.header_size - font->base.data_size;
1212
return CAIRO_STATUS_SUCCESS;
1215
static cairo_status_t
1216
cairo_type1_font_subset_generate (void *abstract_font,
1220
cairo_type1_font_subset_t *font = abstract_font;
1221
cairo_ft_unscaled_font_t *ft_unscaled_font;
1223
cairo_status_t status;
1225
ft_unscaled_font = (cairo_ft_unscaled_font_t *) font->base.unscaled_font;
1226
font->face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
1227
if (unlikely (font->face == NULL))
1228
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1230
font->type1_length = font->face->stream->size;
1231
font->type1_data = malloc (font->type1_length);
1232
if (unlikely (font->type1_data == NULL)) {
1233
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1237
if (font->face->stream->read != NULL) {
1238
/* Note that read() may be implemented as a macro, thanks POSIX!, so we
1239
* need to wrap the following usage in parentheses in order to
1240
* disambiguate it for the pre-processor - using the verbose function
1241
* pointer dereference for clarity.
1243
ret = (* font->face->stream->read) (font->face->stream, 0,
1244
(unsigned char *) font->type1_data,
1245
font->type1_length);
1246
if (ret != font->type1_length) {
1247
status = _cairo_error (CAIRO_STATUS_READ_ERROR);
1251
memcpy (font->type1_data,
1252
font->face->stream->base, font->type1_length);
1255
status = _cairo_array_grow_by (&font->contents, 4096);
1256
if (unlikely (status))
1259
font->output = _cairo_output_stream_create (type1_font_write, NULL, font);
1260
if (unlikely ((status = font->output->status)))
1263
status = cairo_type1_font_subset_write (font, name);
1264
if (unlikely (status))
1267
font->base.data = _cairo_array_index (&font->contents, 0);
1270
_cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
1275
static cairo_status_t
1276
_cairo_type1_font_subset_fini (cairo_type1_font_subset_t *font)
1278
cairo_status_t status = CAIRO_STATUS_SUCCESS;
1281
/* If the subset generation failed, some of the pointers below may
1282
* be NULL depending on at which point the error occurred. */
1284
_cairo_array_fini (&font->contents);
1286
free (font->type1_data);
1287
if (font->glyphs != NULL) {
1288
for (i = 0; i < font->base.num_glyphs; i++)
1289
free (font->glyphs[i].name);
1292
_cairo_unscaled_font_destroy (font->base.unscaled_font);
1294
if (font->output != NULL)
1295
status = _cairo_output_stream_destroy (font->output);
1297
if (font->base.base_font)
1298
free (font->base.base_font);
1299
free (font->glyphs);
1305
_cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
1307
cairo_scaled_font_subset_t *scaled_font_subset,
1308
cairo_bool_t hex_encode)
1310
cairo_type1_font_subset_t font;
1311
cairo_status_t status, status_ignored;
1312
unsigned long parent_glyph, length;
1314
cairo_unscaled_font_t *unscaled_font;
1317
/* XXX: Need to fix this to work with a general cairo_unscaled_font_t. */
1318
if (!_cairo_scaled_font_is_ft (scaled_font_subset->scaled_font))
1319
return CAIRO_INT_STATUS_UNSUPPORTED;
1321
if (_cairo_ft_scaled_font_is_vertical (scaled_font_subset->scaled_font))
1322
return CAIRO_INT_STATUS_UNSUPPORTED;
1324
unscaled_font = _cairo_ft_scaled_font_get_unscaled_font (scaled_font_subset->scaled_font);
1326
status = _cairo_type1_font_subset_init (&font, unscaled_font, hex_encode);
1327
if (unlikely (status))
1330
for (i = 0; i < scaled_font_subset->num_glyphs; i++) {
1331
parent_glyph = scaled_font_subset->glyphs[i];
1332
cairo_type1_font_subset_use_glyph (&font, parent_glyph);
1335
status = cairo_type1_font_subset_generate (&font, name);
1336
if (unlikely (status))
1339
if (font.base.base_font) {
1340
type1_subset->base_font = strdup (font.base.base_font);
1342
snprintf(buf, sizeof (buf), "CairoFont-%u-%u",
1343
scaled_font_subset->font_id, scaled_font_subset->subset_id);
1344
type1_subset->base_font = strdup (buf);
1346
if (unlikely (type1_subset->base_font == NULL))
1349
type1_subset->widths = calloc (sizeof (double), font.num_glyphs);
1350
if (unlikely (type1_subset->widths == NULL))
1352
for (i = 0; i < font.base.num_glyphs; i++) {
1353
if (font.glyphs[i].subset_index < 0)
1355
type1_subset->widths[font.glyphs[i].subset_index] =
1356
font.glyphs[i].width;
1359
type1_subset->x_min = font.base.x_min;
1360
type1_subset->y_min = font.base.y_min;
1361
type1_subset->x_max = font.base.x_max;
1362
type1_subset->y_max = font.base.y_max;
1363
type1_subset->ascent = font.base.ascent;
1364
type1_subset->descent = font.base.descent;
1366
length = font.base.header_size +
1367
font.base.data_size +
1368
font.base.trailer_size;
1369
type1_subset->data = malloc (length);
1370
if (unlikely (type1_subset->data == NULL))
1373
memcpy (type1_subset->data,
1374
_cairo_array_index (&font.contents, 0), length);
1376
type1_subset->header_length = font.base.header_size;
1377
type1_subset->data_length = font.base.data_size;
1378
type1_subset->trailer_length = font.base.trailer_size;
1380
return _cairo_type1_font_subset_fini (&font);
1383
free (type1_subset->widths);
1385
free (type1_subset->base_font);
1387
status_ignored = _cairo_type1_font_subset_fini (&font);
1393
_cairo_type1_subset_fini (cairo_type1_subset_t *subset)
1395
free (subset->base_font);
1396
free (subset->widths);
1397
free (subset->data);
1401
_cairo_type1_scaled_font_is_type1 (cairo_scaled_font_t *scaled_font)
1403
cairo_ft_unscaled_font_t *unscaled;
1405
PS_FontInfoRec font_info;
1406
cairo_bool_t is_type1 = FALSE;
1408
if (!_cairo_scaled_font_is_ft (scaled_font))
1410
unscaled = (cairo_ft_unscaled_font_t *) _cairo_ft_scaled_font_get_unscaled_font (scaled_font);
1411
face = _cairo_ft_unscaled_font_lock_face (unscaled);
1415
if (FT_Get_PS_Font_Info(face, &font_info) == 0)
1418
/* OpenType/CFF fonts also have a PS_FontInfoRec */
1419
#if HAVE_FT_LOAD_SFNT_TABLE
1420
if (FT_IS_SFNT (face))
1424
_cairo_ft_unscaled_font_unlock_face (unscaled);
1429
#endif /* CAIRO_HAS_FT_FONT */
1431
#endif /* CAIRO_HAS_FONT_SUBSET */