% 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} iflanguagelevel 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>{ currentdevice //EmbedFontObjectsQuery .getdeviceparams % <mark> <name> <value> ... 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} forallcurrentdict /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 /configurationerror signalerror } if def currentdict end} bind 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} bind def/IsMyRecord % <raw_record> -> <raw_record> bool{ dup type /dicttype eq { dup /FAPI known } { false } ifelse} bind def/IsActive % <record> IsActive <bool>{ pop //is_device_compatible_to_FAPI exec} bind def/FontRecordVirtualMethods //RecordVirtualMethodsStub dup length 2 add dict copy begin /IsActive //IsActive def /MakeInstance % <Name> <record> MakeInstance <Name> <Instance> <size> { //FontOptions //complete_instance exec 2 copy //GetSize exec } bind 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> { //CIDFontOptions //complete_instance exec 2 copy //GetSize exec } bind defcurrentdict 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 % <map> <Name> <raw_record> PreprocessRecord <map> <Name> <record> <bool> { //IsMyRecord exec dup { pop dup /RecordVirtualMethods //FontRecordVirtualMethods put true } if } bind defcurrentdict end Redefine% Redefine the /CIDFont category :4 dict begin /CategoryName /CIDFont def /MapFileName (FAPIcidfmap) def /VerifyMap { pop } bind def /PreprocessRecord % <map> <Name> <raw_record> PreprocessRecord <map> <Name> <record> <bool> { //IsMyRecord exec dup { pop dup /RecordVirtualMethods //CIDFontRecordVirtualMethods put true } if } bind 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} bind def/FAPIhook_aux % <string|name> <font_dict> .FAPIhook <string|name> <font>{ % name <<font>> { (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 <<font>> [types] 1 index //GetFontType exec //FindInArray exec % name <<font>> 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 % <string|name> <font_dict> .FAPIhook <string|name> <font>{ //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
% 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 <bool>
{ currentdevice //EmbedFontObjectsQuery .getdeviceparams % <mark> <name> <value> ...
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 % <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 /configurationerror signalerror
} if
def
currentdict end
} bind 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
} bind def
/IsMyRecord % <raw_record> -> <raw_record> bool
{ dup type /dicttype eq { dup /FAPI known } { false } ifelse
} bind def
/IsActive % <record> IsActive <bool>
{ pop //is_device_compatible_to_FAPI exec
} bind def
/FontRecordVirtualMethods //RecordVirtualMethodsStub dup length 2 add dict copy begin
/IsActive //IsActive def
/MakeInstance % <Name> <record> MakeInstance <Name> <Instance> <size>
{ //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 % <Name> <record> MakeInstance <Name> <Instance> <size>
{ //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 % <map> <Name> <raw_record> PreprocessRecord <map> <Name> <record> <bool>
{ //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 % <map> <Name> <raw_record> PreprocessRecord <map> <Name> <record> <bool>
{ //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 % <proc> FAPI_hook_debug -
FAPIDEBUG { {exec} } { {pop} } ifelse
bind def
/FAPI_hook_warn % <proc> FAPI_hook_debug -
QUIET { {pop} } { {exec} } ifelse
bind 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
} bind def
/FAPIhook_aux % <string|name> <font_dict> .FAPIhook <string|name> <font>
{ % name <<font>>
{ (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 <<font>> [types]
1 index //GetFontType exec //FindInArray exec % name <<font>> 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 % <string|name> <font_dict> .FAPIhook <string|name> <font>
{ //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