|
|
% Copyright (C) 2001-2023 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., 39 Mesa Street, Suite 108A, San Francisco,
% CA 94129, USA, 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 <bool>
{ //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
} .internalbind 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>> defsystemdict /.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} ifsystemdict /UFST_PlugIn .knownget { 1 index length 0 ne { exch .filenamelistseparator concatstrings exch } if (UFST_PlugIn=) exch concatstrings concatstrings} ifdup 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 % <FontDict> /key RefinePath <FontDict>
{ 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} .internalbind def
/complete_instance % <font_name> <FontDict> <Options> complete_FAPI_Font <font_name> <FontDict>
{ //super.complete_instance exec dup /CIDFontName known { /CIDFontPath } { /FontPath } ifelse //RefinePath exec} .internalbind def
/IsMyRecord % <raw_record> -> <raw_record> bool
{ dup type /dicttype eq { dup /FAPI known } { //false } ifelse} .internalbind def
/IsActive % <record> IsActive <bool>
{ pop //is_device_compatible_to_FAPI exec} .internalbind def
/FontRecordVirtualMethods //RecordVirtualMethodsStub dup length 2 add dict copy begin /IsActive //IsActive def /MakeInstance % <Name> <record> MakeInstance <Name> <Instance> <size>
{ currentglobal 3 1 roll //true setglobal //FontOptions //complete_instance exec 2 copy //GetSize exec 4 3 roll setglobal } .internalbind defcurrentdict end def
/CIDFontRecordVirtualMethods //RecordVirtualMethodsStub dup length 3 add dict copy begin /GetCSI //TranslateCSI def /IsActive //IsActive def /MakeInstance % <Name> <record> MakeInstance <Name> <Instance> <size>
{ currentglobal 3 1 roll //true setglobal //CIDFontOptions //complete_instance exec 2 copy //GetSize exec 4 3 roll setglobal } .internalbind defcurrentdict end def
/ReadFCOfontmap: % <path> 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} .internalbind 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 } .internalbind def /PreprocessRecord % <map> <Name> <raw_record> PreprocessRecord <map> <Name> <record> <bool>
{ //IsMyRecord exec dup { pop dup /RecordVirtualMethods //FontRecordVirtualMethods put //true } if } .internalbind defcurrentdict end Redefine
% Redefine the /CIDFont category :
4 dict begin /CategoryName /CIDFont def /MapFileName systemdict /FAPIcidfmap known {/FAPIcidfmap .systemvar} {(FAPIcidfmap)} ifelse def /VerifyMap { pop } .internalbind def /PreprocessRecord % <map> <Name> <raw_record> PreprocessRecord <map> <Name> <record> <bool>
{ //IsMyRecord exec dup { pop dup /RecordVirtualMethods //CIDFontRecordVirtualMethods put //true } if } .internalbind defcurrentdict 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 % <proc> FAPI_hook_debug -
FAPIDEBUG { {exec} } { {pop} } ifelsebind def
/FAPI_hook_warn % <proc> FAPI_hook_debug -
QUIET { {pop} } { {exec} } ifelsebind def
/FAPI_is_hook_disabled % - FAPI_is_hook_disabled <bool>
{ % checks whether execution stack contains packedarray started with /FAPI_hook_disable .
/FAPI_hook_disable /MappedCategoryRedefiner /ProcSet findresource /execstack_lookup get exec //null ne} .internalbind def
/FAPIhook_aux % <string|name> <font_dict> .FAPIhook <string|name> <font>
{ % name <<font>>
{ (\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 <<font>> [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 <<font>> 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} .internalbind def
/FAPIhook % <string|name> <font_dict> .FAPIhook <string|name> <font>
{ //is_device_compatible_to_FAPI exec { //FAPIhook_aux exec } { { (FAPIhook is disabled for the current device.\n) print flush } //FAPI_hook_debug exec } ifelse} .internalbind def
% ------------------ Redefine .buildfont* with FAPI : -----------------------
/.buildfont1{ //.buildfont1 exec //FAPIhook exec} .internalbind % 'odef' is below.
/.buildfont2{ //.buildfont2 exec //FAPIhook exec} .internalbind % 'odef' is below.
/.buildfont42{ //.buildfont42 exec //FAPIhook exec} .internalbind % 'odef' is below.
/.buildfont9{ //.buildfont9 exec //FAPIhook exec} .internalbind % 'odef' is below.
/.buildfont10{ //.buildfont10 exec //FAPIhook exec} .internalbind % 'odef' is below.
/.buildfont11{ //.buildfont11 exec //FAPIhook exec} .internalbind % '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
|