1 /************************************************************************/
2 /*									*/
3 /*  Type 42 font utility functions. See:				*/
4 /*  http://partners.adobe.com/public/developer/en/font/5012.Type42_Spec.pdf */
5 /*									*/
6 /************************************************************************/
7 
8 #   include	<stdio.h>
9 #   include	<string.h>
10 
11 #   include	<sioHex.h>
12 #   include	<sioEndian.h>
13 #   include	<utilMemoryBuffer.h>
14 #   include	"psTtf.h"
15 #   include	"psReadWriteFontInfo.h"
16 #   include	<utilIndexMapping.h>
17 #   include	<appDebugon.h>
18 
19 #   include	"psTtfIntern.h"
20 
21 /************************************************************************/
22 /*									*/
23 /*  Write the CharStrings dictonary.					*/
24 /*									*/
25 /*  It attaches names to the glyphs enumerated in the 'loca' table.	*/
26 /*									*/
27 /************************************************************************/
28 
utilTtfWriteCharStrings(SimpleOutputStream * sos,const AfmFontInfo * afi)29 static void utilTtfWriteCharStrings(	SimpleOutputStream *	sos,
30 					const AfmFontInfo *	afi )
31     {
32     int				g;
33 
34     sioOutPrintf( sos, "/CharStrings %d dict dup begin\n",
35 						    afi->afiMetricCount );
36 
37     for ( g= 0; g < afi->afiMetricCount; g++ )
38 	{
39 	const char *	name;
40 
41 	name= psFontInfoGetGlyphName( afi, g );
42 	if  ( ! name || ! name[0] )
43 	    { continue;	}
44 
45 	sioOutPrintf( sos, "  /%s %d def\n", name, g );
46 	}
47 
48     sioOutPrintf( sos, "end readonly def\n" );
49 
50     return;
51     }
52 
53 /************************************************************************/
54 /*									*/
55 /*  Write a selection of the true type file to the sfnts dictionary	*/
56 /*									*/
57 /*  1)  List of tables that might be used by the PostScript engine.	*/
58 /*	See paragraph 4.7 on p 12 of the T42 spec. [Techmote #5012].	*/
59 /*  2)  Determine new file offsets for the tables.			*/
60 /*									*/
61 /************************************************************************/
62 
utilTtfWriteTableByteArray(SimpleOutputStream * sos,long filePos,const char * tag,const unsigned char * bytes,unsigned long count,int pad)63 static long utilTtfWriteTableByteArray(	SimpleOutputStream *	sos,
64 					long			filePos,
65 					const char *		tag,
66 					const unsigned char *	bytes,
67 					unsigned long		count,
68 					int			pad )
69     {
70     SimpleOutputStream *	sosHex= (SimpleOutputStream *)0;
71 
72     const int			wide= 72;
73     const int			lastNL= 0;
74 
75     sioOutPrintf( sos, "%% %s %ld bytes @%lu\n", tag, count, filePos );
76 
77     sioOutPrintf( sos, "<\n" );
78     sosHex= sioOutHexOpenFolded( sos, wide, lastNL );
79     if  ( ! sosHex )
80 	{ XDEB(sosHex); filePos= -1; goto ready;	}
81 
82     if  ( sioOutWriteBytes( sosHex, bytes, count ) != count )
83 	{ LDEB(count); filePos= -1; goto ready;	}
84 
85     if  ( pad > 1 )
86 	{
87 	while( count % pad )
88 	    {
89 	    if  ( sioOutPutByte( '\0', sosHex ) < 0 )
90 		{ LDEB(count); filePos= -1; goto ready;	}
91 
92 	    count++;
93 	    }
94 	}
95 
96     filePos += count;
97 
98     if  ( sioOutPutByte( '\0', sosHex ) < 0 )
99 	{ filePos= -1; goto ready;	}
100     sioOutClose( sosHex ); sosHex= (SimpleOutputStream *)0;
101     sioOutPrintf( sos, ">\n" );
102 
103   ready:
104 
105     if  ( sosHex )
106 	{ sioOutClose( sosHex );	}
107 
108     return filePos;
109     }
110 
utilTtfStepTableByteArray(long filePos,unsigned long count,int pad)111 static long utilTtfStepTableByteArray(	long			filePos,
112 					unsigned long		count,
113 					int			pad )
114     {
115     if  ( pad > 1 )
116 	{
117 	while( count % pad )
118 	    { count++; }
119 	}
120 
121     filePos += count;
122     return filePos;
123     }
124 
psTtfLocaChunk(int * pPad,int * pGlyphIdx,const TrueTypeFont * ttf,const TrueTypeTableEntry * ttte,int upto,const int glyphIdx)125 static long psTtfLocaChunk(	int *				pPad,
126 				int *				pGlyphIdx,
127 				const TrueTypeFont *		ttf,
128 				const TrueTypeTableEntry *	ttte,
129 				int				upto,
130 				const int			glyphIdx )
131     {
132     const TrueTypeHeadTable *	ttht= &(ttf->ttfHeadTable);
133     int				glyphCount= ttf->ttfLocationCount;
134     int				glyphs;
135     int				pad;
136 
137     switch( ttht->tthtIndexToLocFormat )
138 	{
139 	case 0:
140 	    pad= 2;
141 	    break;
142 	case 1:
143 	    pad= 4;
144 	    break;
145 	default:
146 	    LDEB(ttht->tthtIndexToLocFormat); return -1;
147 	}
148 
149     glyphs= glyphCount- glyphIdx;
150     if  ( upto > pad* glyphCount )
151 	{ upto=  pad* glyphCount;	}
152 
153     upto= pad* ( upto / pad );
154     glyphs= upto/ pad;
155     if  ( glyphs == 0 )
156 	{ LDEB(glyphs); *pPad= 4; return upto+ 4; }
157 
158     if  ( upto == ttte->ttteMemoryBuffer.mbSize )
159 	{ pad= 4;	}
160 
161     *pPad= pad;
162     *pGlyphIdx= glyphIdx+ glyphs;
163     return upto;
164     }
165 
psTtfHmtxChunk(int * pPad,int * pGlyphIdx,const TrueTypeFont * ttf,const TrueTypeTableEntry * ttte,int upto,const int glyphIdx)166 static long psTtfHmtxChunk(	int *				pPad,
167 				int *				pGlyphIdx,
168 				const TrueTypeFont *		ttf,
169 				const TrueTypeTableEntry *	ttte,
170 				int				upto,
171 				const int			glyphIdx )
172     {
173     const TrueTypeHheaTable *	hhea= &(ttf->ttfHheaTable);
174     int				partialCount;
175     int				fullCount;
176     int				glyphs;
177     int				pad;
178 
179     fullCount= hhea->hheaMetricCount;
180     partialCount= ( ttte->ttteMemoryBuffer.mbSize- 4 * hhea->hheaMetricCount )/ 2;
181 
182     if  ( glyphIdx < fullCount )
183 	{
184 	pad= 4;
185 	glyphs= fullCount- glyphIdx;
186 
187 	/*  Issue full metrics separately */
188 	if  ( upto > pad* fullCount )
189 	    { upto=  pad* fullCount;	}
190 
191 	/*  Issue full metrics separately */
192 	upto= pad* ( upto / pad );
193 	glyphs= upto/ pad;
194 
195 	*pPad= pad;
196 	*pGlyphIdx= glyphIdx+ glyphs;
197 	return upto;
198 	}
199 
200     pad= 2;
201     glyphs= fullCount+ partialCount- glyphIdx;
202     if  ( glyphs == 0 )
203 	{ LDEB(glyphs); *pPad= 4; return upto+ 4; }
204 
205     if  ( upto > 4* fullCount+ 2* partialCount )
206 	{ upto=  4* fullCount+ 2* partialCount;	}
207 
208     upto= pad* ( upto / pad );
209     glyphs= upto/ pad;
210 
211     if  ( upto == ttte->ttteMemoryBuffer.mbSize )
212 	{ pad= 4;	}
213 
214     *pPad= pad;
215     *pGlyphIdx= glyphIdx+ glyphs;
216     return upto;
217     }
218 
psTtfVmtxChunk(int * pPad,int * pGlyphIdx,const TrueTypeFont * ttf,const TrueTypeTableEntry * ttte,int upto,const int glyphIdx)219 static long psTtfVmtxChunk(	int *				pPad,
220 				int *				pGlyphIdx,
221 				const TrueTypeFont *		ttf,
222 				const TrueTypeTableEntry *	ttte,
223 				int				upto,
224 				const int			glyphIdx )
225     {
226     const TrueTypeVheaTable *	vhea= &(ttf->ttfVheaTable);
227     int				partialCount;
228     int				fullCount;
229     int				glyphs;
230     int				pad;
231 
232     fullCount= vhea->vheaMetricCount;
233     partialCount= ( ttte->ttteMemoryBuffer.mbSize- 4 * vhea->vheaMetricCount )/ 2;
234 
235     if  ( glyphIdx < fullCount )
236 	{
237 	pad= 4;
238 	glyphs= fullCount- glyphIdx;
239 
240 	/*  Issue full metrics separately */
241 	if  ( upto > pad* fullCount )
242 	    { upto=  pad* fullCount;	}
243 
244 	/*  Issue full metrics separately */
245 	upto= pad* ( upto / pad );
246 	glyphs= upto/ pad;
247 
248 	*pPad= pad;
249 	*pGlyphIdx= glyphIdx+ glyphs;
250 	return upto;
251 	}
252 
253     pad= 2;
254     glyphs= fullCount+ partialCount- glyphIdx;
255     if  ( glyphs == 0 )
256 	{ LDEB(glyphs); *pPad= 4; return upto+ 4; }
257 
258     if  ( upto > 4* fullCount+ 2* partialCount )
259 	{ upto=  4* fullCount+ 2* partialCount;	}
260 
261     upto= pad* ( upto / pad );
262     glyphs= upto/ pad;
263 
264     if  ( upto == ttte->ttteMemoryBuffer.mbSize )
265 	{ pad= 4;	}
266 
267     *pPad= pad;
268     *pGlyphIdx= glyphIdx+ glyphs;
269     return upto;
270     }
271 
psTtfGlyphChunk(int * pPad,int * pGlyphIdx,const TrueTypeFont * ttf,const TrueTypeTableEntry * ttte,int upto,const int glyphIdx)272 static long psTtfGlyphChunk(	int *				pPad,
273 				int *				pGlyphIdx,
274 				const TrueTypeFont *		ttf,
275 				const TrueTypeTableEntry *	ttte,
276 				int				upto,
277 				const int			glyphIdx )
278     {
279     int		l, r, m;
280     int		pad= 2;
281 
282     l= glyphIdx; r= ttf->ttfLocationCount; m= ( l+ r )/ 2;
283 
284     while ( l < m )
285 	{
286 	if  ( ttf->ttfLocations[m] > upto )
287 	    { r= m;	}
288 	else{ l= m; }
289 
290 	m= ( l+ r )/ 2;
291 	}
292 
293     if  ( m == ttf->ttfLocationCount- 1 )
294 	{ upto= ttte->ttteMemoryBuffer.mbSize; pad= 4;	}
295     else{ upto= ttf->ttfLocations[m]; pad= 2;	}
296 
297     if  ( upto == ttte->ttteMemoryBuffer.mbSize )
298 	{ pad= 4;	}
299 
300     *pPad= pad; *pGlyphIdx= m;
301     return upto;
302     }
303 
utilTtfWriteT42Sfnts(SimpleOutputStream * sos,const char * debFontName,const TrueTypeFont * ttf)304 static int utilTtfWriteT42Sfnts(	SimpleOutputStream *	sos,
305 					const char *		debFontName,
306 					const TrueTypeFont *	ttf )
307     {
308     int				rval= 0;
309     int				tab;
310     TrueTypeTableEntry *	ttte= ttf->ttfTables;
311     long			filePos;
312     int				tableCount;
313     SimpleOutputStream *	sosHex= (SimpleOutputStream *)0;
314 
315     const int			wide= 72;
316     const int			lastNL= 0;
317 
318     /*  1  */
319     static const char * const	sfntfTags[]=
320 	{
321 	"head", "hhea", "hmtx", "loca",
322 	"prep", "fpgm", "vhea", "glyf",
323 	"cvt ", "maxp", "vmtx",
324 	};
325 
326     /*  2  */
327     tableCount= 0;
328     filePos= 12;
329     ttte= ttf->ttfTables;
330     for ( tab= 0; tab < ttf->ttfTableCount; ttte++, tab++ )
331 	{
332 	int	i;
333 
334 	for ( i= 0; i < sizeof(sfntfTags)/sizeof(char *); i++ )
335 	    {
336 	    if  ( ! strcmp( ttte->ttteTag, sfntfTags[i] ) )
337 		{ break;	}
338 	    }
339 
340 	if  ( i >= sizeof(sfntfTags)/sizeof(char *) )
341 	    { ttte->ttteSaveOffset= 0;	}
342 	else{
343 	    ttte->ttteSaveOffset= filePos;
344 	    tableCount++;
345 
346 	    if  ( ttte->ttteMemoryBuffer.mbSize > 65528 )
347 		{
348 		long	pos= 0;
349 		int	glyphIdx= 0;
350 		long	upto= 65534;
351 
352 		if  ( ! strcmp( ttte->ttteTag, "glyf" ) )
353 		    {
354 		    while( pos < ttte->ttteMemoryBuffer.mbSize )
355 			{
356 			int		pad= 2;
357 
358 			upto= psTtfGlyphChunk( &pad, &glyphIdx,
359 						ttf, ttte, upto, glyphIdx );
360 
361 			filePos= utilTtfStepTableByteArray( filePos,
362 							    upto- pos, pad );
363 			pos= upto;
364 			upto += 65528;
365 			}
366 
367 		    continue;
368 		    }
369 
370 		if  ( ! strcmp( ttte->ttteTag, "hmtx" ) )
371 		    {
372 		    while( pos < ttte->ttteMemoryBuffer.mbSize )
373 			{
374 			int		pad= 2;
375 
376 			upto= psTtfHmtxChunk( &pad, &glyphIdx,
377 						ttf, ttte, upto, glyphIdx );
378 
379 			filePos= utilTtfStepTableByteArray( filePos,
380 							    upto- pos, pad );
381 			pos= upto;
382 			upto += 65528;
383 			}
384 
385 		    continue;
386 		    }
387 
388 		if  ( ! strcmp( ttte->ttteTag, "vmtx" ) )
389 		    {
390 		    while( pos < ttte->ttteMemoryBuffer.mbSize )
391 			{
392 			int		pad= 2;
393 
394 			upto= psTtfVmtxChunk( &pad, &glyphIdx,
395 						ttf, ttte, upto, glyphIdx );
396 
397 			filePos= utilTtfStepTableByteArray( filePos,
398 							    upto- pos, pad );
399 			pos= upto;
400 			upto += 65528;
401 			}
402 
403 		    continue;
404 		    }
405 
406 		if  ( ! strcmp( ttte->ttteTag, "loca" ) )
407 		    {
408 		    while( pos < ttte->ttteMemoryBuffer.mbSize )
409 			{
410 			int		pad= 2;
411 
412 			upto= psTtfLocaChunk( &pad, &glyphIdx,
413 						ttf, ttte, upto, glyphIdx );
414 
415 			filePos= utilTtfStepTableByteArray( filePos,
416 							    upto- pos, pad );
417 			pos= upto;
418 			upto += 65528;
419 			}
420 
421 		    continue;
422 		    }
423 
424 		SSLDEB(debFontName,ttte->ttteTag,ttte->ttteMemoryBuffer.mbSize);
425 		rval= -1; goto ready;
426 		}
427 	    else{
428 		filePos= utilTtfStepTableByteArray( filePos,
429 							ttte->ttteMemoryBuffer.mbSize, 4 );
430 		}
431 	    }
432 	}
433 
434     ttte= ttf->ttfTables;
435     for ( tab= 0; tab < ttf->ttfTableCount; ttte++, tab++ )
436 	{
437 	if  ( ttte->ttteSaveOffset > 0 )
438 	    { ttte->ttteSaveOffset += 16* tableCount;	}
439 	}
440 
441     filePos= 0;
442 
443     sioOutPrintf( sos, "/sfnts[\n" );
444 
445     sioOutPrintf( sos, "<\n" );
446     sosHex= sioOutHexOpenFolded( sos, wide, lastNL );
447     if  ( ! sosHex )
448 	{ XDEB(sosHex); rval= -1; goto ready;	}
449 
450     sioEndianPutBeUint32( ttf->ttfVersion, sosHex ); filePos += 4;
451     sioEndianPutBeUint16( tableCount, sosHex ); filePos += 2;
452     sioEndianPutBeUint16( ttf->ttfSearchRange, sosHex ); filePos += 2;
453     sioEndianPutBeUint16( ttf->ttfEntrySelector, sosHex ); filePos += 2;
454     sioEndianPutBeUint16( ttf->ttfRangeShift, sosHex ); filePos += 2;
455 
456     ttte= ttf->ttfTables;
457     for ( tab= 0; tab < ttf->ttfTableCount; ttte++, tab++ )
458 	{
459 	int		b;
460 
461 	if  ( ttte->ttteSaveOffset == 0 )
462 	    { continue;	}
463 
464 	for ( b= 0; b < 4; b++ )
465 	    {
466 	    if  ( sioOutPutByte( ttte->ttteTag[b], sosHex ) < 0 )
467 		{ rval= -1; goto ready;	}
468 	    }
469 	filePos += 4;
470 
471 	sioEndianPutBeUint32( ttte->ttteChecksum, sosHex ); filePos += 4;
472 	sioEndianPutBeUint32( ttte->ttteSaveOffset, sosHex ); filePos += 4;
473 	sioEndianPutBeUint32( ttte->ttteMemoryBuffer.mbSize, sosHex ); filePos += 4;
474 	}
475 
476     if  ( sioOutPutByte( '\0', sosHex ) < 0 )
477 	{ rval= -1; goto ready;	}
478     sioOutClose( sosHex ); sosHex= (SimpleOutputStream *)0;
479     sioOutPrintf( sos, ">\n" );
480 
481     ttte= ttf->ttfTables;
482     for ( tab= 0; tab < ttf->ttfTableCount; ttte++, tab++ )
483 	{
484 	if  ( ttte->ttteSaveOffset == 0 )
485 	    { continue;	}
486 
487 	if  ( filePos != ttte->ttteSaveOffset )
488 	    {
489 	    SLLDEB(ttte->ttteTag,filePos,ttte->ttteSaveOffset);
490 	    rval= -1; goto ready;
491 	    }
492 
493 	if  ( ttte->ttteMemoryBuffer.mbSize > 65528 )
494 	    {
495 	    long	pos= 0;
496 	    int		glyphIdx= 0;
497 	    long	upto= 65534;
498 
499 	    if  ( ! strcmp( ttte->ttteTag, "glyf" ) )
500 		{
501 		while( pos < ttte->ttteMemoryBuffer.mbSize )
502 		    {
503 		    int		pad= 2;
504 
505 		    upto= psTtfGlyphChunk( &pad, &glyphIdx,
506 						ttf, ttte, upto, glyphIdx );
507 
508 		    filePos= utilTtfWriteTableByteArray( sos, filePos,
509 					ttte->ttteTag, ttte->ttteMemoryBuffer.mbBytes+ pos,
510 					upto- pos, pad );
511 		    if  ( filePos < 0 )
512 			{
513 			SLLDEB(ttte->ttteTag,ttte->ttteMemoryBuffer.mbSize,filePos);
514 			rval= -1; goto ready;
515 			}
516 
517 		    pos= upto;
518 		    upto += 65528;
519 		    }
520 
521 		continue;
522 		}
523 
524 	    if  ( ! strcmp( ttte->ttteTag, "hmtx" ) )
525 		{
526 		while( pos < ttte->ttteMemoryBuffer.mbSize )
527 		    {
528 		    int		pad= 2;
529 
530 		    upto= psTtfHmtxChunk( &pad, &glyphIdx,
531 						ttf, ttte, upto, glyphIdx );
532 
533 		    filePos= utilTtfWriteTableByteArray( sos, filePos,
534 					ttte->ttteTag, ttte->ttteMemoryBuffer.mbBytes+ pos,
535 					upto- pos, pad );
536 		    if  ( filePos < 0 )
537 			{
538 			SLLDEB(ttte->ttteTag,ttte->ttteMemoryBuffer.mbSize,filePos);
539 			rval= -1; goto ready;
540 			}
541 
542 		    pos= upto;
543 		    upto += 65528;
544 		    }
545 
546 		continue;
547 		}
548 
549 	    if  ( ! strcmp( ttte->ttteTag, "vmtx" ) )
550 		{
551 		while( pos < ttte->ttteMemoryBuffer.mbSize )
552 		    {
553 		    int		pad= 2;
554 
555 		    upto= psTtfVmtxChunk( &pad, &glyphIdx,
556 						ttf, ttte, upto, glyphIdx );
557 
558 		    filePos= utilTtfWriteTableByteArray( sos, filePos,
559 					ttte->ttteTag, ttte->ttteMemoryBuffer.mbBytes+ pos,
560 					upto- pos, pad );
561 		    if  ( filePos < 0 )
562 			{
563 			SLLDEB(ttte->ttteTag,ttte->ttteMemoryBuffer.mbSize,filePos);
564 			rval= -1; goto ready;
565 			}
566 
567 		    pos= upto;
568 		    upto += 65528;
569 		    }
570 
571 		continue;
572 		}
573 
574 	    if  ( ! strcmp( ttte->ttteTag, "loca" ) )
575 		{
576 		while( pos < ttte->ttteMemoryBuffer.mbSize )
577 		    {
578 		    int		pad= 2;
579 
580 		    upto= psTtfLocaChunk( &pad, &glyphIdx,
581 						ttf, ttte, upto, glyphIdx );
582 
583 		    filePos= utilTtfWriteTableByteArray( sos, filePos,
584 					ttte->ttteTag, ttte->ttteMemoryBuffer.mbBytes+ pos,
585 					upto- pos, pad );
586 		    if  ( filePos < 0 )
587 			{
588 			SLLDEB(ttte->ttteTag,ttte->ttteMemoryBuffer.mbSize,filePos);
589 			rval= -1; goto ready;
590 			}
591 
592 		    pos= upto;
593 		    upto += 65528;
594 		    }
595 
596 		continue;
597 		}
598 
599 	    SSLDEB(debFontName,ttte->ttteTag,ttte->ttteMemoryBuffer.mbSize);
600 	    rval= -1; goto ready;
601 	    }
602 	else{
603 	    filePos= utilTtfWriteTableByteArray( sos, filePos, ttte->ttteTag,
604 				    ttte->ttteMemoryBuffer.mbBytes, ttte->ttteMemoryBuffer.mbSize, 4 );
605 	    if  ( filePos < 0 )
606 		{
607 		SLLDEB(ttte->ttteTag,ttte->ttteMemoryBuffer.mbSize,filePos);
608 		rval= -1; goto ready;
609 		}
610 	    }
611 	}
612 
613     sioOutPrintf( sos, "]def\n" );
614 
615   ready:
616 
617     if  ( sosHex )
618 	{ sioOutClose( sosHex );	}
619 
620     return rval;
621     }
622 
623 /************************************************************************/
624 /*									*/
625 /*  Emit the contents of a PostScript font encoding array.		*/
626 /*									*/
627 /************************************************************************/
628 
psWriteFontEncoding(SimpleOutputStream * sos,const AfmFontInfo * afi)629 static void psWriteFontEncoding(	SimpleOutputStream *	sos,
630 					const AfmFontInfo *	afi )
631     {
632     int		glyph;
633 
634     for ( glyph= 0; glyph < afi->afiMetricCount; glyph++ )
635 	{
636 	const AfmCharMetric *	acm= afi->afiMetrics[glyph];
637 	const AfmCodeList *	acl= &(acm->acmDefaultCodeList);
638 	int			code;
639 
640 	for ( code= 0; code < acl->aclCodeCount; code++ )
641 	    {
642 	    sioOutPrintf( sos, "   dup %d /%s put\n",
643 					    acl->aclCodes[code], acm->acmN );
644 	    }
645 	}
646     }
647 
utilTtfWriteT42(SimpleOutputStream * sos,const AfmFontInfo * afi,const TrueTypeFont * ttf)648 static int utilTtfWriteT42(	SimpleOutputStream *	sos,
649 				const AfmFontInfo *	afi,
650 				const TrueTypeFont *	ttf )
651     {
652     const TrueTypeHeadTable *	ttht= &(ttf->ttfHeadTable);
653 
654     sioOutPrintf( sos, "%%!PS-TrueTypeFont-%lu-%lu\n",
655 				    ttht->tthtVersion,
656 				    ttht->tthtFontRevision );
657     sioOutPrintf( sos, "11 dict begin\n" );
658     sioOutPrintf( sos, "  /FontName /%s def\n", afi->afiFontName );
659     sioOutPrintf( sos, "  /Encoding 256 array\n" );
660     sioOutPrintf( sos, "   0 1 255 { 1 index exch /.notdef put } for\n" );
661 
662     psWriteFontEncoding( sos, afi );
663 
664     sioOutPrintf( sos, "  readonly def\n" );
665     sioOutPrintf( sos, "  /PaintType 0 def\n" );
666     sioOutPrintf( sos, "  /FontMatrix [1 0 0 1 0 0] def\n" );
667     sioOutPrintf( sos, "  /FontBBox [%d %d %d %d] def\n",
668 					afi->afiFontBBox.drX0,
669 					afi->afiFontBBox.drY0,
670 					afi->afiFontBBox.drX1,
671 					afi->afiFontBBox.drY1 );
672     sioOutPrintf( sos, "  /FontType 42 def\n" );
673 
674     psWriteFontInfoDict( sos, afi );
675 
676     utilTtfWriteT42Sfnts( sos, afi->afiFontName, ttf );
677 
678     utilTtfWriteCharStrings( sos, afi );
679 
680     sioOutPrintf( sos, "FontName currentdict end definefont pop\n" );
681 
682     return 0;
683     }
684 
psTtfWriteT42File(SimpleOutputStream * sosPf42,const TrueTypeFont * ttf)685 static int psTtfWriteT42File(	SimpleOutputStream *	sosPf42,
686 				const TrueTypeFont *	ttf )
687     {
688     int				rval= 0;
689 
690     AfmFontInfo			afi;
691 
692     psInitAfmFontInfo( &afi );
693 
694     if  ( psTtfFontInfo( &afi, ttf ) )
695 	{ LDEB(1); rval= -1; goto ready;	}
696 
697     utilTtfWriteT42( sosPf42, &afi, ttf );
698 
699   ready:
700 
701     psCleanAfmFontInfo( &afi );
702 
703     return rval;
704     }
705 
706 /************************************************************************/
707 /*									*/
708 /*  Translate Truetype font to PostScript type 42.			*/
709 /*									*/
710 /************************************************************************/
711 
psTtfToPt42(SimpleOutputStream * sosPf42,const MemoryBuffer * fontFileName,SimpleInputStream * sisTtf)712 int psTtfToPt42(		SimpleOutputStream *	sosPf42,
713 				const MemoryBuffer *	fontFileName,
714 				SimpleInputStream *	sisTtf )
715     {
716     int				rval= 0;
717     TrueTypeFont		ttf;
718 
719     psTtfInitTrueTypeFont( &ttf );
720 
721     if  ( psTtfLoadFont( &ttf, sisTtf, 0L ) )
722 	{ LDEB(1); rval= -1; goto ready;	}
723 
724     psTtfWriteT42File( sosPf42, &ttf );
725 
726   ready:
727 
728     psTtfCleanTrueTypeFont( &ttf );
729 
730     return rval;
731     }
732 
psTtcToPt42(SimpleOutputStream * sosPf42,const MemoryBuffer * fontFileName,int fontFileIndex,SimpleInputStream * sisTtf)733 int psTtcToPt42(		SimpleOutputStream *	sosPf42,
734 				const MemoryBuffer *	fontFileName,
735 				int			fontFileIndex,
736 				SimpleInputStream *	sisTtf )
737     {
738     int				rval= 0;
739     TrueTypeFont		ttf;
740 
741     psTtfInitTrueTypeFont( &ttf );
742 
743     if  ( psTtcLoadFont( &ttf, sisTtf, fontFileIndex ) )
744 	{ LDEB(1); rval= -1; goto ready;	}
745 
746     psTtfWriteT42File( sosPf42, &ttf );
747 
748   ready:
749 
750     psTtfCleanTrueTypeFont( &ttf );
751 
752     return rval;
753     }
754 
755