]>
git.ipfire.org Git - thirdparty/cups.git/blob - pstoraster/zfont0.c
1 /* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
3 This file is part of GNU Ghostscript.
5 GNU Ghostscript is distributed in the hope that it will be useful, but
6 WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
7 to anyone for the consequences of using it or for whether it serves any
8 particular purpose or works at all, unless he says so in writing. Refer
9 to the GNU General Public License for full details.
11 Everyone is granted permission to copy, modify and redistribute GNU
12 Ghostscript, but only under the conditions described in the GNU General
13 Public License. A copy of this license is supposed to have been given
14 to you along with GNU Ghostscript so you can know your rights and
15 responsibilities. It should be in a file named COPYING. Among other
16 things, the copyright notice and this notice must be preserved on all
19 Aladdin Enterprises supports the work of the GNU Project, but is not
20 affiliated with the Free Software Foundation or the GNU Project. GNU
21 Ghostscript, as distributed by Aladdin Enterprises, does not require any
22 GNU software to build or run it.
26 /* Composite font creation operator */
31 * The following lines used to say:
32 * #include "gsmatrix.h"
33 * #include "gxdevice.h" /. for gxfont.h ./
34 * Tony Li says the longer list is necessary to keep the GNU compiler
35 * happy, but this is pretty hard to understand....
39 #include "gzstate.h" /* must precede gxdevice */
40 #include "gxdevice.h" /* must precede gxfont */
53 /* Composite font procedures */
54 extern font_proc_init_fstack(gs_type0_init_fstack
);
55 extern font_proc_define_font(gs_type0_define_font
);
56 extern font_proc_make_font(gs_type0_make_font
);
57 extern font_proc_next_glyph(gs_type0_next_glyph
);
59 /* Imported from zfcmap.c */
60 int ztype0_get_cmap(P3(const gs_cmap
** ppcmap
, const ref
* pfdepvector
,
63 /* Forward references */
64 private font_proc_define_font(ztype0_define_font
);
65 private font_proc_make_font(ztype0_make_font
);
66 private int ensure_char_entry(P4(os_ptr
, const char *, byte
*, int));
68 /* <string|name> <font_dict> .buildfont0 <string|name> <font> */
69 /* Build a type 0 (composite) font. */
71 zbuildfont0(os_ptr op
)
82 check_type(*op
, t_dictionary
);
87 if (dict_find_string(op
, "FMapType", &pfmaptype
) <= 0 ||
88 !r_has_type(pfmaptype
, t_integer
) ||
89 pfmaptype
->value
.intval
< (int)fmap_type_min
||
90 pfmaptype
->value
.intval
> (int)fmap_type_max
||
91 dict_find_string(op
, "FDepVector", &pfdepvector
) <= 0 ||
92 !r_is_array(pfdepvector
)
94 return_error(e_invalidfont
);
95 data
.FMapType
= (fmap_type
) pfmaptype
->value
.intval
;
97 * Adding elements below could cause the font dictionary to be
98 * resized, which would invalidate pfdepvector.
100 fdepvector
= *pfdepvector
;
102 /* Check that every element of the FDepVector is a font. */
103 data
.fdep_size
= r_size(&fdepvector
);
104 for (i
= 0; i
< data
.fdep_size
; i
++) {
108 array_get(&fdepvector
, i
, &fdep
);
109 if ((code
= font_param(&fdep
, &psub
)) < 0)
112 * Check the inheritance rules. Allowed configurations
113 * (paths from root font) are defined by the regular
115 * (shift | double_escape escape* | escape*)
116 * non_modal* non_composite
118 if (psub
->FontType
== ft_composite
) {
119 const gs_font_type0
*const psub0
= (const gs_font_type0
*)psub
;
120 fmap_type fmt
= psub0
->data
.FMapType
;
122 if (fmt
== fmap_double_escape
||
124 (fmt
== fmap_escape
&&
125 !(data
.FMapType
== fmap_escape
||
126 data
.FMapType
== fmap_double_escape
))
128 return_error(e_invalidfont
);
131 switch (data
.FMapType
) {
133 case fmap_double_escape
: /* need EscChar */
134 code
= ensure_char_entry(op
, "EscChar", &data
.EscChar
, 255);
136 case fmap_shift
: /* need ShiftIn & ShiftOut */
137 code
= ensure_char_entry(op
, "ShiftIn", &data
.ShiftIn
, 15);
139 code
= ensure_char_entry(op
, "ShiftOut", &data
.ShiftOut
, 14);
141 case fmap_SubsVector
: /* need SubsVector */
146 if (dict_find_string(op
, "SubsVector", &psubsvector
) <= 0 ||
147 !r_has_type(psubsvector
, t_string
) ||
148 (svsize
= r_size(psubsvector
)) == 0 ||
149 (data
.subs_width
= (int)*psubsvector
->value
.bytes
+ 1) > 4 ||
150 (svsize
- 1) % data
.subs_width
!= 0
152 return_error(e_invalidfont
);
153 data
.subs_size
= (svsize
- 1) / data
.subs_width
;
154 data
.SubsVector
.data
= psubsvector
->value
.bytes
+ 1;
155 data
.SubsVector
.size
= svsize
- 1;
157 case fmap_CMap
: /* need CMap */
158 code
= ztype0_get_cmap(&data
.CMap
, (const ref
*)&fdepvector
,
167 * Save the old FID in case we have to back out.
168 * build_gs_font will return an error if there is a FID entry
169 * but it doesn't reference a valid font.
174 if (dict_find_string(op
, "FID", &pfid
) <= 0)
175 make_null(&save_FID
);
180 build_proc_refs build
;
182 code
= build_proc_name_refs(&build
,
183 "%Type0BuildChar", "%Type0BuildGlyph");
186 code
= build_gs_font(op
, (gs_font
**) & pfont
,
187 ft_composite
, &st_gs_font_type0
, &build
,
192 /* Fill in the rest of the basic font data. */
193 pfont
->procs
.init_fstack
= gs_type0_init_fstack
;
194 pfont
->procs
.next_char
= 0; /* superseded by next_glyph */
195 pfont
->procs
.define_font
= ztype0_define_font
;
196 pfont
->procs
.make_font
= ztype0_make_font
;
197 pfont
->procs
.next_glyph
= gs_type0_next_glyph
;
198 if (dict_find_string(op
, "PrefEnc", &pprefenc
) <= 0) {
202 if ((code
= dict_put_string(op
, "PrefEnc", &nul
)) < 0)
205 /* Fill in the font data */
206 pdata
= pfont_data(pfont
);
207 data
.encoding_size
= r_size(&pdata
->Encoding
);
209 (uint
*) ialloc_byte_array(data
.encoding_size
, sizeof(uint
),
210 "buildfont0(Encoding)");
211 if (data
.Encoding
== 0) {
212 code
= gs_note_error(e_VMerror
);
215 /* Fill in the encoding vector, checking to make sure that */
216 /* each element is an integer between 0 and fdep_size-1. */
217 for (i
= 0; i
< data
.encoding_size
; i
++) {
220 array_get(&pdata
->Encoding
, i
, &enc
);
221 if (!r_has_type(&enc
, t_integer
)) {
222 code
= gs_note_error(e_typecheck
);
225 if ((ulong
) enc
.value
.intval
>= data
.fdep_size
) {
226 code
= gs_note_error(e_rangecheck
);
229 data
.Encoding
[i
] = (uint
) enc
.value
.intval
;
232 ialloc_struct_array(data
.fdep_size
, gs_font
*,
233 &st_gs_font_ptr_element
,
234 "buildfont0(FDepVector)");
235 if (data
.FDepVector
== 0) {
236 code
= gs_note_error(e_VMerror
);
239 for (i
= 0; i
< data
.fdep_size
; i
++) {
243 array_get(&fdepvector
, i
, &fdep
);
244 /* The lookup can't fail, because of the pre-check above. */
245 dict_find_string(&fdep
, "FID", &pfid
);
246 data
.FDepVector
[i
] = r_ptr(pfid
, gs_font
);
249 code
= define_gs_font((gs_font
*) pfont
);
253 /* Undo the insertion of the FID entry in the dictionary. */
254 if (r_has_type(&save_FID
, t_null
)) {
257 name_enter_string("FID", &rnfid
);
258 dict_undef(op
, &rnfid
);
260 dict_put_string(op
, "FID", &save_FID
);
261 gs_free_object(pfont
->memory
, pfont
, "buildfont0(font)");
264 /* If a newly defined or scaled composite font had to scale */
265 /* any composite sub-fonts, adjust the parent font's FDepVector. */
266 /* This is called only if gs_type0_define/make_font */
267 /* actually changed the FDepVector. */
269 ztype0_adjust_FDepVector(gs_font_type0
* pfont
)
271 gs_font
**pdep
= pfont
->data
.FDepVector
;
273 uint fdep_size
= pfont
->data
.fdep_size
;
276 int code
= ialloc_ref_array(&newdep
, a_readonly
, fdep_size
,
277 "ztype0_adjust_matrix");
281 for (prdep
= newdep
.value
.refs
, i
= 0; i
< fdep_size
; i
++, prdep
++) {
282 const ref
*pdict
= pfont_dict(pdep
[i
]);
284 ref_assign_new(prdep
, pdict
);
286 return dict_put_string(pfont_dict(pfont
), "FDepVector", &newdep
);
289 ztype0_define_font(gs_font_dir
* pdir
, gs_font
* pfont
)
291 gs_font_type0
*const pfont0
= (gs_font_type0
*)pfont
;
292 gs_font
**pdep
= pfont0
->data
.FDepVector
;
293 int code
= gs_type0_define_font(pdir
, pfont
);
295 if (code
< 0 || pfont0
->data
.FDepVector
== pdep
)
297 return ztype0_adjust_FDepVector(pfont0
);
300 ztype0_make_font(gs_font_dir
* pdir
, const gs_font
* pfont
,
301 const gs_matrix
* pmat
, gs_font
** ppfont
)
303 gs_font_type0
**const ppfont0
= (gs_font_type0
**)ppfont
;
304 gs_font
**pdep
= (*ppfont0
)->data
.FDepVector
;
307 code
= zdefault_make_font(pdir
, pfont
, pmat
, ppfont
);
310 code
= gs_type0_make_font(pdir
, pfont
, pmat
, ppfont
);
313 if ((*ppfont0
)->data
.FDepVector
== pdep
)
315 return ztype0_adjust_FDepVector(*ppfont0
);
318 /* ------ Internal routines ------ */
320 /* Find or add a character entry in a font dictionary. */
322 ensure_char_entry(os_ptr op
, const char *kstr
,
323 byte
* pvalue
, int default_value
)
327 if (dict_find_string(op
, kstr
, &pentry
) <= 0) {
330 make_int(&ent
, default_value
);
331 *pvalue
= (byte
) default_value
;
332 return dict_put_string(op
, kstr
, &ent
);
334 check_int_leu_only(*pentry
, 255);
335 *pvalue
= (byte
) pentry
->value
.intval
;
340 /* ------ Initialization procedure ------ */
342 const op_def zfont0_op_defs
[] =
344 {"2.buildfont0", zbuildfont0
},