% Copyright (C) 2000 artofcode LLC. 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. % % For more information about licensing, please refer to % http://www.ghostscript.com/licensing/. For information on % commercial licensing, go to http://www.artifex.com/licensing/ or % contact Artifex Software, Inc., 101 Lucas Valley Road #110, % San Rafael, CA 94903, U.S.A., +1(415)492-9861. % $Id: gs_fapi.ps,v 1.25 2003/04/12 18:08:18 ray Exp $ % Redefine Font and CIDFont categories with FAPI-handeled fonts. systemdict /.FAPIavailable known { .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 { currentdevice //EmbedFontObjectsQuery .getdeviceparams % ... dup mark eq { pop true } { exch pop exch pop 0 eq } ifelse % 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 ----------------------- /Config << %% Replace 1 (FAPIconfig) (FAPIconfig) .runlibfile >> def %------------------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 /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 { //FontOptions //complete_instance exec 2 copy //GetSize exec } bind def currentdict end def /CIDFontRecordVirtualMethods //RecordVirtualMethodsStub dup length 3 add dict copy begin /GetCSI //TranslateCSI def /IsActive //IsActive def /MakeInstance % MakeInstance { //CIDFontOptions //complete_instance exec 2 copy //GetSize exec } bind def currentdict end def %----------------------------------The Redefintion--------------------- /MappedCategoryRedefiner /ProcSet findresource /Redefine get /Redefine exch def % Redefine the /Font category : 4 dict begin /CategoryName /Font def /MapFileName (FAPIfontmap) 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 (FAPIcidfmap) 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 <> { (FAPIhook ) print 1 index = } //FAPI_hook_debug exec dup /FAPI known { { //PrintFontRef exec ( is mapped to FAPI=) print dup /FAPI get = } //FAPI_hook_warn exec true //.FAPIrebuildfont //ChooseDecoding exec } { dup /PathLoad known dup { { (PathLoad known for the font ) print //PrintFontRef exec (.) = } //FAPI_hook_debug exec } { pop //FAPI_is_hook_disabled exec dup { pop { (FAPIhook is in .loadfont context for the font ) print //PrintFontRef exec (.) = } //FAPI_hook_debug exec true } if } ifelse { /HookDiskFonts } { /HookEmbeddedFonts } ifelse //Config exch get % name <> [types] 1 index //GetFontType exec //FindInArray exec % name <> bHook { { (Trying to render the font ) print //PrintFontRef exec ( with FAPI...) = } //FAPI_hook_debug exec //.FAPIpassfont { { //PrintFontRef exec ( is being rendered with FAPI=) print dup /FAPI get = } //FAPI_hook_warn exec false //.FAPIrebuildfont //ChooseDecoding exec } { { (Can't render ) print //PrintFontRef exec ( with FAPI, will do with native GS renderer.) = } //FAPI_hook_warn exec } ifelse } { { (The font ) print //PrintFontRef exec ( doesn't need to render with FAPI.) = } //FAPI_hook_debug exec } ifelse } ifelse } bind def /FAPIhook % .FAPIhook { //is_device_compatible_to_FAPI exec { //FAPIhook_aux exec } { { (FAPIhook is disabled for the current device.) = } //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 .setlanguagelevel %END FAPI