Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_unix/sys/src/cmd/gs/src/zfont42.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1996, 1998, 1999, 2000 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: zfont42.c,v 1.23 2005/06/19 21:03:32 igor Exp $ */
18
/* Type 42 font creation operator */
19
#include "memory_.h"
20
#include "ghost.h"
21
#include "oper.h"
22
#include "gsccode.h"
23
#include "gsmatrix.h"
24
#include "gxfont.h"
25
#include "gxfont42.h"
26
#include "bfont.h"
27
#include "icharout.h"
28
#include "idict.h"
29
#include "idparam.h"
30
#include "ifont42.h"
31
#include "ichar1.h"
32
#include "iname.h"
33
#include "store.h"
34
 
35
/* Forward references */
36
private int z42_string_proc(gs_font_type42 *, ulong, uint, const byte **);
37
private uint z42_get_glyph_index(gs_font_type42 *, gs_glyph);
38
private int z42_gdir_get_outline(gs_font_type42 *, uint, gs_glyph_data_t *);
39
private font_proc_enumerate_glyph(z42_enumerate_glyph);
40
private font_proc_enumerate_glyph(z42_gdir_enumerate_glyph);
41
private font_proc_encode_char(z42_encode_char);
42
private font_proc_glyph_info(z42_glyph_info);
43
private font_proc_glyph_outline(z42_glyph_outline);
44
 
45
/* <string|name> <font_dict> .buildfont11/42 <string|name> <font> */
46
/* Build a type 11 (TrueType CID-keyed) or 42 (TrueType) font. */
47
int
48
build_gs_TrueType_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font_type42 **ppfont,
49
		       font_type ftype, gs_memory_type_ptr_t pstype,
50
		       const char *bcstr, const char *bgstr,
51
		       build_font_options_t options)
52
{
53
    build_proc_refs build;
54
    ref sfnts, GlyphDirectory;
55
    gs_font_type42 *pfont;
56
    font_data *pdata;
57
    int code;
58
 
59
    code = build_proc_name_refs(imemory, &build, bcstr, bgstr);
60
    if (code < 0)
61
	return code;
62
    check_type(*op, t_dictionary);
63
    /*
64
     * Since build_gs_primitive_font may resize the dictionary and cause
65
     * pointers to become invalid, we save sfnts and GlyphDirectory.
66
     */
67
    if ((code = font_string_array_param(imemory, op, "sfnts", &sfnts)) < 0 ||
68
	(code = font_GlyphDirectory_param(op, &GlyphDirectory)) < 0
69
	)
70
	return code;
71
    code = build_gs_primitive_font(i_ctx_p, op, (gs_font_base **)ppfont,
72
				   ftype, pstype, &build, options);
73
    if (code != 0)
74
	return code;
75
    pfont = *ppfont;
76
    pdata = pfont_data(pfont);
77
    ref_assign(&pdata->u.type42.sfnts, &sfnts);
78
    make_null_new(&pdata->u.type42.CIDMap);
79
    ref_assign(&pdata->u.type42.GlyphDirectory, &GlyphDirectory);
80
    pfont->data.string_proc = z42_string_proc;
81
    pfont->data.proc_data = (char *)pdata;
82
    code = gs_type42_font_init(pfont);
83
    if (code < 0)
84
	return code;
85
    /*
86
     * If the font has a GlyphDictionary, this replaces loca and glyf for
87
     * accessing character outlines.  In this case, we use alternate
88
     * get_outline and enumerate_glyph procedures.
89
     */
90
    if (!r_has_type(&GlyphDirectory, t_null)) {
91
	pfont->data.get_outline = z42_gdir_get_outline;
92
	pfont->procs.enumerate_glyph = z42_gdir_enumerate_glyph;
93
    } else
94
	pfont->procs.enumerate_glyph = z42_enumerate_glyph;
95
    /*
96
     * The procedures that access glyph information must accept either
97
     * glyph names or glyph indexes.
98
     */
99
    pfont->data.get_glyph_index = z42_get_glyph_index;
100
    pfont->procs.encode_char = z42_encode_char;
101
    pfont->procs.glyph_info = z42_glyph_info;
102
    pfont->procs.glyph_outline = z42_glyph_outline;
103
    return 0;
104
}
105
private int
106
zbuildfont42(i_ctx_t *i_ctx_p)
107
{
108
    os_ptr op = osp;
109
    gs_font_type42 *pfont;
110
    int code = build_gs_TrueType_font(i_ctx_p, op, &pfont, ft_TrueType,
111
				      &st_gs_font_type42, "%Type42BuildChar",
112
				      "%Type42BuildGlyph", bf_options_none);
113
 
114
    if (code < 0)
115
	return code;
116
    return define_gs_font((gs_font *)pfont);
117
}
118
 
119
/*
120
 * Check a parameter for being an array of strings.  Return the parameter
121
 * value even if it is of the wrong type.
122
 */
