Subversion Repositories Kolibri OS

Rev

Rev 1897 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1897 Rev 3959
1
/* cairo - a vector graphics library with display and print output
1
/* cairo - a vector graphics library with display and print output
2
 *
2
 *
3
 * Copyright © 2006 Red Hat, Inc
3
 * Copyright © 2006 Red Hat, Inc
4
 *
4
 *
5
 * This library is free software; you can redistribute it and/or
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
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
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
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
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
10
 * notice, a recipient may use your version of this file under either
11
 * the MPL or the LGPL.
11
 * the MPL or the LGPL.
12
 *
12
 *
13
 * You should have received a copy of the LGPL along with this library
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
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
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
16
 * You should have received a copy of the MPL along with this library
17
 * in the file COPYING-MPL-1.1
17
 * in the file COPYING-MPL-1.1
18
 *
18
 *
19
 * The contents of this file are subject to the Mozilla Public License
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
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
21
 * compliance with the License. You may obtain a copy of the License at
22
 * http://www.mozilla.org/MPL/
22
 * http://www.mozilla.org/MPL/
23
 *
23
 *
24
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
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
25
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26
 * the specific language governing rights and limitations.
26
 * the specific language governing rights and limitations.
27
 *
27
 *
28
 * The Original Code is the cairo graphics library.
28
 * The Original Code is the cairo graphics library.
29
 *
29
 *
30
 * The Initial Developer of the Original Code is Red Hat, Inc.
30
 * The Initial Developer of the Original Code is Red Hat, Inc.
31
 *
31
 *
32
 * Contributor(s):
32
 * Contributor(s):
33
 *	Adrian Johnson 
33
 *	Adrian Johnson 
34
 */
34
 */
35
 
35
 
36
#define _BSD_SOURCE /* for snprintf(), strdup() */
36
#define _BSD_SOURCE /* for snprintf(), strdup() */
37
#include "cairoint.h"
37
#include "cairoint.h"
-
 
38
 
-
 
39
#include "cairo-array-private.h"
38
#include "cairo-error-private.h"
40
#include "cairo-error-private.h"
39
 
41
 
40
#if CAIRO_HAS_FONT_SUBSET
42
#if CAIRO_HAS_FONT_SUBSET
41
 
43
 
42
#include "cairo-type1-private.h"
44
#include "cairo-type1-private.h"
43
#include "cairo-scaled-font-subsets-private.h"
45
#include "cairo-scaled-font-subsets-private.h"
44
#include "cairo-path-fixed-private.h"
46
#include "cairo-path-fixed-private.h"
45
#include "cairo-output-stream-private.h"
47
#include "cairo-output-stream-private.h"
46
 
48
 
47
typedef enum {
49
typedef enum {
48
    CAIRO_CHARSTRING_TYPE1,
50
    CAIRO_CHARSTRING_TYPE1,
49
    CAIRO_CHARSTRING_TYPE2
51
    CAIRO_CHARSTRING_TYPE2
50
} cairo_charstring_type_t;
52
} cairo_charstring_type_t;
51
 
53
 
52
typedef struct _cairo_type1_font {
54
typedef struct _cairo_type1_font {
53
    int *widths;
55
    int *widths;
54
 
56
 
55
    cairo_scaled_font_subset_t *scaled_font_subset;
57
    cairo_scaled_font_subset_t *scaled_font_subset;
56
    cairo_scaled_font_t        *type1_scaled_font;
58
    cairo_scaled_font_t        *type1_scaled_font;
57
 
59
 
58
    cairo_array_t contents;
60
    cairo_array_t contents;
59
 
61
 
60
    double x_min, y_min, x_max, y_max;
62
    double x_min, y_min, x_max, y_max;
61
 
63
 
62
    const char    *data;
64
    const char    *data;
63
    unsigned long  header_size;
65
    unsigned long  header_size;
64
    unsigned long  data_size;
66
    unsigned long  data_size;
65
    unsigned long  trailer_size;
67
    unsigned long  trailer_size;
66
    int            bbox_position;
68
    int            bbox_position;
67
    int            bbox_max_chars;
69
    int            bbox_max_chars;
68
 
70
 
69
    cairo_output_stream_t *output;
71
    cairo_output_stream_t *output;
70
 
72
 
71
    unsigned short eexec_key;
73
    unsigned short eexec_key;
72
    cairo_bool_t hex_encode;
74
    cairo_bool_t hex_encode;
73
    int hex_column;
75
    int hex_column;
74
} cairo_type1_font_t;
76
} cairo_type1_font_t;
75
 
77
 
76
static cairo_status_t
78
static cairo_status_t
77
cairo_type1_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
79
cairo_type1_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
78
                         cairo_type1_font_t         **subset_return,
80
                         cairo_type1_font_t         **subset_return,
79
                         cairo_bool_t                 hex_encode)
81
                         cairo_bool_t                 hex_encode)
80
{
82
{
81
    cairo_type1_font_t *font;
83
    cairo_type1_font_t *font;
82
    cairo_font_face_t *font_face;
84
    cairo_font_face_t *font_face;
83
    cairo_matrix_t font_matrix;
85
    cairo_matrix_t font_matrix;
84
    cairo_matrix_t ctm;
86
    cairo_matrix_t ctm;
85
    cairo_font_options_t font_options;
87
    cairo_font_options_t font_options;
86
    cairo_status_t status;
88
    cairo_status_t status;
87
 
89
 
88
    font = calloc (1, sizeof (cairo_type1_font_t));
90
    font = calloc (1, sizeof (cairo_type1_font_t));
89
    if (unlikely (font == NULL))
91
    if (unlikely (font == NULL))
90
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
92
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
91
 
93
 
92
    font->widths = calloc (scaled_font_subset->num_glyphs, sizeof (int));
94
    font->widths = calloc (scaled_font_subset->num_glyphs, sizeof (int));
93
    if (unlikely (font->widths == NULL)) {
95
    if (unlikely (font->widths == NULL)) {
94
	free (font);
96
	free (font);
95
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
97
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
96
    }
98
    }
97
 
99
 
98
    font->scaled_font_subset = scaled_font_subset;
100
    font->scaled_font_subset = scaled_font_subset;
99
    font->hex_encode = hex_encode;
101
    font->hex_encode = hex_encode;
100
 
102
 
101
    font_face = cairo_scaled_font_get_font_face (scaled_font_subset->scaled_font);
103
    font_face = cairo_scaled_font_get_font_face (scaled_font_subset->scaled_font);
102
 
104
 
103
    cairo_matrix_init_scale (&font_matrix, 1000, -1000);
105
    cairo_matrix_init_scale (&font_matrix, 1000, -1000);
104
    cairo_matrix_init_identity (&ctm);
106
    cairo_matrix_init_identity (&ctm);
105
 
107
 
106
    _cairo_font_options_init_default (&font_options);
108
    _cairo_font_options_init_default (&font_options);
107
    cairo_font_options_set_hint_style (&font_options, CAIRO_HINT_STYLE_NONE);
109
    cairo_font_options_set_hint_style (&font_options, CAIRO_HINT_STYLE_NONE);
108
    cairo_font_options_set_hint_metrics (&font_options, CAIRO_HINT_METRICS_OFF);
110
    cairo_font_options_set_hint_metrics (&font_options, CAIRO_HINT_METRICS_OFF);
109
 
111
 
110
    font->type1_scaled_font = cairo_scaled_font_create (font_face,
112
    font->type1_scaled_font = cairo_scaled_font_create (font_face,
111
							&font_matrix,
113
							&font_matrix,
112
							&ctm,
114
							&ctm,
113
							&font_options);
115
							&font_options);
114
    status = font->type1_scaled_font->status;
116
    status = font->type1_scaled_font->status;
115
    if (unlikely (status))
117
    if (unlikely (status))
116
        goto fail;
118
        goto fail;
117
 
119
 
118
    _cairo_array_init (&font->contents, sizeof (unsigned char));
120
    _cairo_array_init (&font->contents, sizeof (unsigned char));
119
    font->output = NULL;
121
    font->output = NULL;
120
 
122
 
121
    *subset_return = font;
123
    *subset_return = font;
122
 
124
 
123
    return CAIRO_STATUS_SUCCESS;
125
    return CAIRO_STATUS_SUCCESS;
124
 
126
 
125
fail:
127
fail:
126
    free (font->widths);
128
    free (font->widths);
127
    free (font);
129
    free (font);
128
 
130
 
129
    return status;
131
    return status;
130
}
132
}
131
 
