% Copyright (C) 2001-2020 Artifex Software, Inc. % All Rights Reserved. % % This software is provided AS-IS with no warranty, either express or % implied. % % This software is distributed under license and may not be copied, % modified or distributed except as expressly authorized under the terms % of the license contained in the file LICENSE in this distribution. % % Refer to licensing information at http://www.artifex.com or contact % Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, % CA 94945, U.S.A., +1(415)492-9861, for further information. % % Redefine Font and CIDFont categories with FAPI-handeled fonts. systemdict /.FAPIavailable known { //null .FAPIavailable } { //false } ifelse not { (%END FAPI) .skipeof } if languagelevel 2 .setlanguagelevel %==================================================================== % Redefine Font category with FAPIfontmap and CIDFont with FAPIfontmap : 15 dict begin % a temporary dictionary for local binding. /EmbedFontObjectsQuery mark /.EmbedFontObjects 0 .dicttomark def /is_device_compatible_to_FAPI % - is_device_compatible_to_FAPI { //true % removed a bogus check against EmbedFontObjectsQuery % % Temporary switch to allow override of FAPI and fallback to GS font rendering % to be removed at some date after FT integration is completed and released. % /DisableFAPI where { /DisableFAPI get not and }if % The code above assumes that only the requested parameter is rendered. % The commented-out code below may be useful for general case. % Keeping it for a while. % counttomark 2 idiv { % exch /.EmbedFontObjects eq { % counttomark 1 add 1 roll cleartomark % 0 eq exit % } if % } repeat % dup mark eq { % pop //true % } if } bind def %----------------------------- Process FAPIconfig ----------------------- % The HookDiskFonts and HookEmbeddedFonts take a simple array setting normally. % but if two or more FAPI plugins are built in, they can take a dictionary, % whose contents are the FAPI subtype string of a given plugin as the key, % and an array containing the (sub)set of font types the plugin should handle. % Any repetition of font types is ill advised since the resulting bevhaviour % will depend on the order entries are stored in the dictionary, which is % indeterminate. An attempt to use request a font scaler/renderer which cannot % deal with a given font type will result in the FAPI resorting to it's default % search for a viable plugin. % % As an example, you might want UFST to handle Truetype/Type 42 fonts, and % Freetype to handle others, thus: % /HookDiskFonts << /UFST [11 42] /FreeType [1 2 9] >> % /HookEmbeddedFonts << /UFST [11 42] /FreeType [1 2 9] >> /Config << % If we've got a FAPIConfig, run it now. systemdict /FAPIconfig known { /FAPIconfig .systemvar .runlibfile } if % Now setup defaults for any entries not set above - these defaults are correct % for FAPI/Freeetype currentdict /FontPath known not { /FontPath (/Fonts)} if % A default directory for FAPI-handled font files % path in FAPIfontmap. currentdict /CIDFontPath known not { /CIDFontPath (/CIDFonts)} if % A default directory for FAPI-handled CIDfont % files path in FAPIcidfmap. currentdict /HookDiskFonts known not { /HookDiskFonts [1 2 9 11 42] } if % FontType values for disk PS fonts to be % redirected to FAPI. currentdict /HookEmbeddedFonts known not { /HookEmbeddedFonts [1 2 9 11 42] } if % FontType values for embedded PS fonts to be % redirected to FAPI. /ServerOptions 2 dict >> def systemdict /.FAPIconfig //Config put /UFST .FAPIavailable { systemdict /UFST_SSdir known { /UFSTFONTDIR UFST_SSdir def systemdict /UFST_SSdir undef } { /UFSTROMFONTDIR (%rom%fontdata/) def UFSTROMFONTDIR (mtfonts/pcl45/mt3/plug__xi.fco) concatstrings status { pop pop pop pop /UFSTFONTDIR UFSTROMFONTDIR def } { /UFSTFONTDIR () def } ifelse } ifelse systemdict /UFST_PlugIn known not { systemdict /UFST_PlugIn UFSTFONTDIR (mtfonts/pcl45/mt3/plug__xi.fco) concatstrings put } if systemdict /FCOfontfile known not { systemdict /FCOfontfile UFSTFONTDIR (mtfonts/pclps2/mt3/pclp2_xj.fco) concatstrings put } if systemdict /FCOfontfile2 known not { systemdict /FCOfontfile2 UFSTFONTDIR (mtfonts/pcl45/mt3/wd____xh.fco) concatstrings put } if systemdict /FAPIfontmap known not { systemdict /FAPIfontmap (FCOfontmap-PCLPS2) put } if } if () systemdict /UFST_SSdir .knownget { (UFST_SSdir=) exch concatstrings concatstrings } if systemdict /UFST_PlugIn .knownget { 1 index length 0 ne { exch .filenamelistseparator concatstrings exch } if (UFST_PlugIn=) exch concatstrings concatstrings } if dup length 0 ne { //Config /ServerOptions get exch /UFST exch put } { pop } ifelse %------------------Copy the FontEmulationProcs here : ------------------- /FontEmulationProcs /ProcSet findresource { def } forall currentdict /super.complete_instance currentdict /complete_instance get put %-----------FAPI-specific methods for category redefinition : ----------- /RefinePath % /key RefinePath { exch begin //Config exch get /Path exch Path //false .file_name_combine not { exch (Can't combine paths ) print print ( and ) print = /RefinePath cvx /configurationerror signalerror } if def currentdict end } bind def /complete_instance % complete_FAPI_Font { //super.complete_instance exec dup /CIDFontName known { /CIDFontPath } { /FontPath } ifelse //RefinePath exec } bind def /IsMyRecord % -> bool { dup type /dicttype eq { dup /FAPI known } { //false } ifelse } bind def /IsActive % IsActive { pop //is_device_compatible_to_FAPI exec } bind def /FontRecordVirtualMethods //RecordVirtualMethodsStub dup length 2 add dict copy begin /IsActive //IsActive def /MakeInstance % MakeInstance { currentglobal 3 1 roll //true setglobal //FontOptions //complete_instance exec 2 copy //GetSize exec 4 3 roll setglobal } bind def currentdict end def /CIDFontRecordVirtualMethods //RecordVirtualMethodsStub dup length 3 add dict copy begin /GetCSI //TranslateCSI def /IsActive //IsActive def /MakeInstance % MakeInstance { currentglobal 3 1 roll //true setglobal //CIDFontOptions //complete_instance exec 2 copy //GetSize exec 4 3 roll setglobal } bind def currentdict end def /ReadFCOfontmap: % ReadFCOfontmap: name dict ... { /fontfile exch def { currentfile =string readline not { pop exit } if dup length 0 ne { 0 () /SubFileDecode filter dup token not { % A comment line closefile } { dup /EndFCOfontmap cvx eq { pop closefile exit } if exch dup token not { /ReadFCOfontmap: cvx /rangecheck signalerror } if exch dup token not { /StandardEncoding } { dup type /nametype ne { /ReadFCOfontmap: cvx /rangecheck signalerror } if } ifelse findencoding exch dup token not { //null } { dup type /nametype ne { /ReadFCOfontmap: cvx /rangecheck signalerror } if /Decoding findresource } ifelse exch closefile % index name enc dec|null 4 3 roll % name enc dec|null index << /Path fontfile /FontType 1 /FAPI /UFST /SubfontId counttomark 2 add -1 roll /Decoding counttomark 2 add -1 roll dup //null eq { pop pop } if /Encoding counttomark 2 add -1 roll /FontInfo << /UnderlineThickness 50 /Weight (Regular) /version (0.00) /ItalicAngle 0 /UnderlinePosition -100 /FamilyName () /Notice () /FullName () >> % although we pretend this is a Type 1, the FAPI interface currently % needs an identity FontMatrix /FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] % we need a fake CharStrings dictionary to placate certain jobs % which try to look inside it /CharStrings << /.notdef ( ) StandardEncoding { ( ) } forall >> % FontBBox will get replaced with valid numbers pulled from the rendering engine /FontBBox [-128 -128 1024 1024] cvx >> % dup { exch == = } forall } ifelse } { pop } ifelse } loop currentdict /fontfile undef } bind def %----------------------------------The Redefintion--------------------- /MappedCategoryRedefiner /ProcSet findresource /Redefine get /Redefine exch def % Redefine the /Font category : 4 dict begin /CategoryName /Font def /MapFileName systemdict /FAPIfontmap known {/FAPIfontmap .systemvar} {(FAPIfontmap)} ifelse def /VerifyMap { pop } bind def /PreprocessRecord % PreprocessRecord { //IsMyRecord exec dup { pop dup /RecordVirtualMethods //FontRecordVirtualMethods put //true } if } bind def currentdict end Redefine % Redefine the /CIDFont category : 4 dict begin /CategoryName /CIDFont def /MapFileName systemdict /FAPIcidfmap known {/FAPIcidfmap .systemvar} {(FAPIcidfmap)} ifelse def /VerifyMap { pop } bind def /PreprocessRecord % PreprocessRecord { //IsMyRecord exec dup { pop dup /RecordVirtualMethods //CIDFontRecordVirtualMethods put //true } if } bind def currentdict end Redefine %==================== A hook for buildfont* operators ==================== % The procedure .FAPIhook redirects PS fonts to FAPI on necessity. % This depends on the following conditions : % % 1. If font dictionary has /FAPI entry, it is a font listed in FAPIconfig.FontPath, % and must be build with .FAPIrebuildfont, or a copy of a font, which was % built with .FAPIrebuildfont . % % 2. If the font dictionary has /PathLoad entry, and has no /FAPI entry, % it is an installed PS font, which is described in lib/fontmap or % in GS_FONTPATH. .loadfont inserts /PathLoad entry for this case % (see gs_fonts.ps). % % Installed fonts are being loaded with GS font loader, % the they are passed to FAPI is same way as embedded fonts are. % We do so because UFST cannot read fonts, which don't % follow Type 1/42 file format strongly. % % 3. Executing .loadfont, we place /FAPI_hook_disable in the 0th % element of some procedure on the execution stack - see gs_fonts.ps . % If FAPI_hook finds /FAPI_hook_disable in there, % it knows that it is called for a disk font during % its internal definefont. % % 4. If font dictionary has no /FAPI entry, and has no /Path entry, % and if we are not in .loadfont context, it is an embedded font. % % 5. Two entries to be defined in lib/FAPIconfig to control the hooking of PS fonts : % HookDiskFonts and HookEmbeddedFonts . % They specify arrays of font types (integers) to be redirected with FAPI. % HookDiskFonts controls disk PS fonts (which fall into (2) and (3) ). % HookEmbeddedFonts controls fonts being embedded into documents. % % 7. We apply the operator .passtoFAPI for checking whether FAPI can handle a font. % If so, we insert /FAPI entry into the font dictionary and convert it % with .FAPIrebuildfont . Otherwise the font is handled with the native GS font renderer. /FAPI_hook_debug % FAPI_hook_debug - FAPIDEBUG { {exec} } { {pop} } ifelse bind def /FAPI_hook_warn % FAPI_hook_debug - QUIET { {pop} } { {exec} } ifelse bind def /FAPI_is_hook_disabled % - FAPI_is_hook_disabled { % checks whether execution stack contains packedarray started with /FAPI_hook_disable . /FAPI_hook_disable /MappedCategoryRedefiner /ProcSet findresource /execstack_lookup get exec //null ne } bind def /FAPIhook_aux % .FAPIhook { % name <> { (\nFAPIhook ) print 1 index = flush } //FAPI_hook_debug exec dup /FAPI known { { //PrintFontRef exec ( is mapped to FAPI=) print dup /FAPI get = flush } //FAPI_hook_debug exec //true .FAPIrebuildfont //ChooseDecoding exec } { dup /PathLoad known dup { { (PathLoad known for the font ) print //PrintFontRef exec (.\n) print flush} //FAPI_hook_debug exec } { pop //FAPI_is_hook_disabled exec dup { pop { (FAPIhook is in .loadfont context for the font ) print //PrintFontRef exec (.\n) print flush } //FAPI_hook_debug exec //true } if } ifelse { /HookDiskFonts } { /HookEmbeddedFonts } ifelse //Config exch get % name <> [types] dup type /dicttype eq { //false exch { 3 index //GetFontType exec //FindInArray exec { 2 index exch /FAPIPlugInReq exch put pop //true exit } { pop } ifelse } forall } { 1 index //GetFontType exec //FindInArray exec % name <> bHook } ifelse { { (Trying to render the font ) print //PrintFontRef exec ( with FAPI...\n) print flush } //FAPI_hook_debug exec .FAPIpassfont { { //PrintFontRef exec ( is being rendered with FAPI=) print dup /FAPI get = flush } //FAPI_hook_debug exec //false .FAPIrebuildfont //ChooseDecoding exec } { { (Can't render ) print //PrintFontRef exec ( with FAPI, will do with native GS renderer.\n) print flush } //FAPI_hook_warn exec } ifelse } { { (The font ) print //PrintFontRef exec ( doesn't need to render with FAPI.\n) print flush } //FAPI_hook_debug exec } ifelse % Remove the plugin request from the font dictionary dup /FAPIPlugInReq undef } ifelse } bind def /FAPIhook % .FAPIhook { //is_device_compatible_to_FAPI exec { //FAPIhook_aux exec } { { (FAPIhook is disabled for the current device.\n) print flush } //FAPI_hook_debug exec } ifelse } bind def % ------------------ Redefine .buildfont* with FAPI : ----------------------- /.buildfont1 { //.buildfont1 exec //FAPIhook exec } bind % 'odef' is below. /.buildfont2 { //.buildfont2 exec //FAPIhook exec } bind % 'odef' is below. /.buildfont42 { //.buildfont42 exec //FAPIhook exec } bind % 'odef' is below. /.buildfont9 { //.buildfont9 exec //FAPIhook exec } bind % 'odef' is below. /.buildfont10 { //.buildfont10 exec //FAPIhook exec } bind % 'odef' is below. /.buildfont11 { //.buildfont11 exec //FAPIhook exec } bind % 'odef' is below. end % the temporary dictionary for local binding. odef odef odef odef odef odef % Undef these, not needed outside this file [ /.FAPIavailable /.FAPIpassfont /.FAPIrebuildfont ] systemdict .undefinternalnames .setlanguagelevel %END FAPI