123
int
124
font_string_array_param(const gs_memory_t *mem, os_ptr op, const char *kstr, ref *psa)
125
{
126
    ref *pvsa;
127
    ref rstr0;
128
    int code;
129
 
130
    if (dict_find_string(op, kstr, &pvsa) <= 0)
131
	return_error(e_invalidfont);
132
    *psa = *pvsa;
133
    /*
134
     * We only check the first element of the array now, as a sanity test;
135
     * elements are checked as needed by string_array_access_proc.
136
     */
137
    if ((code = array_get(mem, pvsa, 0L, &rstr0)) < 0)
138
	return code;
139
    if (!r_has_type(&rstr0, t_string))
140
	return_error(e_typecheck);
141
    return 0;
142
}
143
 
144
/*
145
 * Get a GlyphDirectory if present.  Return 0 if present, 1 if absent,
146
 * or an error code.
147
 */
148
int
149
font_GlyphDirectory_param(os_ptr op, ref *pGlyphDirectory)
150
{
151
    ref *pgdir;
152
 
153
    if (dict_find_string(op, "GlyphDirectory", &pgdir) <= 0)
154
	make_null(pGlyphDirectory);
155
    else if (!r_has_type(pgdir, t_dictionary) && !r_is_array(pgdir))
156
	return_error(e_typecheck);
157
    else
158
	*pGlyphDirectory = *pgdir;
159
    return 0;
160
}
161
 
162
/*
163
 * Access a given byte offset and length in an array of strings.
164
 * This is used for sfnts and for CIDMap.  The int argument is 2 for sfnts
165
 * (because of the strange behavior of odd-length strings), 1 for CIDMap.
166
 * Return code : 0 - success, <0 - error, 
167
 *               >0 - number of accessible bytes (client must cycle).
168
 */
169
int
170
string_array_access_proc(const gs_memory_t *mem, 
171
			 const ref *psa, int modulus, ulong offset,
172
			 uint length, const byte **pdata)
173
{
174
    ulong left = offset;
175
    uint index = 0;
176
 
177
    if (length == 0)
178
        return 0;
179
    for (;; ++index) {
180
	ref rstr;
181
	int code = array_get(mem, psa, index, &rstr);
182
	uint size;
183
 
184
	if (code < 0)
185
	    return code;
186
	if (!r_has_type(&rstr, t_string))
187
	    return_error(e_typecheck);
188
	/*
189
	 * NOTE: According to the Adobe documentation, each sfnts
190
	 * string should have even length.  If the length is odd,
191
	 * the additional byte is padding and should be ignored.
192
	 */
193
	size = r_size(&rstr) & -modulus;
194
	if (left < size) {
195
	    *pdata = rstr.value.const_bytes + left;
196
	    if (left + length > size)
197
		return size - left;
198
	    return 0;
199
	}
200
	left -= size;
201
    }
202
}
203
 
204
/* ------ Initialization procedure ------ */
205
 
206
const op_def zfont42_op_defs[] =
207
{
208
    {"2.buildfont42", zbuildfont42},
209
    op_def_end(0)
210
};
211
 
212
/* Reduce a glyph name to a glyph index if needed. */
213
private gs_glyph
214
glyph_to_index(const gs_font *font, gs_glyph glyph)
215
{
216
    ref gref;
217
    ref *pcstr;
218
 
219
    if (glyph >= GS_MIN_GLYPH_INDEX)
220
	return glyph;
221
    name_index_ref(font->memory, glyph, &gref);
222
    if (dict_find(&pfont_data(font)->CharStrings, &gref, &pcstr) > 0 &&
223
	r_has_type(pcstr, t_integer)
224
	) {
225
	gs_glyph index_glyph = pcstr->value.intval + GS_MIN_GLYPH_INDEX;
226
 
227
	if (index_glyph >= GS_MIN_GLYPH_INDEX && index_glyph <= gs_max_glyph)
228
	    return index_glyph;
229
    }
230
    return GS_MIN_GLYPH_INDEX;	/* glyph 0 is notdef */
231
}
232
private uint
233
z42_get_glyph_index(gs_font_type42 *pfont, gs_glyph glyph)
234
{
235
    gs_glyph gid = glyph_to_index((gs_font *)pfont, glyph);
236
 
237
    return gid - GS_MIN_GLYPH_INDEX;
238
}
239
 
240
/*
241
 * Get a glyph outline from GlyphDirectory.  Return an empty string if
242
 * the glyph is missing or out of range.
243
 */
244
int
245
font_gdir_get_outline(const gs_memory_t *mem, 
246
		      const ref *pgdir, 
247
		      long glyph_index,
248
		      gs_glyph_data_t *pgd)