133
 
132
/* Charstring commands. If the high byte is 0 the command is encoded
134
/* Charstring commands. If the high byte is 0 the command is encoded
133
 * with a single byte. */
135
 * with a single byte. */
134
#define CHARSTRING_sbw        0x0c07
136
#define CHARSTRING_sbw        0x0c07
135
#define CHARSTRING_rmoveto    0x0015
137
#define CHARSTRING_rmoveto    0x0015
136
#define CHARSTRING_rlineto    0x0005
138
#define CHARSTRING_rlineto    0x0005
137
#define CHARSTRING_rcurveto   0x0008
139
#define CHARSTRING_rcurveto   0x0008
138
#define CHARSTRING_closepath  0x0009
140
#define CHARSTRING_closepath  0x0009
139
#define CHARSTRING_endchar    0x000e
141
#define CHARSTRING_endchar    0x000e
140
 
142
 
141
/* Before calling this function, the caller must allocate sufficient
143
/* Before calling this function, the caller must allocate sufficient
142
 * space in data (see _cairo_array_grow_by). The maximum number of
144
 * space in data (see _cairo_array_grow_by). The maximum number of
143
 * bytes that will be used is 2.
145
 * bytes that will be used is 2.
144
 */
146
 */
145
static void
147
static void
146
charstring_encode_command (cairo_array_t *data, int command)
148
charstring_encode_command (cairo_array_t *data, int command)
147
{
149
{
148
    cairo_status_t status;
150
    cairo_status_t status;
149
    int orig_size;
151
    unsigned int orig_size;
150
    unsigned char buf[5];
152
    unsigned char buf[5];
151
    unsigned char *p = buf;
153
    unsigned char *p = buf;
152
 
154
 
153
    if (command & 0xff00)
155
    if (command & 0xff00)
154
        *p++ = command >> 8;
156
        *p++ = command >> 8;
155
    *p++ = command & 0x00ff;
157
    *p++ = command & 0x00ff;
156
 
158
 
157
    /* Ensure the array doesn't grow, which allows this function to
159
    /* Ensure the array doesn't grow, which allows this function to
158
     * have no possibility of failure. */
160
     * have no possibility of failure. */
159
    orig_size = _cairo_array_size (data);
161
    orig_size = _cairo_array_size (data);
160
    status = _cairo_array_append_multiple (data, buf, p - buf);
162
    status = _cairo_array_append_multiple (data, buf, p - buf);
161
 
163
 
162
    assert (status == CAIRO_STATUS_SUCCESS);
164
    assert (status == CAIRO_STATUS_SUCCESS);
163
    assert (_cairo_array_size (data) == orig_size);
165
    assert (_cairo_array_size (data) == orig_size);
164
}
166
}
165
 
167
 
166
/* Before calling this function, the caller must allocate sufficient
168
/* Before calling this function, the caller must allocate sufficient
167
 * space in data (see _cairo_array_grow_by). The maximum number of
169
 * space in data (see _cairo_array_grow_by). The maximum number of
168
 * bytes that will be used is 5.
170
 * bytes that will be used is 5.
169
 */
171
 */
170
static void
172
static void
171
charstring_encode_integer (cairo_array_t *data,
173
charstring_encode_integer (cairo_array_t *data,
172
                           int i,
174
                           int i,
173
                           cairo_charstring_type_t type)
175
                           cairo_charstring_type_t type)
174
{
176
{
175
    cairo_status_t status;
177
    cairo_status_t status;
176
    int orig_size;
178
    unsigned int orig_size;
177
    unsigned char buf[10];
179
    unsigned char buf[10];
178
    unsigned char *p = buf;
180
    unsigned char *p = buf;
179
 
181
 
180
    if (i >= -107 && i <= 107) {
182
    if (i >= -107 && i <= 107) {
181
        *p++ = i + 139;
183
        *p++ = i + 139;
182
    } else if (i >= 108 && i <= 1131) {
184
    } else if (i >= 108 && i <= 1131) {
183
        i -= 108;
185
        i -= 108;
184
        *p++ = (i >> 8)+ 247;
186
        *p++ = (i >> 8)+ 247;
185
        *p++ = i & 0xff;
187
        *p++ = i & 0xff;
186
    } else if (i >= -1131 && i <= -108) {
188
    } else if (i >= -1131 && i <= -108) {
187
        i = -i - 108;
189
        i = -i - 108;
188
        *p++ = (i >> 8)+ 251;
190
        *p++ = (i >> 8)+ 251;
189
        *p++ = i & 0xff;
191
        *p++ = i & 0xff;
190
    } else {
192
    } else {
191
        if (type == CAIRO_CHARSTRING_TYPE1) {
193
        if (type == CAIRO_CHARSTRING_TYPE1) {
192
            *p++ = 0xff;
194
            *p++ = 0xff;
193
            *p++ = i >> 24;
195
            *p++ = i >> 24;
194
            *p++ = (i >> 16) & 0xff;
196
            *p++ = (i >> 16) & 0xff;
195
            *p++ = (i >> 8)  & 0xff;
197
            *p++ = (i >> 8)  & 0xff;
196
            *p++ = i & 0xff;
198
            *p++ = i & 0xff;
197
        } else {
199
        } else {
198
            *p++ = 0xff;
200
            *p++ = 0xff;
199
            *p++ = (i >> 8)  & 0xff;
201
            *p++ = (i >> 8)  & 0xff;
200
            *p++ = i & 0xff;
202
            *p++ = i & 0xff;
201
            *p++ = 0;
203
            *p++ = 0;
202
            *p++ = 0;
204
            *p++ = 0;
203
        }
205
        }
204
    }
206
    }
205
 
207
 
206
    /* Ensure the array doesn't grow, which allows this function to
208
    /* Ensure the array doesn't grow, which allows this function to
207
     * have no possibility of failure. */
209
     * have no possibility of failure. */
208
    orig_size = _cairo_array_size (data);
210
    orig_size = _cairo_array_size (data);
209
    status = _cairo_array_append_multiple (data, buf, p - buf);
211
    status = _cairo_array_append_multiple (data, buf, p - buf);
210
 
212
 
211
    assert (status == CAIRO_STATUS_SUCCESS);
213
    assert (status == CAIRO_STATUS_SUCCESS);
212
    assert (_cairo_array_size (data) == orig_size);
214
    assert (_cairo_array_size (data) == orig_size);
213
}
215
}
214
 
216
 
215
typedef struct _ps_path_info {
217
typedef struct _ps_path_info {
216
    cairo_array_t *data;
218
    cairo_array_t *data;
217
    int current_x, current_y;
219
    int current_x, current_y;
218
    cairo_charstring_type_t type;
220
    cairo_charstring_type_t type;
219
} t1_path_info_t;
221
} t1_path_info_t;
220
 
222
 
221
static cairo_status_t
223
static cairo_status_t
222
_charstring_move_to (void		    *closure,
224
_charstring_move_to (void		    *closure,
223
                     const cairo_point_t    *point)
225
                     const cairo_point_t    *point)
224
{
226
{
225
    t1_path_info_t *path_info = (t1_path_info_t *) closure;
227
    t1_path_info_t *path_info = (t1_path_info_t *) closure;
226
    int dx, dy;
228
    int dx, dy;
227
    cairo_status_t status;
229
    cairo_status_t status;
228
 
230
 
229
    status = _cairo_array_grow_by (path_info->data, 12);
231
    status = _cairo_array_grow_by (path_info->data, 12);
230
    if (unlikely (status))
232
    if (unlikely (status))
231
        return status;
233
        return status;
232
 
234
 
233
    dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
235
    dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
234
    dy = _cairo_fixed_integer_part (point->y) - path_info->current_y;
236
    dy = _cairo_fixed_integer_part (point->y) - path_info->current_y;
235
    charstring_encode_integer (path_info->data, dx, path_info->type);
237
    charstring_encode_integer (path_info->data, dx, path_info->type);
236
    charstring_encode_integer (path_info->data, dy, path_info->type);
238
    charstring_encode_integer (path_info->data, dy, path_info->type);
237
    path_info->current_x += dx;
239
    path_info->current_x += dx;
238
    path_info->current_y += dy;
240
    path_info->current_y += dy;
239
 
241
 
240
    charstring_encode_command (path_info->data, CHARSTRING_rmoveto);
242
    charstring_encode_command (path_info->data, CHARSTRING_rmoveto);
241
 
243
 
242
    return CAIRO_STATUS_SUCCESS;
244
    return CAIRO_STATUS_SUCCESS;
243
}
245
}
244
 
