xref: /plan9-contrib/sys/src/cmd/gs/src/zfcid1.c (revision 409b3aff3015608d158d294a437acca386aba474)
1593dc095SDavid du Colombier /* Copyright (C) 2000, 2001 Aladdin Enterprises.  All rights reserved.
23ff48bf5SDavid du Colombier 
3593dc095SDavid du Colombier   This software is provided AS-IS with no warranty, either express or
4593dc095SDavid du Colombier   implied.
53ff48bf5SDavid du Colombier 
6593dc095SDavid du Colombier   This software is distributed under license and may not be copied,
7593dc095SDavid du Colombier   modified or distributed except as expressly authorized under the terms
8593dc095SDavid du Colombier   of the license contained in the file LICENSE in this distribution.
93ff48bf5SDavid du Colombier 
10593dc095SDavid du Colombier   For more information about licensing, please refer to
11593dc095SDavid du Colombier   http://www.ghostscript.com/licensing/. For information on
12593dc095SDavid du Colombier   commercial licensing, go to http://www.artifex.com/licensing/ or
13593dc095SDavid du Colombier   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14593dc095SDavid du Colombier   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
153ff48bf5SDavid du Colombier */
163ff48bf5SDavid du Colombier 
17593dc095SDavid du Colombier /* $Id: zfcid1.c,v 1.23 2004/11/19 04:39:11 ray Exp $ */
183ff48bf5SDavid du Colombier /* CIDFontType 1 and 2 operators */
193ff48bf5SDavid du Colombier #include "memory_.h"
203ff48bf5SDavid du Colombier #include "ghost.h"
213ff48bf5SDavid du Colombier #include "oper.h"
223ff48bf5SDavid du Colombier #include "gsmatrix.h"
233ff48bf5SDavid du Colombier #include "gsccode.h"
243ff48bf5SDavid du Colombier #include "gsstruct.h"
25593dc095SDavid du Colombier #include "gsgcache.h"
263ff48bf5SDavid du Colombier #include "gxfcid.h"
273ff48bf5SDavid du Colombier #include "bfont.h"
283ff48bf5SDavid du Colombier #include "icid.h"
293ff48bf5SDavid du Colombier #include "idict.h"
303ff48bf5SDavid du Colombier #include "idparam.h"
313ff48bf5SDavid du Colombier #include "ifcid.h"
32593dc095SDavid du Colombier #include "ichar1.h"
333ff48bf5SDavid du Colombier #include "ifont42.h"
343ff48bf5SDavid du Colombier #include "store.h"
35593dc095SDavid du Colombier #include "stream.h"
36593dc095SDavid du Colombier #include "files.h"
373ff48bf5SDavid du Colombier 
383ff48bf5SDavid du Colombier /* ---------------- CIDFontType 1 (FontType 10) ---------------- */
393ff48bf5SDavid du Colombier 
403ff48bf5SDavid du Colombier /* <string|name> <font_dict> .buildfont10 <string|name> <font> */
413ff48bf5SDavid du Colombier private int
zbuildfont10(i_ctx_t * i_ctx_p)423ff48bf5SDavid du Colombier zbuildfont10(i_ctx_t *i_ctx_p)
433ff48bf5SDavid du Colombier {
443ff48bf5SDavid du Colombier     os_ptr op = osp;
453ff48bf5SDavid du Colombier     build_proc_refs build;
463ff48bf5SDavid du Colombier     int code = build_gs_font_procs(op, &build);
473ff48bf5SDavid du Colombier     gs_cid_system_info_t cidsi;
483ff48bf5SDavid du Colombier     gs_font_base *pfont;
493ff48bf5SDavid du Colombier 
503ff48bf5SDavid du Colombier     if (code < 0)
513ff48bf5SDavid du Colombier 	return code;
523ff48bf5SDavid du Colombier     code = cid_font_system_info_param(&cidsi, op);
533ff48bf5SDavid du Colombier     if (code < 0)
543ff48bf5SDavid du Colombier 	return code;
553ff48bf5SDavid du Colombier     make_null(&build.BuildChar);	/* only BuildGlyph */
563ff48bf5SDavid du Colombier     code = build_gs_simple_font(i_ctx_p, op, &pfont, ft_CID_user_defined,
573ff48bf5SDavid du Colombier 				&st_gs_font_cid1, &build,
583ff48bf5SDavid du Colombier 				bf_Encoding_optional |
593ff48bf5SDavid du Colombier 				bf_UniqueID_ignored);
603ff48bf5SDavid du Colombier     if (code < 0)
613ff48bf5SDavid du Colombier 	return code;
623ff48bf5SDavid du Colombier     ((gs_font_cid1 *)pfont)->cidata.CIDSystemInfo = cidsi;
633ff48bf5SDavid du Colombier     return define_gs_font((gs_font *)pfont);
643ff48bf5SDavid du Colombier }
653ff48bf5SDavid du Colombier 
663ff48bf5SDavid du Colombier /* ---------------- CIDFontType 2 (FontType 11) ---------------- */
673ff48bf5SDavid du Colombier 
683ff48bf5SDavid du Colombier /* ------ Accessing ------ */
693ff48bf5SDavid du Colombier 
703ff48bf5SDavid du Colombier /* Map a glyph CID to a TrueType glyph number using the CIDMap. */
713ff48bf5SDavid du Colombier private int
z11_CIDMap_proc(gs_font_cid2 * pfont,gs_glyph glyph)723ff48bf5SDavid du Colombier z11_CIDMap_proc(gs_font_cid2 *pfont, gs_glyph glyph)
733ff48bf5SDavid du Colombier {
743ff48bf5SDavid du Colombier     const ref *pcidmap = &pfont_data(pfont)->u.type42.CIDMap;
753ff48bf5SDavid du Colombier     ulong cid = glyph - gs_min_cid_glyph;
763ff48bf5SDavid du Colombier     int gdbytes = pfont->cidata.common.GDBytes;
773ff48bf5SDavid du Colombier     int gnum = 0;
783ff48bf5SDavid du Colombier     const byte *data;
793ff48bf5SDavid du Colombier     int i, code;
803ff48bf5SDavid du Colombier     ref rcid;
813ff48bf5SDavid du Colombier     ref *prgnum;
823ff48bf5SDavid du Colombier 
833ff48bf5SDavid du Colombier     switch (r_type(pcidmap)) {
843ff48bf5SDavid du Colombier     case t_string:
853ff48bf5SDavid du Colombier 	if (cid >= r_size(pcidmap) / gdbytes)
863ff48bf5SDavid du Colombier 	    return_error(e_rangecheck);
873ff48bf5SDavid du Colombier 	data = pcidmap->value.const_bytes + cid * gdbytes;
883ff48bf5SDavid du Colombier 	break;
893ff48bf5SDavid du Colombier     case t_integer:
903ff48bf5SDavid du Colombier 	return cid + pcidmap->value.intval;
913ff48bf5SDavid du Colombier     case t_dictionary:
923ff48bf5SDavid du Colombier 	make_int(&rcid, cid);
933ff48bf5SDavid du Colombier 	code = dict_find(pcidmap, &rcid, &prgnum);
943ff48bf5SDavid du Colombier 	if (code <= 0)
953ff48bf5SDavid du Colombier 	    return (code < 0 ? code : gs_note_error(e_undefined));
963ff48bf5SDavid du Colombier 	if (!r_has_type(prgnum, t_integer))
973ff48bf5SDavid du Colombier 	    return_error(e_typecheck);
983ff48bf5SDavid du Colombier 	return prgnum->value.intval;
993ff48bf5SDavid du Colombier     default:			/* array type */
100593dc095SDavid du Colombier         code = string_array_access_proc(pfont->memory, pcidmap, 1, cid * gdbytes,
1013ff48bf5SDavid du Colombier 					gdbytes, &data);
1023ff48bf5SDavid du Colombier 
1033ff48bf5SDavid du Colombier 	if (code < 0)
1043ff48bf5SDavid du Colombier 	    return code;
105593dc095SDavid du Colombier 	if ( code > 0 )
106593dc095SDavid du Colombier 	    return_error(e_invalidfont);
1073ff48bf5SDavid du Colombier     }
1083ff48bf5SDavid du Colombier     for (i = 0; i < gdbytes; ++i)
1093ff48bf5SDavid du Colombier 	gnum = (gnum << 8) + data[i];
1103ff48bf5SDavid du Colombier     return gnum;
1113ff48bf5SDavid du Colombier }
1123ff48bf5SDavid du Colombier 
1133ff48bf5SDavid du Colombier /* Handle MetricsCount when accessing outline or metrics information. */
1143ff48bf5SDavid du Colombier private int
z11_get_outline(gs_font_type42 * pfont,uint glyph_index,gs_glyph_data_t * pgd)1153ff48bf5SDavid du Colombier z11_get_outline(gs_font_type42 * pfont, uint glyph_index,
116593dc095SDavid du Colombier 		gs_glyph_data_t *pgd)
1173ff48bf5SDavid du Colombier {
1183ff48bf5SDavid du Colombier     gs_font_cid2 *const pfcid = (gs_font_cid2 *)pfont;
1193ff48bf5SDavid du Colombier     int skip = pfcid->cidata.MetricsCount << 1;
120593dc095SDavid du Colombier     int code = pfcid->cidata.orig_procs.get_outline(pfont, glyph_index, pgd);
1213ff48bf5SDavid du Colombier 
1223ff48bf5SDavid du Colombier     if (code >= 0) {
123593dc095SDavid du Colombier 	uint size = pgd->bits.size;
1243ff48bf5SDavid du Colombier 
1253ff48bf5SDavid du Colombier 	if (size <= skip) {
126593dc095SDavid du Colombier 	    gs_glyph_data_free(pgd, "z11_get_outline");
127593dc095SDavid du Colombier 	    gs_glyph_data_from_null(pgd);
1283ff48bf5SDavid du Colombier 	} else {
129593dc095SDavid du Colombier 	    gs_glyph_data_substring(pgd, skip, size - skip);
1303ff48bf5SDavid du Colombier 	}
1313ff48bf5SDavid du Colombier     }
1323ff48bf5SDavid du Colombier     return code;
1333ff48bf5SDavid du Colombier }
134593dc095SDavid du Colombier 
135593dc095SDavid du Colombier #define GET_U16_MSB(p) (((uint)((p)[0]) << 8) + (p)[1])
136593dc095SDavid du Colombier #define GET_S16_MSB(p) (int)((GET_U16_MSB(p) ^ 0x8000) - 0x8000)
137593dc095SDavid du Colombier 
138*409b3affSDavid du Colombier double	recipunitsperem(gs_font_type42 *pfont);
139*409b3affSDavid du Colombier 
1403ff48bf5SDavid du Colombier private int
z11_get_metrics(gs_font_type42 * pfont,uint glyph_index,int wmode,float sbw[4])1413ff48bf5SDavid du Colombier z11_get_metrics(gs_font_type42 * pfont, uint glyph_index, int wmode,
1423ff48bf5SDavid du Colombier 		float sbw[4])
1433ff48bf5SDavid du Colombier {
1443ff48bf5SDavid du Colombier     gs_font_cid2 *const pfcid = (gs_font_cid2 *)pfont;
1453ff48bf5SDavid du Colombier     int skip = pfcid->cidata.MetricsCount << 1;
146593dc095SDavid du Colombier     gs_glyph_data_t gdata;
1473ff48bf5SDavid du Colombier     const byte *pmetrics;
1483ff48bf5SDavid du Colombier     int lsb, width;
1493ff48bf5SDavid du Colombier     int code = 0;
1503ff48bf5SDavid du Colombier 
151593dc095SDavid du Colombier     gdata.memory = pfont->memory;
152593dc095SDavid du Colombier     if (wmode >= skip >> 2 ||
153593dc095SDavid du Colombier 	(code = pfcid->cidata.orig_procs.get_outline(pfont, glyph_index, &gdata)) < 0 ||
154593dc095SDavid du Colombier 	gdata.bits.size < skip
1553ff48bf5SDavid du Colombier 	)
1563ff48bf5SDavid du Colombier 	return pfcid->cidata.orig_procs.get_metrics(pfont, glyph_index, wmode,
1573ff48bf5SDavid du Colombier 						    sbw);
158593dc095SDavid du Colombier     pmetrics = gdata.bits.data + skip - 4 - (wmode << 2);
159593dc095SDavid du Colombier     lsb = GET_S16_MSB(pmetrics + 2);
160593dc095SDavid du Colombier     width = GET_U16_MSB(pmetrics + 0);
1613ff48bf5SDavid du Colombier     {
162*409b3affSDavid du Colombier 	double factor = recipunitsperem(pfont);
1633ff48bf5SDavid du Colombier 
1643ff48bf5SDavid du Colombier 	if (wmode) {
1653ff48bf5SDavid du Colombier 	    sbw[0] = 0, sbw[1] = -lsb * factor;
1663ff48bf5SDavid du Colombier 	    sbw[2] = 0, sbw[3] = -width * factor;
1673ff48bf5SDavid du Colombier 	} else {
1683ff48bf5SDavid du Colombier 	    sbw[0] = lsb * factor, sbw[1] = 0;
1693ff48bf5SDavid du Colombier 	    sbw[2] = width * factor, sbw[3] = 0;
1703ff48bf5SDavid du Colombier 	}
1713ff48bf5SDavid du Colombier     }
172593dc095SDavid du Colombier     gs_glyph_data_free(&gdata, "z11_get_metrics");
1733ff48bf5SDavid du Colombier     return 0;
1743ff48bf5SDavid du Colombier }
1753ff48bf5SDavid du Colombier 
176593dc095SDavid du Colombier private int
z11_glyph_info_aux(gs_font * font,gs_glyph glyph,const gs_matrix * pmat,int members,gs_glyph_info_t * info)177593dc095SDavid du Colombier z11_glyph_info_aux(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
178593dc095SDavid du Colombier 		     int members, gs_glyph_info_t *info)
179593dc095SDavid du Colombier {
180593dc095SDavid du Colombier     gs_font_cid2 *fontCID2 = (gs_font_cid2 *)font;
181593dc095SDavid du Colombier     uint glyph_index;
182593dc095SDavid du Colombier     int code = (glyph > GS_MIN_GLYPH_INDEX
183593dc095SDavid du Colombier 	    ? glyph - GS_MIN_GLYPH_INDEX
184593dc095SDavid du Colombier 	    : fontCID2->cidata.CIDMap_proc(fontCID2, glyph));
185593dc095SDavid du Colombier 
186593dc095SDavid du Colombier     if(code < 0)
187593dc095SDavid du Colombier 	return code;
188593dc095SDavid du Colombier     glyph_index = (uint)code;
189593dc095SDavid du Colombier     return gs_type42_glyph_info_by_gid(font, glyph, pmat, members, info, glyph_index);
190593dc095SDavid du Colombier }
191593dc095SDavid du Colombier 
192593dc095SDavid du Colombier private int
z11_glyph_info(gs_font * font,gs_glyph glyph,const gs_matrix * pmat,int members,gs_glyph_info_t * info)193593dc095SDavid du Colombier z11_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat,
194593dc095SDavid du Colombier 		     int members, gs_glyph_info_t *info)
195593dc095SDavid du Colombier {
196593dc095SDavid du Colombier     int wmode = (members & GLYPH_INFO_WIDTH0 ? 0 : 1);
197593dc095SDavid du Colombier 
198593dc095SDavid du Colombier     return z1_glyph_info_generic(font, glyph, pmat, members, info,
199593dc095SDavid du Colombier 				    &z11_glyph_info_aux, wmode);
200593dc095SDavid du Colombier }
201593dc095SDavid du Colombier 
202593dc095SDavid du Colombier 
203593dc095SDavid du Colombier /* Enumerate glyphs (keys) from GlyphDirectory instead of loca / glyf. */
204593dc095SDavid du Colombier private int
z11_enumerate_glyph(gs_font * font,int * pindex,gs_glyph_space_t glyph_space,gs_glyph * pglyph)205593dc095SDavid du Colombier z11_enumerate_glyph(gs_font *font, int *pindex,
206593dc095SDavid du Colombier 			 gs_glyph_space_t glyph_space, gs_glyph *pglyph)
207593dc095SDavid du Colombier {
208593dc095SDavid du Colombier     gs_font_cid2 *pfont = (gs_font_cid2 *)font;
209593dc095SDavid du Colombier     int code0 = z11_CIDMap_proc(pfont, GS_MIN_CID_GLYPH);
210593dc095SDavid du Colombier     int code;
211593dc095SDavid du Colombier 
212593dc095SDavid du Colombier     for (;;) {
213593dc095SDavid du Colombier 	code = z11_CIDMap_proc(pfont, GS_MIN_CID_GLYPH + *pindex);
214593dc095SDavid du Colombier 
215593dc095SDavid du Colombier 	if (code < 0) {
216593dc095SDavid du Colombier 	    *pindex = 0;
217593dc095SDavid du Colombier 	    return 0;
218593dc095SDavid du Colombier 	}
219593dc095SDavid du Colombier 	(*pindex)++;
220593dc095SDavid du Colombier 	if (*pindex == 1 || code != code0)
221593dc095SDavid du Colombier 	    break;
222593dc095SDavid du Colombier 	/* else skip an underfined glyph */
223593dc095SDavid du Colombier     }
224593dc095SDavid du Colombier     if (glyph_space == GLYPH_SPACE_INDEX)
225593dc095SDavid du Colombier 	*pglyph = GS_MIN_GLYPH_INDEX + (uint)code;
226593dc095SDavid du Colombier     else
227593dc095SDavid du Colombier 	*pglyph = GS_MIN_CID_GLYPH + (uint)(*pindex - 1);
228593dc095SDavid du Colombier     return 0;
229593dc095SDavid du Colombier }
230593dc095SDavid du Colombier 
231593dc095SDavid du Colombier private uint
z11_get_glyph_index(gs_font_type42 * pfont,gs_glyph glyph)232593dc095SDavid du Colombier z11_get_glyph_index(gs_font_type42 *pfont, gs_glyph glyph)
233593dc095SDavid du Colombier {
234593dc095SDavid du Colombier     int code = z11_CIDMap_proc((gs_font_cid2 *)pfont, glyph);
235593dc095SDavid du Colombier 
236593dc095SDavid du Colombier     return (code < 0 ? 0 /* notdef */: (uint)code);
237593dc095SDavid du Colombier }
238593dc095SDavid du Colombier 
239593dc095SDavid du Colombier 
240593dc095SDavid du Colombier private int
z11_glyph_outline(gs_font * font,int WMode,gs_glyph glyph,const gs_matrix * pmat,gx_path * ppath,double sbw[4])241593dc095SDavid du Colombier z11_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matrix *pmat,
242593dc095SDavid du Colombier 		  gx_path *ppath, double sbw[4])
243593dc095SDavid du Colombier {
244593dc095SDavid du Colombier     return gs_type42_glyph_outline(font, WMode,
245593dc095SDavid du Colombier 	    z11_get_glyph_index((gs_font_type42 *)font, glyph) + GS_MIN_GLYPH_INDEX,
246593dc095SDavid du Colombier 				   pmat, ppath, sbw);
247593dc095SDavid du Colombier }
248593dc095SDavid du Colombier 
2493ff48bf5SDavid du Colombier /* ------ Defining ------ */
2503ff48bf5SDavid du Colombier 
2513ff48bf5SDavid du Colombier /* <string|name> <font_dict> .buildfont11 <string|name> <font> */
2523ff48bf5SDavid du Colombier private int
zbuildfont11(i_ctx_t * i_ctx_p)2533ff48bf5SDavid du Colombier zbuildfont11(i_ctx_t *i_ctx_p)
2543ff48bf5SDavid du Colombier {
2553ff48bf5SDavid du Colombier     os_ptr op = osp;
2563ff48bf5SDavid du Colombier     gs_font_cid_data common;
2573ff48bf5SDavid du Colombier     gs_font_type42 *pfont;
2583ff48bf5SDavid du Colombier     gs_font_cid2 *pfcid;
2593ff48bf5SDavid du Colombier     int MetricsCount;
260593dc095SDavid du Colombier     ref rcidmap, ignore_gdir, file, *pfile, cfnstr, *pCIDFontName, CIDFontName;
261593dc095SDavid du Colombier     ulong loca_glyph_pos[2][2];
2623ff48bf5SDavid du Colombier     int code = cid_font_data_param(op, &common, &ignore_gdir);
2633ff48bf5SDavid du Colombier 
2643ff48bf5SDavid du Colombier     if (code < 0 ||
265593dc095SDavid du Colombier 	(code = dict_find_string(op, "CIDFontName", &pCIDFontName)) <= 0 ||
2663ff48bf5SDavid du Colombier 	(code = dict_int_param(op, "MetricsCount", 0, 4, 0, &MetricsCount)) < 0
2673ff48bf5SDavid du Colombier 	)
2683ff48bf5SDavid du Colombier 	return code;
269593dc095SDavid du Colombier     /*
270593dc095SDavid du Colombier      * Since build_gs_simple_font may resize the dictionary and cause
271593dc095SDavid du Colombier      * pointers to become invalid, save CIDFontName
272593dc095SDavid du Colombier      */
273593dc095SDavid du Colombier     CIDFontName = *pCIDFontName;
2743ff48bf5SDavid du Colombier     if (MetricsCount & 1)	/* only allowable values are 0, 2, 4 */
2753ff48bf5SDavid du Colombier 	return_error(e_rangecheck);
276593dc095SDavid du Colombier     code = dict_find_string(op, "File", &pfile);
277593dc095SDavid du Colombier     if (code < 0 && code != e_dictfull)
278593dc095SDavid du Colombier 	return code;
279593dc095SDavid du Colombier     if (code > 0) {
280593dc095SDavid du Colombier 	ref *file_table_pos, *a, v;
281593dc095SDavid du Colombier 	const char *name[2] = {"loca", "glyf"};
282593dc095SDavid du Colombier 	int i, j;
283593dc095SDavid du Colombier 
284593dc095SDavid du Colombier 	/*
285593dc095SDavid du Colombier 	 * Since build_gs_simple_font may resize the dictionary and cause
286593dc095SDavid du Colombier 	 * pointers to become invalid, save File and CIDFontName
287593dc095SDavid du Colombier 	 */
288593dc095SDavid du Colombier 	file = *pfile;
289593dc095SDavid du Colombier         check_read_type(file, t_file);
290593dc095SDavid du Colombier 	code = dict_find_string(op, "file_table_pos", &file_table_pos);
291593dc095SDavid du Colombier 	if (code <= 0 || r_type(file_table_pos) != t_dictionary)
292593dc095SDavid du Colombier 	    return_error(e_invalidfont);
293593dc095SDavid du Colombier 	for (i = 0; i < 2; i++) {
294593dc095SDavid du Colombier 	    code = dict_find_string(file_table_pos, name[i], &a);
295593dc095SDavid du Colombier 	    if (code <= 0 || r_type(a) != t_array)
296593dc095SDavid du Colombier 		return_error(e_invalidfont);
297593dc095SDavid du Colombier 	    for (j = 0; j < 2; j++) {
298593dc095SDavid du Colombier 	        code = array_get(imemory, a, j, &v);
299593dc095SDavid du Colombier 		if (code < 0 || r_type(&v) != t_integer)
300593dc095SDavid du Colombier 		    return_error(e_invalidfont);
301593dc095SDavid du Colombier 		loca_glyph_pos[i][j] = v.value.intval;
302593dc095SDavid du Colombier 	    }
303593dc095SDavid du Colombier 	}
304593dc095SDavid du Colombier     } else
305593dc095SDavid du Colombier 	pfile = NULL;
306593dc095SDavid du Colombier     code = font_string_array_param(imemory, op, "CIDMap", &rcidmap);
3073ff48bf5SDavid du Colombier     switch (code) {
3083ff48bf5SDavid du Colombier     case 0:			/* in PLRM3 */
3093ff48bf5SDavid du Colombier     gdb:
3103ff48bf5SDavid du Colombier 	/* GDBytes is required for indexing a string or string array. */
3113ff48bf5SDavid du Colombier 	if (common.GDBytes == 0)
3123ff48bf5SDavid du Colombier 	    return_error(e_rangecheck);
3133ff48bf5SDavid du Colombier 	break;
3143ff48bf5SDavid du Colombier     default:
3153ff48bf5SDavid du Colombier 	return code;
3163ff48bf5SDavid du Colombier     case e_typecheck:
3173ff48bf5SDavid du Colombier 	switch (r_type(&rcidmap)) {
3183ff48bf5SDavid du Colombier 	case t_string:		/* in PLRM3 */
3193ff48bf5SDavid du Colombier 	    goto gdb;
3203ff48bf5SDavid du Colombier 	case t_dictionary:	/* added in 3011 */
3213ff48bf5SDavid du Colombier 	case t_integer:		/* added in 3011 */
3223ff48bf5SDavid du Colombier 	    break;
3233ff48bf5SDavid du Colombier 	default:
3243ff48bf5SDavid du Colombier 	    return code;
3253ff48bf5SDavid du Colombier 	}
3263ff48bf5SDavid du Colombier 	break;
3273ff48bf5SDavid du Colombier     }
3283ff48bf5SDavid du Colombier     code = build_gs_TrueType_font(i_ctx_p, op, &pfont, ft_CID_TrueType,
3293ff48bf5SDavid du Colombier 				  &st_gs_font_cid2,
3303ff48bf5SDavid du Colombier 				  (const char *)0, "%Type11BuildGlyph",
3313ff48bf5SDavid du Colombier 				  bf_Encoding_optional |
3323ff48bf5SDavid du Colombier 				  bf_UniqueID_ignored |
3333ff48bf5SDavid du Colombier 				  bf_CharStrings_optional);
3343ff48bf5SDavid du Colombier     if (code < 0)
3353ff48bf5SDavid du Colombier 	return code;
3363ff48bf5SDavid du Colombier     pfcid = (gs_font_cid2 *)pfont;
3373ff48bf5SDavid du Colombier     pfcid->cidata.common = common;
3383ff48bf5SDavid du Colombier     pfcid->cidata.MetricsCount = MetricsCount;
3393ff48bf5SDavid du Colombier     ref_assign(&pfont_data(pfont)->u.type42.CIDMap, &rcidmap);
3403ff48bf5SDavid du Colombier     pfcid->cidata.CIDMap_proc = z11_CIDMap_proc;
341593dc095SDavid du Colombier     pfont->procs.enumerate_glyph = z11_enumerate_glyph;
342593dc095SDavid du Colombier     pfont->procs.glyph_info = z11_glyph_info;
343593dc095SDavid du Colombier     pfont->procs.glyph_outline = z11_glyph_outline;
344593dc095SDavid du Colombier     pfont->data.get_glyph_index = z11_get_glyph_index;
345593dc095SDavid du Colombier     get_font_name(imemory, &cfnstr, &CIDFontName);
346593dc095SDavid du Colombier     copy_font_name(&pfcid->font_name, &cfnstr);
3473ff48bf5SDavid du Colombier     if (MetricsCount) {
3483ff48bf5SDavid du Colombier 	/* "Wrap" the glyph accessor procedures. */
3493ff48bf5SDavid du Colombier 	pfcid->cidata.orig_procs.get_outline = pfont->data.get_outline;
3503ff48bf5SDavid du Colombier 	pfont->data.get_outline = z11_get_outline;
3513ff48bf5SDavid du Colombier 	pfcid->cidata.orig_procs.get_metrics = pfont->data.get_metrics;
3523ff48bf5SDavid du Colombier 	pfont->data.get_metrics = z11_get_metrics;
353593dc095SDavid du Colombier     } else if(pfile != NULL) {
354593dc095SDavid du Colombier         /*
355593dc095SDavid du Colombier 	 * We assume that disk fonts has no MetricsCount.
356593dc095SDavid du Colombier 	 * We could do not, but the number of virtual function wariants increases.
357593dc095SDavid du Colombier 	 */
358593dc095SDavid du Colombier 	stream *s;
359593dc095SDavid du Colombier 
360593dc095SDavid du Colombier 	check_read_file(s, &file);
361593dc095SDavid du Colombier 	pfont->data.loca = loca_glyph_pos[0][0];
362593dc095SDavid du Colombier 	pfont->data.glyf = loca_glyph_pos[1][0];
363593dc095SDavid du Colombier 	pfont->data.get_outline = gs_get_glyph_data_cached;
364593dc095SDavid du Colombier    	pfont->data.gdcache = gs_glyph_cache__alloc(pfont, s, gs_type42_get_outline_from_TT_file);
3653ff48bf5SDavid du Colombier     }
3663ff48bf5SDavid du Colombier     return define_gs_font((gs_font *)pfont);
3673ff48bf5SDavid du Colombier }
3683ff48bf5SDavid du Colombier 
3693ff48bf5SDavid du Colombier /* <cid11font> <cid> .type11mapcid <glyph_index> */
3703ff48bf5SDavid du Colombier private int
ztype11mapcid(i_ctx_t * i_ctx_p)3713ff48bf5SDavid du Colombier ztype11mapcid(i_ctx_t *i_ctx_p)
3723ff48bf5SDavid du Colombier {
3733ff48bf5SDavid du Colombier     os_ptr op = osp;
3743ff48bf5SDavid du Colombier     gs_font *pfont;
3753ff48bf5SDavid du Colombier     int code = font_param(op - 1, &pfont);
3763ff48bf5SDavid du Colombier 
3773ff48bf5SDavid du Colombier     if (code < 0)
3783ff48bf5SDavid du Colombier 	return code;
379593dc095SDavid du Colombier     check_type(*op, t_integer);
380593dc095SDavid du Colombier #if defined(TEST)
381593dc095SDavid du Colombier     /* Allow a Type 42 font here, for testing .wrapfont. */
382593dc095SDavid du Colombier     if (pfont->FontType == ft_TrueType) {
383593dc095SDavid du Colombier 	/* Use the CID as the glyph index. */
384593dc095SDavid du Colombier 	if (op->value.intval < 0 ||
385593dc095SDavid du Colombier 	    op->value.intval >= ((gs_font_type42 *)pfont)->data.numGlyphs
386593dc095SDavid du Colombier 	    )
387593dc095SDavid du Colombier 	    return_error(e_rangecheck);
388593dc095SDavid du Colombier 	code = (int)op->value.intval;
389593dc095SDavid du Colombier     } else
390593dc095SDavid du Colombier #endif
391593dc095SDavid du Colombier     {
3923ff48bf5SDavid du Colombier 	if (pfont->FontType != ft_CID_TrueType)
3933ff48bf5SDavid du Colombier 	    return_error(e_invalidfont);
3943ff48bf5SDavid du Colombier 	code = z11_CIDMap_proc((gs_font_cid2 *)pfont,
3953ff48bf5SDavid du Colombier 			(gs_glyph)(gs_min_cid_glyph + op->value.intval));
396593dc095SDavid du Colombier     }
3973ff48bf5SDavid du Colombier     if (code < 0)
3983ff48bf5SDavid du Colombier 	return code;
3993ff48bf5SDavid du Colombier     make_int(op - 1, code);
4003ff48bf5SDavid du Colombier     pop(1);
4013ff48bf5SDavid du Colombier     return 0;
4023ff48bf5SDavid du Colombier }
4033ff48bf5SDavid du Colombier 
404593dc095SDavid du Colombier /* <Decoding> <TT_cmap> <SubstNWP> <GDBytes> <CIDMap> .fillCIDMap - */
405593dc095SDavid du Colombier private int
zfillCIDMap(i_ctx_t * i_ctx_p)406593dc095SDavid du Colombier zfillCIDMap(i_ctx_t *i_ctx_p)
407593dc095SDavid du Colombier {
408593dc095SDavid du Colombier     os_ptr op = osp;
409593dc095SDavid du Colombier     ref *Decoding = op - 4, *TT_cmap = op - 3, *SubstNWP = op - 2,
410593dc095SDavid du Colombier         *GDBytes = op - 1, *CIDMap = op;
411593dc095SDavid du Colombier     int code;
412593dc095SDavid du Colombier 
413593dc095SDavid du Colombier     check_type(*Decoding, t_dictionary);
414593dc095SDavid du Colombier     check_type(*TT_cmap, t_array);
415593dc095SDavid du Colombier     check_type(*SubstNWP, t_array);
416593dc095SDavid du Colombier     check_type(*GDBytes, t_integer);
417593dc095SDavid du Colombier     check_type(*CIDMap, t_array);
418593dc095SDavid du Colombier     code = cid_fill_CIDMap(imemory, Decoding, TT_cmap, SubstNWP, GDBytes->value.intval, CIDMap);
419593dc095SDavid du Colombier     pop(5);
420593dc095SDavid du Colombier     return code;
421593dc095SDavid du Colombier }
422593dc095SDavid du Colombier 
4233ff48bf5SDavid du Colombier /* ------ Initialization procedure ------ */
4243ff48bf5SDavid du Colombier 
4253ff48bf5SDavid du Colombier const op_def zfcid1_op_defs[] =
4263ff48bf5SDavid du Colombier {
4273ff48bf5SDavid du Colombier     {"2.buildfont10", zbuildfont10},
4283ff48bf5SDavid du Colombier     {"2.buildfont11", zbuildfont11},
4293ff48bf5SDavid du Colombier     {"2.type11mapcid", ztype11mapcid},
430593dc095SDavid du Colombier     {"2.fillCIDMap", zfillCIDMap},
4313ff48bf5SDavid du Colombier     op_def_end(0)
4323ff48bf5SDavid du Colombier };
433