/* ** Write a BYTE as a hexadecimal value as part of the sfnts array. */ void sfnts_pputBYTE(TTStreamWriter& stream, BYTE n) { static const char hexdigits[]="0123456789ABCDEF"; if (!in_string) { stream.put_char('<'); string_len=0; line_len++; in_string=TRUE; } stream.put_char( hexdigits[ n / 16 ] ); stream.put_char( hexdigits[ n % 16 ] ); string_len++; line_len+=2; if (line_len > 70) { stream.put_char('\n'); line_len=0; } } /* end of sfnts_pputBYTE() */
/* ** This is called whenever it is ** necessary to end a string in the sfnts array. ** ** (The array must be broken into strings which are ** no longer than 64K characters.) */ void sfnts_end_string(TTStreamWriter& stream) { if (in_string) { string_len=0; /* fool sfnts_pputBYTE() */ #ifdef DEBUG_TRUETYPE_INLINE puts("\n% dummy byte:\n"); #endif sfnts_pputBYTE(stream, 0); /* extra byte for pre-2013 compatibility */ stream.put_char('>'); line_len++; } in_string=FALSE; } /* end of sfnts_end_string() */
/* ** This routine is used to break the character ** procedure up into a number of smaller ** procedures. This is necessary so as not to ** overflow the stack on certain level 1 interpreters. ** ** Prepare to push another item onto the stack, ** starting a new proceedure if necessary. ** ** Not all the stack depth calculations in this routine ** are perfectly accurate, but they do the job. */ void GlyphToType3::stack(TTStreamWriter& stream, int new_elem) { if ( !pdf_mode && num_pts > 25 ) /* Only do something of we will */ { /* have a log of points. */ if (stack_depth == 0) { stream.put_char('{'); stack_depth=1; } stack_depth += new_elem; /* Account for what we propose to add */ if (stack_depth > 100) { stream.puts("}_e{"); stack_depth = 3 + new_elem; /* A rough estimate */ } } } /* end of stack() */
/*---------------------------------------------------------------- ** Emmit the code to finish up the dictionary and turn ** it into a font. ----------------------------------------------------------------*/ void ttfont_trailer(TTStreamWriter& stream, struct TTFONT *font) { /* If we are generating a type 3 font, we need to provide */ /* a BuildGlyph and BuildChar proceedures. */ if (font->target_type == PS_TYPE_3 || font->target_type == PS_TYPE_42_3_HYBRID) { stream.put_char('\n'); stream.putline("/BuildGlyph"); stream.putline(" {exch begin"); /* start font dictionary */ stream.putline(" CharStrings exch"); stream.putline(" 2 copy known not{pop /.notdef}if"); stream.putline(" true 3 1 roll get exec"); stream.putline(" end}_d"); stream.put_char('\n'); /* This proceedure is for compatiblity with */ /* level 1 interpreters. */ stream.putline("/BuildChar {"); stream.putline(" 1 index /Encoding get exch get"); stream.putline(" 1 index /BuildGlyph get exec"); stream.putline("}_d"); stream.put_char('\n'); } /* If we are generating a type 42 font, we need to check to see */ /* if this PostScript interpreter understands type 42 fonts. If */ /* it doesn't, we will hope that the Apple TrueType rasterizer */ /* has been loaded and we will adjust the font accordingly. */ /* I found out how to do this by examining a TrueType font */ /* generated by a Macintosh. That is where the TrueType interpreter */ /* setup instructions and part of BuildGlyph came from. */ if (font->target_type == PS_TYPE_42 || font->target_type == PS_TYPE_42_3_HYBRID) { stream.put_char('\n'); /* If we have no "resourcestatus" command, or FontType 42 */ /* is unknown, leave "true" on the stack. */ stream.putline("systemdict/resourcestatus known"); stream.putline(" {42 /FontType resourcestatus"); stream.putline(" {pop pop false}{true}ifelse}"); stream.putline(" {true}ifelse"); /* If true, execute code to produce an error message if */ /* we can't find Apple's TrueDict in VM. */ stream.putline("{/TrueDict where{pop}{(%%[ Error: no TrueType rasterizer ]%%)= flush}ifelse"); /* Since we are expected to use Apple's TrueDict TrueType */ /* reasterizer, change the font type to 3. */ stream.putline("/FontType 3 def"); /* Define a string to hold the state of the Apple */ /* TrueType interpreter. */ stream.putline(" /TrueState 271 string def"); /* It looks like we get information about the resolution */ /* of the printer and store it in the TrueState string. */ stream.putline(" TrueDict begin sfnts save"); stream.putline(" 72 0 matrix defaultmatrix dtransform dup"); stream.putline(" mul exch dup mul add sqrt cvi 0 72 matrix"); stream.putline(" defaultmatrix dtransform dup mul exch dup"); stream.putline(" mul add sqrt cvi 3 -1 roll restore"); stream.putline(" TrueState initer end"); /* This BuildGlyph procedure will look the name up in the */ /* CharStrings array, and then check to see if what it gets */ /* is a procedure. If it is, it executes it, otherwise, it */ /* lets the TrueType rasterizer loose on it. */ /* When this proceedure is executed the stack contains */ /* the font dictionary and the character name. We */ /* exchange arguments and move the dictionary to the */ /* dictionary stack. */ stream.putline(" /BuildGlyph{exch begin"); /* stack: charname */ /* Put two copies of CharStrings on the stack and consume */ /* one testing to see if the charname is defined in it, */ /* leave the answer on the stack. */ stream.putline(" CharStrings dup 2 index known"); /* stack: charname CharStrings bool */ /* Exchange the CharStrings dictionary and the charname, */ /* but if the answer was false, replace the character name */ /* with ".notdef". */ stream.putline(" {exch}{exch pop /.notdef}ifelse"); /* stack: CharStrings charname */ /* Get the value from the CharStrings dictionary and see */ /* if it is executable. */ stream.putline(" get dup xcheck"); /* stack: CharStrings_entry */ /* If is a proceedure. Execute according to RBIIp 277-278. */ stream.putline(" {currentdict systemdict begin begin exec end end}"); /* Is a TrueType character index, let the rasterizer at it. */ stream.putline(" {TrueDict begin /bander load cvlit exch TrueState render end}"); stream.putline(" ifelse"); /* Pop the font's dictionary off the stack. */ stream.putline(" end}bind def"); /* This is the level 1 compatibility BuildChar procedure. */ /* See RBIIp 281. */ stream.putline(" /BuildChar{"); stream.putline(" 1 index /Encoding get exch get"); stream.putline(" 1 index /BuildGlyph get exec"); stream.putline(" }bind def"); /* Here we close the condition which is true */ /* if the printer has no built-in TrueType */ /* rasterizer. */ stream.putline("}if"); stream.put_char('\n'); } /* end of if Type 42 not understood. */ stream.putline("FontName currentdict end definefont pop"); /* stream.putline("%%EOF"); */ } /* end of ttfont_trailer() */