246
 
245
static cairo_status_t
247
static cairo_status_t
246
_charstring_line_to (void		    *closure,
248
_charstring_line_to (void		    *closure,
247
                     const cairo_point_t    *point)
249
                     const cairo_point_t    *point)
248
{
250
{
249
    t1_path_info_t *path_info = (t1_path_info_t *) closure;
251
    t1_path_info_t *path_info = (t1_path_info_t *) closure;
250
    int dx, dy;
252
    int dx, dy;
251
    cairo_status_t status;
253
    cairo_status_t status;
252
 
254
 
253
    status = _cairo_array_grow_by (path_info->data, 12);
255
    status = _cairo_array_grow_by (path_info->data, 12);
254
    if (unlikely (status))
256
    if (unlikely (status))
255
        return status;
257
        return status;
256
 
258
 
257
    dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
259
    dx = _cairo_fixed_integer_part (point->x) - path_info->current_x;
258
    dy = _cairo_fixed_integer_part (point->y) - path_info->current_y;
260
    dy = _cairo_fixed_integer_part (point->y) - path_info->current_y;
259
    charstring_encode_integer (path_info->data, dx, path_info->type);
261
    charstring_encode_integer (path_info->data, dx, path_info->type);
260
    charstring_encode_integer (path_info->data, dy, path_info->type);
262
    charstring_encode_integer (path_info->data, dy, path_info->type);
261
    path_info->current_x += dx;
263
    path_info->current_x += dx;
262
    path_info->current_y += dy;
264
    path_info->current_y += dy;
263
 
265
 
264
    charstring_encode_command (path_info->data, CHARSTRING_rlineto);
266
    charstring_encode_command (path_info->data, CHARSTRING_rlineto);
265
 
267
 
266
    return CAIRO_STATUS_SUCCESS;
268
    return CAIRO_STATUS_SUCCESS;
267
}
269
}
268
 
270
 
269
static cairo_status_t
271
static cairo_status_t
270
_charstring_curve_to (void		    *closure,
272
_charstring_curve_to (void		    *closure,
271
                      const cairo_point_t   *point1,
273
                      const cairo_point_t   *point1,
272
                      const cairo_point_t   *point2,
274
                      const cairo_point_t   *point2,
273
                      const cairo_point_t   *point3)
275
                      const cairo_point_t   *point3)
274
{
276
{
275
    t1_path_info_t *path_info = (t1_path_info_t *) closure;
277
    t1_path_info_t *path_info = (t1_path_info_t *) closure;
276
    int dx1, dy1, dx2, dy2, dx3, dy3;
278
    int dx1, dy1, dx2, dy2, dx3, dy3;
277
    cairo_status_t status;
279
    cairo_status_t status;
278
 
280
 
279
    status = _cairo_array_grow_by (path_info->data, 32);
281
    status = _cairo_array_grow_by (path_info->data, 32);
280
    if (unlikely (status))
282
    if (unlikely (status))
281
        return status;
283
        return status;
282
 
284
 
283
    dx1 = _cairo_fixed_integer_part (point1->x) - path_info->current_x;
285
    dx1 = _cairo_fixed_integer_part (point1->x) - path_info->current_x;
284
    dy1 = _cairo_fixed_integer_part (point1->y) - path_info->current_y;
286
    dy1 = _cairo_fixed_integer_part (point1->y) - path_info->current_y;
285
    dx2 = _cairo_fixed_integer_part (point2->x) - path_info->current_x - dx1;
287
    dx2 = _cairo_fixed_integer_part (point2->x) - path_info->current_x - dx1;
286
    dy2 = _cairo_fixed_integer_part (point2->y) - path_info->current_y - dy1;
288
    dy2 = _cairo_fixed_integer_part (point2->y) - path_info->current_y - dy1;
287
    dx3 = _cairo_fixed_integer_part (point3->x) - path_info->current_x - dx1 - dx2;
289
    dx3 = _cairo_fixed_integer_part (point3->x) - path_info->current_x - dx1 - dx2;
288
    dy3 = _cairo_fixed_integer_part (point3->y) - path_info->current_y - dy1 - dy2;
290
    dy3 = _cairo_fixed_integer_part (point3->y) - path_info->current_y - dy1 - dy2;
289
    charstring_encode_integer (path_info->data, dx1, path_info->type);
291
    charstring_encode_integer (path_info->data, dx1, path_info->type);
290
    charstring_encode_integer (path_info->data, dy1, path_info->type);
292
    charstring_encode_integer (path_info->data, dy1, path_info->type);
291
    charstring_encode_integer (path_info->data, dx2, path_info->type);
293
    charstring_encode_integer (path_info->data, dx2, path_info->type);
292
    charstring_encode_integer (path_info->data, dy2, path_info->type);
294
    charstring_encode_integer (path_info->data, dy2, path_info->type);
293
    charstring_encode_integer (path_info->data, dx3, path_info->type);
295
    charstring_encode_integer (path_info->data, dx3, path_info->type);
294
    charstring_encode_integer (path_info->data, dy3, path_info->type);
296
    charstring_encode_integer (path_info->data, dy3, path_info->type);
295
    path_info->current_x += dx1 + dx2 + dx3;
297
    path_info->current_x += dx1 + dx2 + dx3;
296
    path_info->current_y += dy1 + dy2 + dy3;
298
    path_info->current_y += dy1 + dy2 + dy3;
297
    charstring_encode_command (path_info->data, CHARSTRING_rcurveto);
299
    charstring_encode_command (path_info->data, CHARSTRING_rcurveto);
298
 
300
 
299
    return CAIRO_STATUS_SUCCESS;
301
    return CAIRO_STATUS_SUCCESS;
300
}
302
}
301
 
303
 
302
static cairo_status_t
304
static cairo_status_t
303
_charstring_close_path (void *closure)
305
_charstring_close_path (void *closure)
304
{
306
{
305
    cairo_status_t status;
307
    cairo_status_t status;
306
    t1_path_info_t *path_info = (t1_path_info_t *) closure;
308
    t1_path_info_t *path_info = (t1_path_info_t *) closure;
307
 
309
 
308
    if (path_info->type == CAIRO_CHARSTRING_TYPE2)
310
    if (path_info->type == CAIRO_CHARSTRING_TYPE2)
309
        return CAIRO_STATUS_SUCCESS;
311
        return CAIRO_STATUS_SUCCESS;
310
 
312
 
311
    status = _cairo_array_grow_by (path_info->data, 2);
313
    status = _cairo_array_grow_by (path_info->data, 2);
312
    if (unlikely (status))
314
    if (unlikely (status))
313
	return status;
315
	return status;
314
 
316
 
315
    charstring_encode_command (path_info->data, CHARSTRING_closepath);
317
    charstring_encode_command (path_info->data, CHARSTRING_closepath);
316
 
318
 
317
    return CAIRO_STATUS_SUCCESS;
319
    return CAIRO_STATUS_SUCCESS;
318
}
320
}
319
 
321
 
320
static void
322
static void
321
charstring_encrypt (cairo_array_t *data)
323
charstring_encrypt (cairo_array_t *data)
322
{
324
{
323
    unsigned char *d, *end;
325
    unsigned char *d, *end;
324
    uint16_t c, p, r;
326
    uint16_t c, p, r;
325
 
327
 
326
    r = CAIRO_TYPE1_CHARSTRING_KEY;
328
    r = CAIRO_TYPE1_CHARSTRING_KEY;
327
    d = (unsigned char *) _cairo_array_index (data, 0);
329
    d = (unsigned char *) _cairo_array_index (data, 0);
328
    end = d + _cairo_array_num_elements (data);
330
    end = d + _cairo_array_num_elements (data);
329
    while (d < end) {
331
    while (d < end) {
330
	p = *d;
332
	p = *d;
331
	c = p ^ (r >> 8);
333
	c = p ^ (r >> 8);
332
	r = (c + r) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
334
	r = (c + r) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
333
        *d++ = c;
335
        *d++ = c;
334
    }
336
    }
335
}
337
}
336
 
338
 
