xref: /plan9/sys/src/cmd/gs/src/gsfcid.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
13ff48bf5SDavid du Colombier /* Copyright (C) 2000 Aladdin Enterprises.  All rights reserved.
23ff48bf5SDavid du Colombier 
3*593dc095SDavid du Colombier   This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier   implied.
53ff48bf5SDavid du Colombier 
6*593dc095SDavid du Colombier   This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier   modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier   of the license contained in the file LICENSE in this distribution.
93ff48bf5SDavid du Colombier 
10*593dc095SDavid du Colombier   For more information about licensing, please refer to
11*593dc095SDavid du Colombier   http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier   commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
153ff48bf5SDavid du Colombier */
163ff48bf5SDavid du Colombier 
17*593dc095SDavid du Colombier /* $Id: gsfcid.c,v 1.14 2005/01/13 16:58:07 igor Exp $ */
183ff48bf5SDavid du Colombier /* Support for CID-keyed fonts */
193ff48bf5SDavid du Colombier #include "memory_.h"
203ff48bf5SDavid du Colombier #include "gx.h"
213ff48bf5SDavid du Colombier #include "gsmatrix.h"		/* for gsfont.h */
223ff48bf5SDavid du Colombier #include "gsstruct.h"
233ff48bf5SDavid du Colombier #include "gxfcid.h"
24*593dc095SDavid du Colombier #include "gserrors.h"
253ff48bf5SDavid du Colombier 
263ff48bf5SDavid du Colombier /* CIDSystemInfo structure descriptors */
273ff48bf5SDavid du Colombier public_st_cid_system_info();
283ff48bf5SDavid du Colombier public_st_cid_system_info_element();
293ff48bf5SDavid du Colombier 
303ff48bf5SDavid du Colombier /* CID-keyed font structure descriptors */
313ff48bf5SDavid du Colombier public_st_gs_font_cid_data();
323ff48bf5SDavid du Colombier public_st_gs_font_cid0();
333ff48bf5SDavid du Colombier private
ENUM_PTRS_WITH(font_cid0_enum_ptrs,gs_font_cid0 * pfcid0)343ff48bf5SDavid du Colombier ENUM_PTRS_WITH(font_cid0_enum_ptrs, gs_font_cid0 *pfcid0)
353ff48bf5SDavid du Colombier {
363ff48bf5SDavid du Colombier     index -= 2;
373ff48bf5SDavid du Colombier     if (index < st_gs_font_cid_data_num_ptrs)
383ff48bf5SDavid du Colombier 	return ENUM_USING(st_gs_font_cid_data, &pfcid0->cidata.common,
393ff48bf5SDavid du Colombier 			  sizeof(gs_font_cid_data), index);
403ff48bf5SDavid du Colombier     ENUM_PREFIX(st_gs_font_base, st_gs_font_cid_data_num_ptrs);
413ff48bf5SDavid du Colombier }
423ff48bf5SDavid du Colombier ENUM_PTR(0, gs_font_cid0, cidata.FDArray);
433ff48bf5SDavid du Colombier ENUM_PTR(1, gs_font_cid0, cidata.proc_data);
443ff48bf5SDavid du Colombier ENUM_PTRS_END
453ff48bf5SDavid du Colombier private
463ff48bf5SDavid du Colombier RELOC_PTRS_WITH(font_cid0_reloc_ptrs, gs_font_cid0 *pfcid0);
473ff48bf5SDavid du Colombier     RELOC_PREFIX(st_gs_font_base);
483ff48bf5SDavid du Colombier     RELOC_USING(st_gs_font_cid_data, &pfcid0->cidata.common,
493ff48bf5SDavid du Colombier 		sizeof(st_gs_font_cid_data));
503ff48bf5SDavid du Colombier     RELOC_VAR(pfcid0->cidata.FDArray);
513ff48bf5SDavid du Colombier     RELOC_VAR(pfcid0->cidata.proc_data);
523ff48bf5SDavid du Colombier RELOC_PTRS_END
533ff48bf5SDavid du Colombier public_st_gs_font_cid1();
543ff48bf5SDavid du Colombier private
ENUM_PTRS_WITH(font_cid1_enum_ptrs,gs_font_cid1 * pfcid1)553ff48bf5SDavid du Colombier ENUM_PTRS_WITH(font_cid1_enum_ptrs, gs_font_cid1 *pfcid1)
563ff48bf5SDavid du Colombier {
573ff48bf5SDavid du Colombier     if (index < st_cid_system_info_num_ptrs)
583ff48bf5SDavid du Colombier 	return ENUM_USING(st_cid_system_info, &pfcid1->cidata.CIDSystemInfo,
593ff48bf5SDavid du Colombier 			  sizeof(st_cid_system_info), index);
603ff48bf5SDavid du Colombier     ENUM_PREFIX(st_gs_font_base, st_cid_system_info_num_ptrs);
613ff48bf5SDavid du Colombier }
623ff48bf5SDavid du Colombier ENUM_PTRS_END
633ff48bf5SDavid du Colombier private
643ff48bf5SDavid du Colombier RELOC_PTRS_WITH(font_cid1_reloc_ptrs, gs_font_cid1 *pfcid1);
653ff48bf5SDavid du Colombier     RELOC_PREFIX(st_gs_font_base);
663ff48bf5SDavid du Colombier     RELOC_USING(st_cid_system_info, &pfcid1->cidata.CIDSystemInfo,
673ff48bf5SDavid du Colombier 		sizeof(st_cid_system_info));
683ff48bf5SDavid du Colombier RELOC_PTRS_END
693ff48bf5SDavid du Colombier public_st_gs_font_cid2();
703ff48bf5SDavid du Colombier private
ENUM_PTRS_WITH(font_cid2_enum_ptrs,gs_font_cid2 * pfcid2)713ff48bf5SDavid du Colombier ENUM_PTRS_WITH(font_cid2_enum_ptrs, gs_font_cid2 *pfcid2)
723ff48bf5SDavid du Colombier {
733ff48bf5SDavid du Colombier     if (index < st_gs_font_cid_data_num_ptrs)
743ff48bf5SDavid du Colombier 	return ENUM_USING(st_gs_font_cid_data, &pfcid2->cidata.common,
753ff48bf5SDavid du Colombier 			  sizeof(gs_font_cid_data), index);
763ff48bf5SDavid du Colombier     ENUM_PREFIX(st_gs_font_type42, st_gs_font_cid_data_num_ptrs);
773ff48bf5SDavid du Colombier }
783ff48bf5SDavid du Colombier ENUM_PTRS_END
793ff48bf5SDavid du Colombier private
803ff48bf5SDavid du Colombier RELOC_PTRS_WITH(font_cid2_reloc_ptrs, gs_font_cid2 *pfcid2);
813ff48bf5SDavid du Colombier     RELOC_PREFIX(st_gs_font_type42);
823ff48bf5SDavid du Colombier     RELOC_USING(st_gs_font_cid_data, &pfcid2->cidata.common,
833ff48bf5SDavid du Colombier 		sizeof(st_gs_font_cid_data));
843ff48bf5SDavid du Colombier RELOC_PTRS_END
853ff48bf5SDavid du Colombier 
86*593dc095SDavid du Colombier /* GC descriptor for allocating FDArray for CIDFontType 0 fonts. */
87*593dc095SDavid du Colombier gs_private_st_ptr(st_gs_font_type1_ptr, gs_font_type1 *, "gs_font_type1 *",
88*593dc095SDavid du Colombier   font1_ptr_enum_ptrs, font1_ptr_reloc_ptrs);
89*593dc095SDavid du Colombier gs_public_st_element(st_gs_font_type1_ptr_element, gs_font_type1 *,
90*593dc095SDavid du Colombier   "gs_font_type1 *[]", font1_ptr_element_enum_ptrs,
91*593dc095SDavid du Colombier   font1_ptr_element_reloc_ptrs, st_gs_font_type1_ptr);
92*593dc095SDavid du Colombier 
933ff48bf5SDavid du Colombier /*
943ff48bf5SDavid du Colombier  * The CIDSystemInfo of a CMap may be null.  We represent this by setting
953ff48bf5SDavid du Colombier  * Registry and Ordering to empty strings, and Supplement to 0.
963ff48bf5SDavid du Colombier  */
973ff48bf5SDavid du Colombier void
cid_system_info_set_null(gs_cid_system_info_t * pcidsi)983ff48bf5SDavid du Colombier cid_system_info_set_null(gs_cid_system_info_t *pcidsi)
993ff48bf5SDavid du Colombier {
1003ff48bf5SDavid du Colombier     memset(pcidsi, 0, sizeof(*pcidsi));
1013ff48bf5SDavid du Colombier }
1023ff48bf5SDavid du Colombier bool
cid_system_info_is_null(const gs_cid_system_info_t * pcidsi)1033ff48bf5SDavid du Colombier cid_system_info_is_null(const gs_cid_system_info_t *pcidsi)
1043ff48bf5SDavid du Colombier {
1053ff48bf5SDavid du Colombier     return (pcidsi->Registry.size == 0 && pcidsi->Ordering.size == 0 &&
1063ff48bf5SDavid du Colombier 	    pcidsi->Supplement == 0);
1073ff48bf5SDavid du Colombier }
1083ff48bf5SDavid du Colombier 
1093ff48bf5SDavid du Colombier /*
1103ff48bf5SDavid du Colombier  * Get the CIDSystemInfo of a font.  If the font is not a CIDFont,
1113ff48bf5SDavid du Colombier  * return NULL.
1123ff48bf5SDavid du Colombier  */
1133ff48bf5SDavid du Colombier const gs_cid_system_info_t *
gs_font_cid_system_info(const gs_font * pfont)1143ff48bf5SDavid du Colombier gs_font_cid_system_info(const gs_font *pfont)
1153ff48bf5SDavid du Colombier {
1163ff48bf5SDavid du Colombier     switch (pfont->FontType) {
1173ff48bf5SDavid du Colombier     case ft_CID_encrypted:
1183ff48bf5SDavid du Colombier 	return &((const gs_font_cid0 *)pfont)->cidata.common.CIDSystemInfo;
1193ff48bf5SDavid du Colombier     case ft_CID_user_defined:
1203ff48bf5SDavid du Colombier 	return &((const gs_font_cid1 *)pfont)->cidata.CIDSystemInfo;
1213ff48bf5SDavid du Colombier     case ft_CID_TrueType:
1223ff48bf5SDavid du Colombier 	return &((const gs_font_cid2 *)pfont)->cidata.common.CIDSystemInfo;
1233ff48bf5SDavid du Colombier     default:
1243ff48bf5SDavid du Colombier 	return 0;
1253ff48bf5SDavid du Colombier     }
1263ff48bf5SDavid du Colombier }
1273ff48bf5SDavid du Colombier 
1283ff48bf5SDavid du Colombier /*
129*593dc095SDavid du Colombier  * Check CIDSystemInfo compatibility.
130*593dc095SDavid du Colombier  */
131*593dc095SDavid du Colombier bool
gs_is_CIDSystemInfo_compatible(const gs_cid_system_info_t * info0,const gs_cid_system_info_t * info1)132*593dc095SDavid du Colombier gs_is_CIDSystemInfo_compatible(const gs_cid_system_info_t *info0,
133*593dc095SDavid du Colombier 			       const gs_cid_system_info_t *info1)
134*593dc095SDavid du Colombier {
135*593dc095SDavid du Colombier     if (info0 == NULL || info1 == NULL)
136*593dc095SDavid du Colombier 	return false;
137*593dc095SDavid du Colombier     if (info0->Registry.size != info1->Registry.size)
138*593dc095SDavid du Colombier 	return false;
139*593dc095SDavid du Colombier     if (info0->Ordering.size !=	info1->Ordering.size)
140*593dc095SDavid du Colombier 	return false;
141*593dc095SDavid du Colombier     if (memcmp(info0->Registry.data, info1->Registry.data,
142*593dc095SDavid du Colombier 	       info0->Registry.size))
143*593dc095SDavid du Colombier 	return false;
144*593dc095SDavid du Colombier     if (memcmp(info0->Ordering.data, info1->Ordering.data,
145*593dc095SDavid du Colombier 	       info0->Ordering.size))
146*593dc095SDavid du Colombier 	return false;
147*593dc095SDavid du Colombier     return true;
148*593dc095SDavid du Colombier }
149*593dc095SDavid du Colombier 
150*593dc095SDavid du Colombier /*
1513ff48bf5SDavid du Colombier  * Provide a default enumerate_glyph procedure for CIDFontType 0 fonts.
1523ff48bf5SDavid du Colombier  * Built for simplicity, not for speed.
1533ff48bf5SDavid du Colombier  */
1543ff48bf5SDavid du Colombier font_proc_enumerate_glyph(gs_font_cid0_enumerate_glyph); /* check prototype */
1553ff48bf5SDavid du Colombier int
gs_font_cid0_enumerate_glyph(gs_font * font,int * pindex,gs_glyph_space_t ignore_glyph_space,gs_glyph * pglyph)1563ff48bf5SDavid du Colombier gs_font_cid0_enumerate_glyph(gs_font *font, int *pindex,
1573ff48bf5SDavid du Colombier 			     gs_glyph_space_t ignore_glyph_space,
1583ff48bf5SDavid du Colombier 			     gs_glyph *pglyph)
1593ff48bf5SDavid du Colombier {
1603ff48bf5SDavid du Colombier     gs_font_cid0 *const pfont = (gs_font_cid0 *)font;
1613ff48bf5SDavid du Colombier 
1623ff48bf5SDavid du Colombier     while (*pindex < pfont->cidata.common.CIDCount) {
163*593dc095SDavid du Colombier 	gs_glyph_data_t gdata;
1643ff48bf5SDavid du Colombier 	int fidx;
1653ff48bf5SDavid du Colombier 	gs_glyph glyph = (gs_glyph)(gs_min_cid_glyph + (*pindex)++);
166*593dc095SDavid du Colombier 	int code;
1673ff48bf5SDavid du Colombier 
168*593dc095SDavid du Colombier 	gdata.memory = pfont->memory;
169*593dc095SDavid du Colombier 	code = pfont->cidata.glyph_data((gs_font_base *)pfont, glyph,
170*593dc095SDavid du Colombier 					    &gdata, &fidx);
171*593dc095SDavid du Colombier 	if (code < 0 || gdata.bits.size == 0)
1723ff48bf5SDavid du Colombier 	    continue;
1733ff48bf5SDavid du Colombier 	*pglyph = glyph;
174*593dc095SDavid du Colombier 	gs_glyph_data_free(&gdata, "gs_font_cid0_enumerate_glyphs");
1753ff48bf5SDavid du Colombier 	return 0;
1763ff48bf5SDavid du Colombier     }
1773ff48bf5SDavid du Colombier     *pindex = 0;
1783ff48bf5SDavid du Colombier     return 0;
1793ff48bf5SDavid du Colombier }
180*593dc095SDavid du Colombier 
181*593dc095SDavid du Colombier /* Return the font from the FDArray at the given index */
182*593dc095SDavid du Colombier const gs_font *
gs_cid0_indexed_font(const gs_font * font,int fidx)183*593dc095SDavid du Colombier gs_cid0_indexed_font(const gs_font *font, int fidx)
184*593dc095SDavid du Colombier {
185*593dc095SDavid du Colombier     gs_font_cid0 *const pfont = (gs_font_cid0 *)font;
186*593dc095SDavid du Colombier 
187*593dc095SDavid du Colombier     if (font->FontType != ft_CID_encrypted) {
188*593dc095SDavid du Colombier 	eprintf1("Unexpected font type: %d\n", font->FontType);
189*593dc095SDavid du Colombier         return 0;
190*593dc095SDavid du Colombier     }
191*593dc095SDavid du Colombier     return (const gs_font*) (pfont->cidata.FDArray[fidx]);
192*593dc095SDavid du Colombier }
193*593dc095SDavid du Colombier 
194*593dc095SDavid du Colombier /* Check whether a CID font has a Type 2 subfont. */
195*593dc095SDavid du Colombier bool
gs_cid0_has_type2(const gs_font * font)196*593dc095SDavid du Colombier gs_cid0_has_type2(const gs_font *font)
197*593dc095SDavid du Colombier {
198*593dc095SDavid du Colombier     gs_font_cid0 *const pfont = (gs_font_cid0 *)font;
199*593dc095SDavid du Colombier     int i;
200*593dc095SDavid du Colombier 
201*593dc095SDavid du Colombier     if (font->FontType != ft_CID_encrypted) {
202*593dc095SDavid du Colombier 	eprintf1("Unexpected font type: %d\n", font->FontType);
203*593dc095SDavid du Colombier         return false;
204*593dc095SDavid du Colombier     }
205*593dc095SDavid du Colombier     for (i = 0; i < pfont->cidata.FDArray_size; i++)
206*593dc095SDavid du Colombier 	if (((const gs_font *)pfont->cidata.FDArray[i])->FontType == ft_encrypted2)
207*593dc095SDavid du Colombier 	    return true;
208*593dc095SDavid du Colombier     return false;
209*593dc095SDavid du Colombier }
210