249
{
250
    ref iglyph;
251
    ref gdef;
252
    ref *pgdef;
253
    int code;
254
 
255
    if (r_has_type(pgdir, t_dictionary)) {
256
	make_int(&iglyph, glyph_index);
257
	code = dict_find(pgdir, &iglyph, &pgdef) - 1; /* 0 => not found */
258
    } else {
259
	code = array_get(mem, pgdir, glyph_index, &gdef);
260
	pgdef = &gdef;
261
    }
262
    if (code < 0) {
263
	gs_glyph_data_from_null(pgd);
264
    } else if (!r_has_type(pgdef, t_string)) {
265
	return_error(e_typecheck);
266
    } else {
267
	gs_glyph_data_from_string(pgd, pgdef->value.const_bytes, r_size(pgdef),
268
				  NULL);
269
    }
270
    return 0;
271
}
272
private int
273
z42_gdir_get_outline(gs_font_type42 * pfont, uint glyph_index,
274
		     gs_glyph_data_t *pgd)
275
{
276
    const font_data *pfdata = pfont_data(pfont);
277
    const ref *pgdir = &pfdata->u.type42.GlyphDirectory;
278
 
279
    return font_gdir_get_outline(pfont->memory, pgdir, (long)glyph_index, pgd);
280
}
281
 
282
/* Enumerate glyphs from CharStrings or loca / glyf. */
283
private int
284
z42_enumerate_glyph(gs_font *font, int *pindex, gs_glyph_space_t glyph_space,
285
		    gs_glyph *pglyph)
286
{
287
    if (glyph_space == GLYPH_SPACE_INDEX)
288
	return gs_type42_enumerate_glyph(font, pindex, glyph_space, pglyph);
289
    else {
290
	const ref *pcsdict = &pfont_data(font)->CharStrings;
291
 
292
	return zchar_enumerate_glyph(font->memory, pcsdict, pindex, pglyph);
293
    }
294
}
295
 
296
/* Enumerate glyphs (keys) from GlyphDirectory instead of loca / glyf. */
297
private int
298
z42_gdir_enumerate_glyph(gs_font *font, int *pindex,
299
			 gs_glyph_space_t glyph_space, gs_glyph *pglyph)
300
{
301
    const ref *pgdict;
302
    int code;
303
 
304
    if (glyph_space == GLYPH_SPACE_INDEX) {
305
	pgdict = &pfont_data(font)->u.type42.GlyphDirectory;
306
	if (!r_has_type(pgdict, t_dictionary)) {
307
	    ref gdef;
308
 
309
	    for (;; (*pindex)++) {
310
		if (array_get(font->memory, pgdict, (long)*pindex, &gdef) < 0) {
311
		    *pindex = 0;
312
		    return 0;
313
		}
314
		if (!r_has_type(&gdef, t_null)) {
315
		    *pglyph = GS_MIN_GLYPH_INDEX + (*pindex)++;
316
		    return 0;
317
		}
318
	    }
319
	}
320
    } else
321
	pgdict = &pfont_data(font)->CharStrings;
322
    /* A trick : use zchar_enumerate_glyph to enumerate GIDs : */
323
    code = zchar_enumerate_glyph(font->memory, pgdict, pindex, pglyph);
324
    if (*pindex != 0 && *pglyph >= gs_min_cid_glyph)
325
	*pglyph	= *pglyph - gs_min_cid_glyph + GS_MIN_GLYPH_INDEX;
326
    return code;
327
}
328
 
329
/*
330
 * Define font procedures that accept either a character name or a glyph
331
 * index as the glyph.
332
 */
333
private gs_glyph
334
z42_encode_char(gs_font *font, gs_char chr, gs_glyph_space_t glyph_space)
335
{
336
    gs_glyph glyph = zfont_encode_char(font, chr, glyph_space);
337
 
338
    return (glyph_space == GLYPH_SPACE_INDEX && glyph != gs_no_glyph ?
339
	    glyph_to_index(font, glyph) : glyph);
340
}
341
private int
342
z42_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *pmat,
343
		  gx_path *ppath, double sbw[4])
344
{
345
    return gs_type42_glyph_outline(font, WMode, glyph_to_index(font, glyph),
346
				   pmat, ppath, sbw);
347
}
348
private int
349
z42_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
350
	       int members, gs_glyph_info_t *info)
351
{   /* fixme : same as z1_glyph_info. */
352
    int wmode = font->WMode;
353
 
354
    return z1_glyph_info_generic(font, glyph, pmat, members, info, gs_type42_glyph_info, wmode);
355
}
356
 
357
/* Procedure for accessing the sfnts array.
358
 * Return code : 0 - success, <0 - error, 
359
 *               >0 - number of accessible bytes (client must cycle).
360
 */
361
private int
362
z42_string_proc(gs_font_type42 * pfont, ulong offset, uint length,
363
		const byte ** pdata)
364
{
365
    return string_array_access_proc(pfont->memory, &pfont_data(pfont)->u.type42.sfnts, 2,
366
				    offset, length, pdata);
367
}