337
static cairo_int_status_t
339
static cairo_int_status_t
338
cairo_type1_font_create_charstring (cairo_type1_font_t      *font,
340
cairo_type1_font_create_charstring (cairo_type1_font_t      *font,
339
                                    int                      subset_index,
341
                                    int                      subset_index,
340
                                    int                      glyph_index,
342
                                    int                      glyph_index,
341
                                    cairo_charstring_type_t  type,
343
                                    cairo_charstring_type_t  type,
342
                                    cairo_array_t           *data)
344
                                    cairo_array_t           *data)
343
{
345
{
344
    cairo_int_status_t status;
346
    cairo_int_status_t status;
345
    cairo_scaled_glyph_t *scaled_glyph;
347
    cairo_scaled_glyph_t *scaled_glyph;
346
    t1_path_info_t path_info;
348
    t1_path_info_t path_info;
347
    cairo_text_extents_t *metrics;
349
    cairo_text_extents_t *metrics;
348
    cairo_bool_t emit_path = TRUE;
350
    cairo_bool_t emit_path = TRUE;
349
 
351
 
350
    /* This call may return CAIRO_INT_STATUS_UNSUPPORTED for bitmap fonts. */
352
    /* This call may return CAIRO_INT_STATUS_UNSUPPORTED for bitmap fonts. */
351
    status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
353
    status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
352
					 glyph_index,
354
					 glyph_index,
353
					 CAIRO_SCALED_GLYPH_INFO_METRICS|
355
					 CAIRO_SCALED_GLYPH_INFO_METRICS|
354
					 CAIRO_SCALED_GLYPH_INFO_PATH,
356
					 CAIRO_SCALED_GLYPH_INFO_PATH,
355
					 &scaled_glyph);
357
					 &scaled_glyph);
356
 
358
 
357
    /* It is ok for the .notdef glyph to not have a path available. We
359
    /* It is ok for the .notdef glyph to not have a path available. We
358
     * just need the metrics to emit an empty glyph.  */
360
     * just need the metrics to emit an empty glyph.  */
359
    if (glyph_index == 0 && status == CAIRO_INT_STATUS_UNSUPPORTED) {
361
    if (glyph_index == 0 && status == CAIRO_INT_STATUS_UNSUPPORTED) {
360
	emit_path = FALSE;
362
	emit_path = FALSE;
361
	status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
363
	status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
362
					     glyph_index,
364
					     glyph_index,
363
					     CAIRO_SCALED_GLYPH_INFO_METRICS,
365
					     CAIRO_SCALED_GLYPH_INFO_METRICS,
364
					     &scaled_glyph);
366
					     &scaled_glyph);
365
    }
367
    }
366
    if (unlikely (status))
368
    if (unlikely (status))
367
        return status;
369
        return status;
368
 
370
 
369
    metrics = &scaled_glyph->metrics;
371
    metrics = &scaled_glyph->metrics;
370
    if (subset_index == 0) {
372
    if (subset_index == 0) {
371
        font->x_min = metrics->x_bearing;
373
        font->x_min = metrics->x_bearing;
372
        font->y_min = metrics->y_bearing;
374
        font->y_min = metrics->y_bearing;
373
        font->x_max = metrics->x_bearing + metrics->width;
375
        font->x_max = metrics->x_bearing + metrics->width;
374
        font->y_max = metrics->y_bearing + metrics->height;
376
        font->y_max = metrics->y_bearing + metrics->height;
375
    } else {
377
    } else {
376
        if (metrics->x_bearing < font->x_min)
378
        if (metrics->x_bearing < font->x_min)
377
            font->x_min = metrics->x_bearing;
379
            font->x_min = metrics->x_bearing;
378
        if (metrics->y_bearing < font->y_min)
380
        if (metrics->y_bearing < font->y_min)
379
            font->y_min = metrics->y_bearing;
381
            font->y_min = metrics->y_bearing;
380
        if (metrics->x_bearing + metrics->width > font->x_max)
382
        if (metrics->x_bearing + metrics->width > font->x_max)
381
            font->x_max = metrics->x_bearing + metrics->width;
383
            font->x_max = metrics->x_bearing + metrics->width;
382
        if (metrics->y_bearing + metrics->height > font->y_max)
384
        if (metrics->y_bearing + metrics->height > font->y_max)
383
            font->y_max = metrics->y_bearing + metrics->height;
385
            font->y_max = metrics->y_bearing + metrics->height;
384
    }
386
    }
385
    font->widths[subset_index] = metrics->x_advance;
387
    font->widths[subset_index] = metrics->x_advance;
386
 
388
 
387
    status = _cairo_array_grow_by (data, 30);
389
    status = _cairo_array_grow_by (data, 30);
388
    if (unlikely (status))
390
    if (unlikely (status))
389
        return status;
391
        return status;
390
 
392
 
391
    if (type == CAIRO_CHARSTRING_TYPE1) {
393
    if (type == CAIRO_CHARSTRING_TYPE1) {
392
        charstring_encode_integer (data, (int) scaled_glyph->metrics.x_bearing, type);
394
        charstring_encode_integer (data, (int) scaled_glyph->metrics.x_bearing, type);
393
        charstring_encode_integer (data, (int) scaled_glyph->metrics.y_bearing, type);
395
        charstring_encode_integer (data, (int) scaled_glyph->metrics.y_bearing, type);
394
        charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type);
396
        charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type);
395
        charstring_encode_integer (data, (int) scaled_glyph->metrics.y_advance, type);
397
        charstring_encode_integer (data, (int) scaled_glyph->metrics.y_advance, type);
396
        charstring_encode_command (data, CHARSTRING_sbw);
398
        charstring_encode_command (data, CHARSTRING_sbw);
397
 
399
 
398
        path_info.current_x = (int) scaled_glyph->metrics.x_bearing;
400
        path_info.current_x = (int) scaled_glyph->metrics.x_bearing;
399
        path_info.current_y = (int) scaled_glyph->metrics.y_bearing;
401
        path_info.current_y = (int) scaled_glyph->metrics.y_bearing;
400
    } else {
402
    } else {
401
        charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type);
403
        charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type);
402
 
404
 
403
        path_info.current_x = 0;
405
        path_info.current_x = 0;
404
        path_info.current_y = 0;
406
        path_info.current_y = 0;
405
    }
407
    }
406
    path_info.data = data;
408
    path_info.data = data;
407
    path_info.type = type;
409
    path_info.type = type;
408
    if (emit_path) {
410
    if (emit_path) {
409
	status = _cairo_path_fixed_interpret (scaled_glyph->path,
411
	status = _cairo_path_fixed_interpret (scaled_glyph->path,
410
					      CAIRO_DIRECTION_FORWARD,
-
 
411
					      _charstring_move_to,
412
					      _charstring_move_to,
412
					      _charstring_line_to,
413
					      _charstring_line_to,
413
					      _charstring_curve_to,
414
					      _charstring_curve_to,
414
					      _charstring_close_path,
415
					      _charstring_close_path,
415
					      &path_info);
416
					      &path_info);
416
	if (unlikely (status))
417
	if (unlikely (status))
417
	    return status;
418
	    return status;
418
    }
419
    }
419
 
420
 
420
    status = _cairo_array_grow_by (data, 1);
421
    status = _cairo_array_grow_by (data, 1);
421
    if (unlikely (status))
422
    if (unlikely (status))
422
        return status;
423
        return status;
423
    charstring_encode_command (path_info.data, CHARSTRING_endchar);
424
    charstring_encode_command (path_info.data, CHARSTRING_endchar);
424
 
425
 
425
    return CAIRO_STATUS_SUCCESS;
426
    return CAIRO_STATUS_SUCCESS;
426
}
427
}
427
 
428
 
428
static cairo_int_status_t
429
static cairo_int_status_t
429
cairo_type1_font_write_charstrings (cairo_type1_font_t    *font,
430
cairo_type1_font_write_charstrings (cairo_type1_font_t    *font,
430
                                    cairo_output_stream_t *encrypted_output)
431
                                    cairo_output_stream_t *encrypted_output)
431
{
432
{
432
    cairo_status_t status;
433
    cairo_status_t status;
433
    unsigned char zeros[] = { 0, 0, 0, 0 };
434
    unsigned char zeros[] = { 0, 0, 0, 0 };
434
    cairo_array_t data;
435
    cairo_array_t data;
435
    unsigned int i;
436
    unsigned int i;
436
    int length;
437
    int length;
437
 
438
 
438
    _cairo_array_init (&data, sizeof (unsigned char));
439
    _cairo_array_init (&data, sizeof (unsigned char));
439
    status = _cairo_array_grow_by (&data, 1024);
440
    status = _cairo_array_grow_by (&data, 1024);
440
    if (unlikely (status))
441
    if (unlikely (status))
441
        goto fail;
442
        goto fail;
442
 
443
 
443
    _cairo_output_stream_printf (encrypted_output,
444
    _cairo_output_stream_printf (encrypted_output,
444
                                 "2 index /CharStrings %d dict dup begin\n",
445
                                 "2 index /CharStrings %d dict dup begin\n",
445
                                 font->scaled_font_subset->num_glyphs + 1);
446
                                 font->scaled_font_subset->num_glyphs + 1);
446
 
447
 
447
    _cairo_scaled_font_freeze_cache (font->type1_scaled_font);
448
    _cairo_scaled_font_freeze_cache (font->type1_scaled_font);
448
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
449
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
449
        _cairo_array_truncate (&data, 0);
450
        _cairo_array_truncate (&data, 0);
450
        /* four "random" bytes required by encryption algorithm */
451
        /* four "random" bytes required by encryption algorithm */
451
        status = _cairo_array_append_multiple (&data, zeros, 4);
452
        status = _cairo_array_append_multiple (&data, zeros, 4);
452
        if (unlikely (status))
453
        if (unlikely (status))
453
	    break;
454
	    break;
454
 
455
 
455
        status = cairo_type1_font_create_charstring (font, i,
456
        status = cairo_type1_font_create_charstring (font, i,
456
						     font->scaled_font_subset->glyphs[i],
457
						     font->scaled_font_subset->glyphs[i],
457
                                                     CAIRO_CHARSTRING_TYPE1,
458
                                                     CAIRO_CHARSTRING_TYPE1,
458
						     &data);
459
						     &data);
459
        if (unlikely (status))
460
        if (unlikely (status))
460
	    break;
461
	    break;
461
 
462
 
462
        charstring_encrypt (&data);
463
        charstring_encrypt (&data);
463
        length = _cairo_array_num_elements (&data);
464
        length = _cairo_array_num_elements (&data);
464
	if (font->scaled_font_subset->glyph_names != NULL) {
465
	if (font->scaled_font_subset->glyph_names != NULL) {
465
	    _cairo_output_stream_printf (encrypted_output, "/%s %d RD ",
466
	    _cairo_output_stream_printf (encrypted_output, "/%s %d RD ",
466
					 font->scaled_font_subset->glyph_names[i],
467
					 font->scaled_font_subset->glyph_names[i],
467
					 length);
468
					 length);
468
	} else if (i == 0) {
469
	} else if (i == 0) {
469
	    _cairo_output_stream_printf (encrypted_output, "/.notdef %d RD ", length);
470
	    _cairo_output_stream_printf (encrypted_output, "/.notdef %d RD ", length);
470
	} else {
471
	} else {
471
	    _cairo_output_stream_printf (encrypted_output, "/g%d %d RD ", i, length);
472
	    _cairo_output_stream_printf (encrypted_output, "/g%d %d RD ", i, length);
472
	}
473
	}
473
        _cairo_output_stream_write (encrypted_output,
474
        _cairo_output_stream_write (encrypted_output,
474
                                    _cairo_array_index (&data, 0),
475
                                    _cairo_array_index (&data, 0),
475
                                    length);
476
                                    length);
476
        _cairo_output_stream_printf (encrypted_output, " ND\n");
477
        _cairo_output_stream_printf (encrypted_output, " ND\n");
477
    }
478
    }
478
    _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
479
    _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
479
 
480
 
480
fail:
481
fail:
481
    _cairo_array_fini (&data);
482
    _cairo_array_fini (&data);
482
    return status;
483
    return status;
483
}
484
}
484
 
485
 
485
static void
486
static void
486
cairo_type1_font_write_header (cairo_type1_font_t *font,
487
cairo_type1_font_write_header (cairo_type1_font_t *font,
487
                               const char         *name)
488
                               const char         *name)
488
{
489
{
489
    unsigned int i;
490
    unsigned int i;
490
    const char spaces[50] = "                                                  ";
491
    const char spaces[50] = "                                                  ";
491
 
492
 
492
    _cairo_output_stream_printf (font->output,
493
    _cairo_output_stream_printf (font->output,
493
                                 "%%!FontType1-1.1 %s 1.0\n"
494
                                 "%%!FontType1-1.1 %s 1.0\n"
494
                                 "11 dict begin\n"
495
                                 "11 dict begin\n"
495
                                 "/FontName /%s def\n"
496
                                 "/FontName /%s def\n"
496
                                 "/PaintType 0 def\n"
497
                                 "/PaintType 0 def\n"
497
                                 "/FontType 1 def\n"
498
                                 "/FontType 1 def\n"
498
                                  "/FontMatrix [0.001 0 0 0.001 0 0] readonly def\n",
499
                                  "/FontMatrix [0.001 0 0 0.001 0 0] readonly def\n",
499
                                 name,
500
                                 name,
500
                                 name);
501
                                 name);
501
 
502
 
502
    /* We don't know the bbox values until after the charstrings have
503
    /* We don't know the bbox values until after the charstrings have
503
     * been generated.  Reserve some space and fill in the bbox
504
     * been generated.  Reserve some space and fill in the bbox
504
     * later. */
505
     * later. */
505
 
506
 
506
    /* Worst case for four signed ints with spaces between each number */
507
    /* Worst case for four signed ints with spaces between each number */
507
    font->bbox_max_chars = 50;
508
    font->bbox_max_chars = 50;
508
 
509
 
509
    _cairo_output_stream_printf (font->output, "/FontBBox {");
510
    _cairo_output_stream_printf (font->output, "/FontBBox {");
510
    font->bbox_position = _cairo_output_stream_get_position (font->output);
511
    font->bbox_position = _cairo_output_stream_get_position (font->output);
511
    _cairo_output_stream_write (font->output, spaces, font->bbox_max_chars);
512
    _cairo_output_stream_write (font->output, spaces, font->bbox_max_chars);
512
 
513
 
513
    _cairo_output_stream_printf (font->output,
514
    _cairo_output_stream_printf (font->output,
514
                                 "} readonly def\n"
515
                                 "} readonly def\n"
515
                                 "/Encoding 256 array\n"
516
                                 "/Encoding 256 array\n"
516
				 "0 1 255 {1 index exch /.notdef put} for\n");
517
				 "0 1 255 {1 index exch /.notdef put} for\n");
-
 
518
    if (font->scaled_font_subset->is_latin) {
-
 
519
	for (i = 1; i < 256; i++) {
-
 
520
	    int subset_glyph = font->scaled_font_subset->latin_to_subset_glyph_index[i];
-
 
521
 
-
 
522
	    if (subset_glyph > 0) {
-
 
523
		if (font->scaled_font_subset->glyph_names != NULL) {
-
 
524
		    _cairo_output_stream_printf (font->output, "dup %d /%s put\n",
-
 
525
						 i, font->scaled_font_subset->glyph_names[subset_glyph]);
-
 
526
		} else {
-
 
527
		    _cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, subset_glyph);
-
 
528
		}
-
 
529
	    }
-
 
530
	}
-
 
531
    } else {
517
    for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
532
	for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
518
	if (font->scaled_font_subset->glyph_names != NULL) {
533
	    if (font->scaled_font_subset->glyph_names != NULL) {
519
	    _cairo_output_stream_printf (font->output, "dup %d /%s put\n",
534
		_cairo_output_stream_printf (font->output, "dup %d /%s put\n",
520
					 i, font->scaled_font_subset->glyph_names[i]);
535
					     i, font->scaled_font_subset->glyph_names[i]);
521
	} else {
536
	    } else {
522
	    _cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, i);
537
		_cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, i);
523
	}
538
	    }
524
    }
539
	}
-
 
540
    }
525
    _cairo_output_stream_printf (font->output,
541
    _cairo_output_stream_printf (font->output,
526
                                 "readonly def\n"
542
                                 "readonly def\n"
527
                                 "currentdict end\n"
543
                                 "currentdict end\n"
528
                                 "currentfile eexec\n");
544
                                 "currentfile eexec\n");
529
}
545
}
530
 
546
 
531
static cairo_status_t
547
static cairo_status_t
532
cairo_type1_write_stream_encrypted (void                *closure,
548
cairo_type1_write_stream_encrypted (void                *closure,
533
                                    const unsigned char *data,
549
                                    const unsigned char *data,
534
                                    unsigned int         length)
550
                                    unsigned int         length)
535
{
551
{
536
    const unsigned char *in, *end;
552
    const unsigned char *in, *end;
537
    uint16_t c, p;
553
    uint16_t c, p;
538
    static const char hex_digits[16] = "0123456789abcdef";
554
    static const char hex_digits[16] = "0123456789abcdef";
539
    char digits[3];
555
    char digits[3];
540
    cairo_type1_font_t *font = closure;
556
    cairo_type1_font_t *font = closure;
541
 
557
 
542
    in = (const unsigned char *) data;
558
    in = (const unsigned char *) data;
543
    end = (const unsigned char *) data + length;
559
    end = (const unsigned char *) data + length;
544
    while (in < end) {
560
    while (in < end) {
545
	p = *in++;
561
	p = *in++;
546
	c = p ^ (font->eexec_key >> 8);
562
	c = p ^ (font->eexec_key >> 8);
547
	font->eexec_key = (c + font->eexec_key) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
563
	font->eexec_key = (c + font->eexec_key) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2;
548
 
564
 
549
	if (font->hex_encode) {
565
	if (font->hex_encode) {
550
	    digits[0] = hex_digits[c >> 4];
566
	    digits[0] = hex_digits[c >> 4];
551
	    digits[1] = hex_digits[c & 0x0f];
567
	    digits[1] = hex_digits[c & 0x0f];
552
	    digits[2] = '\n';
568
	    digits[2] = '\n';
553
	    font->hex_column += 2;
569
	    font->hex_column += 2;
554
 
570
 
555
	    if (font->hex_column == 78) {
571
	    if (font->hex_column == 78) {
556
		_cairo_output_stream_write (font->output, digits, 3);
572
		_cairo_output_stream_write (font->output, digits, 3);
557
		font->hex_column = 0;
573
		font->hex_column = 0;
558
	    } else {
574
	    } else {
559
		_cairo_output_stream_write (font->output, digits, 2);
575
		_cairo_output_stream_write (font->output, digits, 2);
560
	    }
576
	    }
561
	} else {
577
	} else {
562
	    digits[0] = c;
578
	    digits[0] = c;
563
	    _cairo_output_stream_write (font->output, digits, 1);
579
	    _cairo_output_stream_write (font->output, digits, 1);
564
	}
580
	}
565
    }
581
    }
566
 
582
 
567
    return CAIRO_STATUS_SUCCESS;
583
    return CAIRO_STATUS_SUCCESS;
568
}
584
}
569
 
585
 
570
static cairo_int_status_t
586
static cairo_int_status_t
571
cairo_type1_font_write_private_dict (cairo_type1_font_t *font,
587
cairo_type1_font_write_private_dict (cairo_type1_font_t *font,
572
                                     const char         *name)
588
                                     const char         *name)
573
{
589
{
574
    cairo_int_status_t status;
590
    cairo_int_status_t status;
575
    cairo_status_t status2;
591
    cairo_status_t status2;
576
    cairo_output_stream_t *encrypted_output;
592
    cairo_output_stream_t *encrypted_output;
577
 
593
 
578
    font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY;
594
    font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY;
579
    font->hex_column = 0;
595
    font->hex_column = 0;
580
    encrypted_output = _cairo_output_stream_create (
596
    encrypted_output = _cairo_output_stream_create (
581
        cairo_type1_write_stream_encrypted,
597
        cairo_type1_write_stream_encrypted,
582
        NULL,
598
        NULL,
583
        font);
599
        font);
584
    if (_cairo_output_stream_get_status (encrypted_output))
600
    if (_cairo_output_stream_get_status (encrypted_output))
585
	return  _cairo_output_stream_destroy (encrypted_output);
601
	return  _cairo_output_stream_destroy (encrypted_output);
586
 
602
 
587
    /* Note: the first four spaces at the start of this private dict
603
    /* Note: the first four spaces at the start of this private dict
588
     * are the four "random" bytes of plaintext required by the
604
     * are the four "random" bytes of plaintext required by the
589
     * encryption algorithm */
605
     * encryption algorithm */
590
    _cairo_output_stream_printf (encrypted_output,
606
    _cairo_output_stream_printf (encrypted_output,
591
                                 "    dup /Private 9 dict dup begin\n"
607
                                 "    dup /Private 9 dict dup begin\n"
592
                                 "/RD {string currentfile exch readstring pop}"
608
                                 "/RD {string currentfile exch readstring pop}"
593
                                 " bind executeonly def\n"
609
                                 " bind executeonly def\n"
594
                                 "/ND {noaccess def} executeonly def\n"
610
                                 "/ND {noaccess def} executeonly def\n"
595
                                 "/NP {noaccess put} executeonly def\n"
611
                                 "/NP {noaccess put} executeonly def\n"
596
                                 "/BlueValues [] def\n"
612
                                 "/BlueValues [] def\n"
597
                                 "/MinFeature {16 16} def\n"
613
                                 "/MinFeature {16 16} def\n"
598
                                 "/lenIV 4 def\n"
614
                                 "/lenIV 4 def\n"
599
                                 "/password 5839 def\n");
615
                                 "/password 5839 def\n");
600
 
616
 
601
    status = cairo_type1_font_write_charstrings (font, encrypted_output);
617
    status = cairo_type1_font_write_charstrings (font, encrypted_output);
602
    if (unlikely (status))
618
    if (unlikely (status))
603
	goto fail;
619
	goto fail;
604
 
620
 
605
    _cairo_output_stream_printf (encrypted_output,
621
    _cairo_output_stream_printf (encrypted_output,
606
                                 "end\n"
622
                                 "end\n"
607
                                 "end\n"
623
                                 "end\n"
608
                                 "readonly put\n"
624
                                 "readonly put\n"
609
                                 "noaccess put\n"
625
                                 "noaccess put\n"
610
                                 "dup /FontName get exch definefont pop\n"
626
                                 "dup /FontName get exch definefont pop\n"
611
                                 "mark currentfile closefile\n");
627
                                 "mark currentfile closefile\n");
612
 
628
 
613
  fail:
629
  fail:
614
    status2 = _cairo_output_stream_destroy (encrypted_output);
630
    status2 = _cairo_output_stream_destroy (encrypted_output);
615
    if (status == CAIRO_STATUS_SUCCESS)
631
    if (status == CAIRO_INT_STATUS_SUCCESS)
616
	status = status2;
632
	status = status2;
617
 
633
 
618
    return status;
634
    return status;
619
}
635
}
620
 
636
 
621
static void
637
static void
622
cairo_type1_font_write_trailer(cairo_type1_font_t *font)
638
cairo_type1_font_write_trailer(cairo_type1_font_t *font)
623
{
639
{
624
    int i;
640
    int i;
625
    static const char zeros[65] =
641
    static const char zeros[65] =
626
	"0000000000000000000000000000000000000000000000000000000000000000\n";
642
	"0000000000000000000000000000000000000000000000000000000000000000\n";
627
 
643
 
628
    for (i = 0; i < 8; i++)
644
    for (i = 0; i < 8; i++)
629
	_cairo_output_stream_write (font->output, zeros, sizeof zeros);
645
	_cairo_output_stream_write (font->output, zeros, sizeof zeros);
630
 
646
 
631
    _cairo_output_stream_printf (font->output, "cleartomark\n");
647
    _cairo_output_stream_printf (font->output, "cleartomark\n");
632
}
648
}
633
 
649
 
634
static cairo_status_t
650
static cairo_status_t
635
cairo_type1_write_stream (void *closure,
651
cairo_type1_write_stream (void *closure,
636
                         const unsigned char *data,
652
                         const unsigned char *data,
637
                         unsigned int length)
653
                         unsigned int length)
638
{
654
{
639
    cairo_type1_font_t *font = closure;
655
    cairo_type1_font_t *font = closure;
640
 
656
 
641
    return _cairo_array_append_multiple (&font->contents, data, length);
657
    return _cairo_array_append_multiple (&font->contents, data, length);
642
}
658
}
643
 
659
 
644
static cairo_int_status_t
660
static cairo_int_status_t
645
cairo_type1_font_write (cairo_type1_font_t *font,
661
cairo_type1_font_write (cairo_type1_font_t *font,
646
                        const char *name)
662
                        const char *name)
647
{
663
{
648
    cairo_int_status_t status;
664
    cairo_int_status_t status;
649
 
665
 
650
    cairo_type1_font_write_header (font, name);
666
    cairo_type1_font_write_header (font, name);
651
    font->header_size = _cairo_output_stream_get_position (font->output);
667
    font->header_size = _cairo_output_stream_get_position (font->output);
652
 
668
 
653
    status = cairo_type1_font_write_private_dict (font, name);
669
    status = cairo_type1_font_write_private_dict (font, name);
654
    if (unlikely (status))
670
    if (unlikely (status))
655
	return status;
671
	return status;
656
 
672
 
657
    font->data_size = _cairo_output_stream_get_position (font->output) -
673
    font->data_size = _cairo_output_stream_get_position (font->output) -
658
	font->header_size;
674
	font->header_size;
659
 
675
 
660
    cairo_type1_font_write_trailer (font);
676
    cairo_type1_font_write_trailer (font);
661
    font->trailer_size =
677
    font->trailer_size =
662
	_cairo_output_stream_get_position (font->output) -
678
	_cairo_output_stream_get_position (font->output) -
663
	font->header_size - font->data_size;
679
	font->header_size - font->data_size;
664
 
680
 
665
    return CAIRO_STATUS_SUCCESS;
681
    return CAIRO_STATUS_SUCCESS;
666
}
682
}
667
 
683
 
668
static cairo_int_status_t
684
static cairo_int_status_t
669
cairo_type1_font_generate (cairo_type1_font_t *font, const char *name)
685
cairo_type1_font_generate (cairo_type1_font_t *font, const char *name)
670
{
686
{
671
    cairo_int_status_t status;
687
    cairo_int_status_t status;
672
 
688
 
673
    status = _cairo_array_grow_by (&font->contents, 4096);
689
    status = _cairo_array_grow_by (&font->contents, 4096);
674
    if (unlikely (status))
690
    if (unlikely (status))
675
	return status;
691
	return status;
676
 
692
 
677
    font->output = _cairo_output_stream_create (cairo_type1_write_stream, NULL, font);
693
    font->output = _cairo_output_stream_create (cairo_type1_write_stream, NULL, font);
678
    if (_cairo_output_stream_get_status (font->output))
694
    if (_cairo_output_stream_get_status (font->output))
679
	return _cairo_output_stream_destroy (font->output);
695
	return _cairo_output_stream_destroy (font->output);
680
 
696
 
681
    status = cairo_type1_font_write (font, name);
697
    status = cairo_type1_font_write (font, name);
682
    if (unlikely (status))
698
    if (unlikely (status))
683
	return status;
699
	return status;
684
 
700
 
685
    font->data = _cairo_array_index (&font->contents, 0);
701
    font->data = _cairo_array_index (&font->contents, 0);
686
 
702
 
687
    return CAIRO_STATUS_SUCCESS;
703
    return CAIRO_STATUS_SUCCESS;
688
}
704
}
689
 
705
 
690
static cairo_status_t
706
static cairo_status_t
691
cairo_type1_font_destroy (cairo_type1_font_t *font)
707
cairo_type1_font_destroy (cairo_type1_font_t *font)
692
{
708
{
693
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
709
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
694
 
710
 
695
    free (font->widths);
711
    free (font->widths);
696
    cairo_scaled_font_destroy (font->type1_scaled_font);
712
    cairo_scaled_font_destroy (font->type1_scaled_font);
697
    _cairo_array_fini (&font->contents);
713
    _cairo_array_fini (&font->contents);
698
    if (font->output)
714
    if (font->output)
699
	status = _cairo_output_stream_destroy (font->output);
715
	status = _cairo_output_stream_destroy (font->output);
700
    free (font);
716
    free (font);
701
 
717
 
702
    return status;
718
    return status;
703
}
719
}
704
 
720
 
705
static cairo_status_t
721
static cairo_status_t
706
_cairo_type1_fallback_init_internal (cairo_type1_subset_t	*type1_subset,
722
_cairo_type1_fallback_init_internal (cairo_type1_subset_t	*type1_subset,
707
                                     const char			*name,
723
                                     const char			*name,
708
                                     cairo_scaled_font_subset_t	*scaled_font_subset,
724
                                     cairo_scaled_font_subset_t	*scaled_font_subset,
709
                                     cairo_bool_t                hex_encode)
725
                                     cairo_bool_t                hex_encode)
710
{
726
{
711
    cairo_type1_font_t *font;
727
    cairo_type1_font_t *font;
712
    cairo_status_t status;
728
    cairo_status_t status;
713
    unsigned long length;
729
    unsigned long length;
714
    unsigned int i, len;
730
    unsigned int i, len;
715
 
731
 
716
    status = cairo_type1_font_create (scaled_font_subset, &font, hex_encode);
732
    status = cairo_type1_font_create (scaled_font_subset, &font, hex_encode);
717
    if (unlikely (status))
733
    if (unlikely (status))
718
	return status;
734
	return status;
719
 
735
 
720
    status = cairo_type1_font_generate (font, name);
736
    status = cairo_type1_font_generate (font, name);
721
    if (unlikely (status))
737
    if (unlikely (status))
722
	goto fail1;
738
	goto fail1;
723
 
739
 
724
    type1_subset->base_font = strdup (name);
740
    type1_subset->base_font = strdup (name);
725
    if (unlikely (type1_subset->base_font == NULL)) {
741
    if (unlikely (type1_subset->base_font == NULL)) {
726
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
742
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
727
        goto fail1;
743
        goto fail1;
728
    }
744
    }
729
 
745
 
730
    type1_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
746
    type1_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
731
    if (unlikely (type1_subset->widths == NULL)) {
747
    if (unlikely (type1_subset->widths == NULL)) {
732
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
748
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
733
        goto fail2;
749
        goto fail2;
734
    }
750
    }
735
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
751
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
736
	type1_subset->widths[i] = (double)font->widths[i]/1000;
752
	type1_subset->widths[i] = (double)font->widths[i]/1000;
737
 
753
 
738
    type1_subset->x_min   = (double)font->x_min/1000;
754
    type1_subset->x_min   = (double)font->x_min/1000;
739
    type1_subset->y_min   = (double)font->y_min/1000;
755
    type1_subset->y_min   = (double)font->y_min/1000;
740
    type1_subset->x_max   = (double)font->x_max/1000;
756
    type1_subset->x_max   = (double)font->x_max/1000;
741
    type1_subset->y_max   = (double)font->y_max/1000;
757
    type1_subset->y_max   = (double)font->y_max/1000;
742
    type1_subset->ascent  = (double)font->y_max/1000;
758
    type1_subset->ascent  = (double)font->y_max/1000;
743
    type1_subset->descent = (double)font->y_min/1000;
759
    type1_subset->descent = (double)font->y_min/1000;
744
 
760
 
745
    length = font->header_size + font->data_size +
761
    length = font->header_size + font->data_size +
746
	font->trailer_size;
762
	font->trailer_size;
747
    type1_subset->data = malloc (length);
763
    type1_subset->data = malloc (length);
748
    if (unlikely (type1_subset->data == NULL)) {
764
    if (unlikely (type1_subset->data == NULL)) {
749
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
765
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
750
	goto fail3;
766
	goto fail3;
751
    }
767
    }
752
    memcpy (type1_subset->data,
768
    memcpy (type1_subset->data,
753
	    _cairo_array_index (&font->contents, 0), length);
769
	    _cairo_array_index (&font->contents, 0), length);
754
 
770
 
755
    len = snprintf(type1_subset->data + font->bbox_position,
771
    len = snprintf(type1_subset->data + font->bbox_position,
756
                   font->bbox_max_chars,
772
                   font->bbox_max_chars,
757
                   "%d %d %d %d",
773
                   "%d %d %d %d",
758
                   (int)font->x_min,
774
                   (int)font->x_min,
759
                   (int)font->y_min,
775
                   (int)font->y_min,
760
                   (int)font->x_max,
776
                   (int)font->x_max,
761
                   (int)font->y_max);
777
                   (int)font->y_max);
762
    type1_subset->data[font->bbox_position + len] = ' ';
778
    type1_subset->data[font->bbox_position + len] = ' ';
763
 
779
 
764
    type1_subset->header_length = font->header_size;
780
    type1_subset->header_length = font->header_size;
765
    type1_subset->data_length = font->data_size;
781
    type1_subset->data_length = font->data_size;
766
    type1_subset->trailer_length = font->trailer_size;
782
    type1_subset->trailer_length = font->trailer_size;
767
 
783
 
768
    return cairo_type1_font_destroy (font);
784
    return cairo_type1_font_destroy (font);
769
 
785
 
770
 fail3:
786
 fail3:
771
    free (type1_subset->widths);
787
    free (type1_subset->widths);
772
 fail2:
788
 fail2:
773
    free (type1_subset->base_font);
789
    free (type1_subset->base_font);
774
 fail1:
790
 fail1:
775
    /* status is already set, ignore further errors */
791
    /* status is already set, ignore further errors */
776
    cairo_type1_font_destroy (font);
792
    cairo_type1_font_destroy (font);
777
 
793
 
778
    return status;
794
    return status;
779
}
795
}
780
 
796
 
781
cairo_status_t
797
cairo_status_t
782
_cairo_type1_fallback_init_binary (cairo_type1_subset_t	      *type1_subset,
798
_cairo_type1_fallback_init_binary (cairo_type1_subset_t	      *type1_subset,
783
                                   const char		      *name,
799
                                   const char		      *name,
784
                                   cairo_scaled_font_subset_t *scaled_font_subset)
800
                                   cairo_scaled_font_subset_t *scaled_font_subset)
785
{
801
{
786
    return _cairo_type1_fallback_init_internal (type1_subset,
802
    return _cairo_type1_fallback_init_internal (type1_subset,
787
                                                name,
803
                                                name,
788
                                                scaled_font_subset, FALSE);
804
                                                scaled_font_subset, FALSE);
789
}
805
}
790
 
806
 
791
cairo_status_t
807
cairo_status_t
792
_cairo_type1_fallback_init_hex (cairo_type1_subset_t	   *type1_subset,
808
_cairo_type1_fallback_init_hex (cairo_type1_subset_t	   *type1_subset,
793
                                const char		   *name,
809
                                const char		   *name,
794
                                cairo_scaled_font_subset_t *scaled_font_subset)
810
                                cairo_scaled_font_subset_t *scaled_font_subset)
795
{
811
{
796
    return _cairo_type1_fallback_init_internal (type1_subset,
812
    return _cairo_type1_fallback_init_internal (type1_subset,
797
                                                name,
813
                                                name,
798
                                                scaled_font_subset, TRUE);
814
                                                scaled_font_subset, TRUE);
799
}
815
}
800
 
816
 
801
void
817
void
802
_cairo_type1_fallback_fini (cairo_type1_subset_t *subset)
818
_cairo_type1_fallback_fini (cairo_type1_subset_t *subset)
803
{
819
{
804
    free (subset->base_font);
820
    free (subset->base_font);
805
    free (subset->widths);
821
    free (subset->widths);
806
    free (subset->data);
822
    free (subset->data);
807
}
823
}
808
 
824
 
809
cairo_status_t
825
cairo_status_t
810
_cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset,
826
_cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset,
811
                               cairo_scaled_font_subset_t *scaled_font_subset)
827
                               cairo_scaled_font_subset_t *scaled_font_subset)
812
{
828
{
813
    cairo_type1_font_t *font;
829
    cairo_type1_font_t *font;
814
    cairo_status_t status;
830
    cairo_status_t status;
815
    unsigned int i;
831
    unsigned int i;
816
    cairo_array_t charstring;
832
    cairo_array_t charstring;
817
 
833
 
818
    status = cairo_type1_font_create (scaled_font_subset, &font, FALSE);
834
    status = cairo_type1_font_create (scaled_font_subset, &font, FALSE);
819
    if (unlikely (status))
835
    if (unlikely (status))
820
	return status;
836
	return status;
821
 
837
 
822
    _cairo_array_init (&type2_subset->charstrings, sizeof (cairo_array_t));
838
    _cairo_array_init (&type2_subset->charstrings, sizeof (cairo_array_t));
823
 
839
 
824
    type2_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
840
    type2_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
825
    if (unlikely (type2_subset->widths == NULL)) {
841
    if (unlikely (type2_subset->widths == NULL)) {
826
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
842
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
827
        goto fail1;
843
        goto fail1;
828
    }
844
    }
829
 
845
 
830
    _cairo_scaled_font_freeze_cache (font->type1_scaled_font);
846
    _cairo_scaled_font_freeze_cache (font->type1_scaled_font);
831
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
847
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
832
        _cairo_array_init (&charstring, sizeof (unsigned char));
848
        _cairo_array_init (&charstring, sizeof (unsigned char));
833
        status = _cairo_array_grow_by (&charstring, 32);
849
        status = _cairo_array_grow_by (&charstring, 32);
834
        if (unlikely (status))
850
        if (unlikely (status))
835
            goto fail2;
851
            goto fail2;
836
 
852
 
837
	status = cairo_type1_font_create_charstring (font, i,
853
	status = cairo_type1_font_create_charstring (font, i,
838
						     font->scaled_font_subset->glyphs[i],
854
						     font->scaled_font_subset->glyphs[i],
839
						     CAIRO_CHARSTRING_TYPE2,
855
						     CAIRO_CHARSTRING_TYPE2,
840
						     &charstring);
856
						     &charstring);
841
        if (unlikely (status))
857
        if (unlikely (status))
842
            goto fail2;
858
            goto fail2;
843
 
859
 
844
        status = _cairo_array_append (&type2_subset->charstrings, &charstring);
860
        status = _cairo_array_append (&type2_subset->charstrings, &charstring);
845
        if (unlikely (status))
861
        if (unlikely (status))
846
            goto fail2;
862
            goto fail2;
847
    }
863
    }
848
    _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
864
    _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
849
 
865
 
850
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
866
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
851
	type2_subset->widths[i] = font->widths[i];
867
	type2_subset->widths[i] = font->widths[i];
852
 
868
 
853
    type2_subset->x_min   = (int) font->x_min;
869
    type2_subset->x_min   = (int) font->x_min;
854
    type2_subset->y_min   = (int) font->y_min;
870
    type2_subset->y_min   = (int) font->y_min;
855
    type2_subset->x_max   = (int) font->x_max;
871
    type2_subset->x_max   = (int) font->x_max;
856
    type2_subset->y_max   = (int) font->y_max;
872
    type2_subset->y_max   = (int) font->y_max;
857
    type2_subset->ascent  = (int) font->y_max;
873
    type2_subset->ascent  = (int) font->y_max;
858
    type2_subset->descent = (int) font->y_min;
874
    type2_subset->descent = (int) font->y_min;
859
 
875
 
860
    return cairo_type1_font_destroy (font);
876
    return cairo_type1_font_destroy (font);
861
 
877
 
862
fail2:
878
fail2:
863
    _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
879
    _cairo_scaled_font_thaw_cache (font->type1_scaled_font);
864
    _cairo_array_fini (&charstring);
880
    _cairo_array_fini (&charstring);
865
    _cairo_type2_charstrings_fini (type2_subset);
881
    _cairo_type2_charstrings_fini (type2_subset);
866
fail1:
882
fail1:
867
    cairo_type1_font_destroy (font);
883
    cairo_type1_font_destroy (font);
868
    return status;
884
    return status;
869
}
885
}
870
 
886
 
871
void
887
void
872
_cairo_type2_charstrings_fini (cairo_type2_charstrings_t *type2_subset)
888
_cairo_type2_charstrings_fini (cairo_type2_charstrings_t *type2_subset)
873
{
889
{
874
    unsigned int i, num_charstrings;
890
    unsigned int i, num_charstrings;
875
    cairo_array_t *charstring;
891
    cairo_array_t *charstring;
876
 
892
 
877
    num_charstrings = _cairo_array_num_elements (&type2_subset->charstrings);
893
    num_charstrings = _cairo_array_num_elements (&type2_subset->charstrings);
878
    for (i = 0; i < num_charstrings; i++) {
894
    for (i = 0; i < num_charstrings; i++) {
879
        charstring = _cairo_array_index (&type2_subset->charstrings, i);
895
        charstring = _cairo_array_index (&type2_subset->charstrings, i);
880
        _cairo_array_fini (charstring);
896
        _cairo_array_fini (charstring);
881
    }
897
    }
882
    _cairo_array_fini (&type2_subset->charstrings);
898
    _cairo_array_fini (&type2_subset->charstrings);
883
 
899
 
884
    free (type2_subset->widths);
900
    free (type2_subset->widths);
885
}
901
}
886
 
902
 
887
#endif /* CAIRO_HAS_FONT_SUBSET */
903
#endif /* CAIRO_HAS_FONT_SUBSET */