diff options
author | Reinhard Kotucha <reinhard.kotucha@web.de> | 2017-04-23 22:15:25 +0000 |
---|---|---|
committer | Reinhard Kotucha <reinhard.kotucha@web.de> | 2017-04-23 22:15:25 +0000 |
commit | 54448d6ab44d2033482fafa56ddc40d42a6815eb (patch) | |
tree | d4fdfff7b7f75c367a76f872e2986af75c5f81a3 /Master/tlpkg/tlgs/Resource/Init | |
parent | f2a947f3017b82f1dfa1058d1d720fe11d298e92 (diff) |
Add files needed for CJK to tlgs, adapt runscript.tlu accordingly.
git-svn-id: svn://tug.org/texlive/trunk@43997 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg/tlgs/Resource/Init')
63 files changed, 41763 insertions, 0 deletions
diff --git a/Master/tlpkg/tlgs/Resource/Init/FAPIcidfmap b/Master/tlpkg/tlgs/Resource/Init/FAPIcidfmap new file mode 100644 index 00000000000..38e42e60df1 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/FAPIcidfmap @@ -0,0 +1,32 @@ +%! +% $Id: FAPIcidfmap 6826 2006-05-31 15:29:52Z leonardo $ +% This is a sample map file for FAPI CID fonts. + +% +% The map is a set of records like this : +% +% /CIDfont_name options_dict ; +% +% where options_dict is a dictionary with the following entries : +% +% Key Type Description +% Path string Absolute path to font file, or relative path to font file from +% the GS_EXTFONTPATH value. +% CIDFontType interger PostScript type for this CID font. Only 0 is currently allowed. +% Note that this is unrelated to the real type of the font file - +% the bridge will perform format conversion. +% FAPI name Name of the renderer to be used with the font. Only /UFST is now allowed. +% SubfontId integer (optional) Index of the font in font collection, such as FCO or TTC. +% It is being ignored if /Path doesn't specify a collection. +% Default value is 0. +% CSI array Must have strongly 2 elements. +% The first element of the array specifies Ordering of CIDSystemInfo. +% The second element specifies Supplement of CIDSystemInfo. +% +% Use regular Postscript syntax. +% +% Examples : +% +% /Ryumin-Medium << /Path (msgothic.ttc) /CIDFontType 0 /FAPI /UFST /CSI [(Japan1) 2] >> ; +% /HeiseiKakuGo-W5 << /Path (F:/WIN2000/Fonts/BATANG.TTC) /CIDFontType 0 /FAPI /UFST /CSI [(Japan1) 2] >> ; + diff --git a/Master/tlpkg/tlgs/Resource/Init/FAPIconfig b/Master/tlpkg/tlgs/Resource/Init/FAPIconfig new file mode 100644 index 00000000000..f893add7db2 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/FAPIconfig @@ -0,0 +1,14 @@ +%! +% $Id: FAPIconfig 6870 2006-06-20 16:31:15Z leonardo $ +% This is configuration file for FAPI client. +% +% /FontPath (/Fonts) % A default directory for FAPI-handled font files path in FAPIfontmap. +% /CIDFontPath (/CIDFonts) % A default directory for FAPI-handled CID font files path in FAPIcidfmap. +% /HookDiskFonts [1 2 9 11 42] % FontType values for disk PS fonts to be redirected to FAPI. +% /HookEmbeddedFonts [1 2 9 11 42] % FontType values for embedded PS fonts to be redirected to FAPI. +% +% Values allowed for HookDiskFonts and HookEmbeddedFonts are 1, 2, 9, 11, 42. +% "Disk fonts" are fonts being installed to Ghostscript with 'lib/Fontmap' or with GS_FONTPATH, +% and CID font resource files. +% "Embedded fonts" are fonts and CID fonts being embedded into a document. + diff --git a/Master/tlpkg/tlgs/Resource/Init/FAPIfontmap b/Master/tlpkg/tlgs/Resource/Init/FAPIfontmap new file mode 100644 index 00000000000..0fedcdeaef8 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/FAPIfontmap @@ -0,0 +1,33 @@ +%! +% $Id: FAPIfontmap 6870 2006-06-20 16:31:15Z leonardo $ +% This is a sample map file for FAPI fonts. + +% +% The map is a set of records like this : +% +% /font_name options_dict ; +% +% where options_dict is a dictionary with the following entries : +% +% Key Type Description +% Path string Absolute path to font file, or relative path to font file from +% the GS_EXTFONTPATH value. +% FontType interger PostScript type for this font. Only 1 and 42 are currently allowed. +% Note that this is unrelated to the real type of the font file - +% the bridge will perform format conversion. +% FAPI name Name of the renderer to be used with the font. Only /AgfaUFST is now allowed. +% SubfontId integer (optional) Index of the font in font collection, such as FCO or TTC. +% It is being ignored if /Path doesn't specify a collection. +% Default value is 0. +% Decoding name (optional) The name of a Decoding resource to be used with the font. +% If specified, "xlatmap" doesn't work for this font. +% +% Use regular Postscript syntax. +% +% Examples : +% +% /ArialTT << /Path (arial.ttf) /FontType 1 /FAPI /UFST >> ; +% /CourierTT << /Path (F:/WIN2000/Fonts/cour.ttf) /FontType 1 /FAPI /UFST >> ; +% /FCO1 << /Path (F:/AFPL/ufst/fontdata/MTFONTS/PCLPS3/MT1/PCLP3__G.FCO) /FontType 42 /FAPI /UFST /SubfontId 10 >> ; +% + diff --git a/Master/tlpkg/tlgs/Resource/Init/FCOfontmap-PCLPS2 b/Master/tlpkg/tlgs/Resource/Init/FCOfontmap-PCLPS2 new file mode 100644 index 00000000000..9011451e2c8 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/FCOfontmap-PCLPS2 @@ -0,0 +1,106 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + + +% May add general FAPIfontmap records here like this : +/Wingdings-Regular << /Path FCOfontfile2 /FontType 1 /FAPI /UFST /SubfontId 0 /Encoding /Wingdings /Decoding /FCO_Wingdings>> ; + +% Mapping Postscript fonts to pclp2_xj.fco FCO members : +FCOfontfile ReadFCOfontmap: +0 Albertus-Medium +1 Albertus-ExtraBold +2 AntiqueOlive +3 AntiqueOlive-Italic +4 AntiqueOlive-Bold +5 Arial +6 Arial-Italic +7 Arial-Bold +8 Arial-BoldItalic +9 Clarendon-Condensed-Bold +10 Coronet +11 CourierHP +12 CourierHP-Italic +13 CourierHP-Bold +14 CourierHP-BoldItalic +15 Garamond-Antiqua +16 Garamond-Kursiv +17 Garamond-Halbfett +18 Garamond-KursivHalbfett +19 LetterGothic +20 LetterGothic-Italic +21 LetterGothic-Bold +22 Marigold +23 CGOmega +24 CGOmega-Italic +25 CGOmega-Bold +26 CGOmega-BoldItalic +27 SymbolMT SymbolEncoding FCO_Symbol +28 CGTimes +29 CGTimes-Italic +30 CGTimes-Bold +31 CGTimes-BoldItalic +32 TimesNewRoman +33 TimesNewRoman-Italic +34 TimesNewRoman-Bold +35 TimesNewRoman-BoldItalic +36 UniversMedium +37 UniversMedium-Italic +38 Univers-Bold +39 Univers-BoldItalic +40 Univers-Condensed-Medium +41 Univers-Condensed-MediumItalic +42 Univers-Condensed-Bold +43 Univers-Condensed-BoldItalic +44 Courier- +45 Courier-Italic +46 Courier-Bold- +47 Courier-BoldItalic +48 AvantGarde-Book +49 AvantGarde-BookOblique +50 AvantGarde-Demi +51 AvantGarde-DemiOblique +52 Bookman-Light +53 Bookman-LightItalic +54 Bookman-Demi +55 Bookman-DemiItalic +56 Courier +57 Courier-Oblique +58 Courier-Bold +59 Courier-BoldOblique +60 Helvetica +61 Helvetica-Oblique +62 Helvetica-Bold +63 Helvetica-BoldOblique +64 Helvetica-Narrow +65 Helvetica-Narrow-Oblique +66 Helvetica-Narrow-Bold +67 Helvetica-Narrow-BoldOblique +68 NewCenturySchlbk-Roman +69 NewCenturySchlbk-Italic +70 NewCenturySchlbk-Bold +71 NewCenturySchlbk-BoldItalic +72 Palatino-Roman +73 Palatino-Italic +74 Palatino-Bold +75 Palatino-BoldItalic +76 Symbol SymbolEncoding FCO_Symbol +77 Times-Roman +78 Times-Italic +79 Times-Bold +80 Times-BoldItalic +81 ZapfChancery-MediumItalic +82 ZapfDingbats DingbatsEncoding FCO_Dingbats +EndFCOfontmap +%EOF diff --git a/Master/tlpkg/tlgs/Resource/Init/Fontmap b/Master/tlpkg/tlgs/Resource/Init/Fontmap new file mode 100644 index 00000000000..ae5af96e0ee --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/Fontmap @@ -0,0 +1,4 @@ +%! +% See Fontmap.GS for the syntax of real Fontmap files. +%% Replace 1 (Fontmap.GS) +(Fontmap.GS) .runlibfile diff --git a/Master/tlpkg/tlgs/Resource/Init/Fontmap.GS b/Master/tlpkg/tlgs/Resource/Init/Fontmap.GS new file mode 100644 index 00000000000..a9fa335a219 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/Fontmap.GS @@ -0,0 +1,343 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Fontmap - standard font catalog for Ghostscript. + +% ---------------------------------------------------------------- + +% This file is a catalog of fonts known to Ghostscript. Any font +% that is to be loaded automatically when named must be in this catalog, +% except for fonts that Ghostscript finds automatically in directories +% named in the GS_FONTPATH environment variable. + +% Each font has an entry consisting of three items: +% +% - The name by which the font is known inside Ghostscript +% (a Ghostscript name preceded by a `/', or a string enclosed +% in parentheses). This is used to find the file from which +% a font of a given name should be loaded. +% +% - Information depending on whether this is a real font or a +% font alias: +% +% - For real fonts, the name of the Ghostscript font +% file (a Ghostscript string, enclosed in parentheses). +% The filename should include the extension, which (by +% convention) is `.gsf'. `.pfa' and `.pfb' files are +% also usable as fonts for Ghostscript. +% +% - For font aliases, the name of the font which should +% be used when this one is requested, preceded by a +% `/'. See the entry for Charter below for an example. +% Note that an alias name cannot be enclosed in parentheses. +% +% - At least one space or tab, and a terminating semicolon. + +% The following table is executed as a PostScript file. +% If you add new entries, be sure to copy the punctuation accurately; +% in particular, you must leave at least one space or tab between each +% field in the entry. Also, please read fonts.doc for important information +% about font names. + +% PDF interpreter evaluates hexadecimal escapes in PDF font names before +% looking up the font. When the resulting name cannot be represented using +% PostScript name syntax, the string can be used instead of the name. + +% Note that .pfa and .pfb fonts are compatible with Adobe Type Manager +% and other programs that don't include full PostScript interpreters, +% as well as with PostScript interpreters; .gsf fonts are compatible with +% PostScript interpreters, but not with ATM or similar programs. + +% +% +% Fonts contributed by: +% URW++ Design and Development Incorporated +% Poppenbuetteler Bogen 29A +% D-22399 Hamburg +% Germany +% tel. +49 (40) 60 60 50 +% fax +49 (40) 60 60 51 11 +% http://www.urwpp.de +% for distribution under the GNU License and Aladdin Free Public License. +% See the notice at the head of this Fontmap file for licensing terms. +% Each of these fonts is individually covered by the license: +% for licensing purposes, they are not "part of" any larger entity. +% The following notice applies to these fonts: +% +% Copyright URW Software, Copyright 1994 by URW. +% + +% Aliases + +/AvantGarde-BookOblique /URWGothic-BookOblique ; +/AvantGarde-Book /URWGothic-Book ; +/AvantGarde-DemiOblique /URWGothic-DemiOblique ; +/AvantGarde-Demi /URWGothic-Demi ; +/Bookman-DemiItalic /URWBookman-DemiItalic ; +/Bookman-Demi /URWBookman-Demi ; +/Bookman-LightItalic /URWBookman-LightItalic ; +/Bookman-Light /URWBookman-Light ; +/Courier-Bold /NimbusMonoPS-Bold ; +/Courier-BoldOblique /NimbusMonoPS-BoldItalic ; +/Courier /NimbusMonoPS-Regular ; +/Courier-Oblique /NimbusMonoPS-Italic ; +/Helvetica-Bold /NimbusSans-Bold ; +/Helvetica-BoldOblique /NimbusSans-BoldOblique ; +/Helvetica-Narrow-Bold /NimbusSansNarrow-Bold ; +/Helvetica-Narrow-BoldOblique /NimbusSansNarrow-BdOblique ; +/Helvetica-Narrow /NimbusSansNarrow-Regular ; +/Helvetica-Narrow-Oblique /NimbusSansNarrow-Oblique ; +/Helvetica /NimbusSans-Regular ; +/Helvetica-Oblique /NimbusSans-Oblique ; +/NewCenturySchlbk-Bold /C059-Bold ; +/NewCenturySchlbk-BoldItalic /C059-BdIta ; +/NewCenturySchlbk-Italic /C059-Italic ; +/NewCenturySchlbk-Roman /C059-Roman ; +/Palatino-BoldItalic /P052-BoldItalic ; +/Palatino-Bold /P052-Bold ; +/Palatino-Italic /P052-Italic ; +/Palatino-Roman /P052-Roman ; +/Symbol /StandardSymbolsPS ; +/Times-BoldItalic /NimbusRoman-BoldItalic ; +/Times-Bold /NimbusRoman-Bold ; +/Times-Italic /NimbusRoman-Italic ; +/Times-Roman /NimbusRoman-Regular ; +/ZapfChancery-MediumItalic /Z003-MediumItalic ; +/ZapfDingbats /D050000L ; + +% +% +% Type 1 fonts contributed to the X11R5 distribution. +% + +% The following notice accompanied the Charter fonts. +% +% (c) Copyright 1989-1992, Bitstream Inc., Cambridge, MA. +% +% You are hereby granted permission under all Bitstream propriety rights +% to use, copy, modify, sublicense, sell, and redistribute the 4 Bitstream +% Charter (r) Type 1 outline fonts and the 4 Courier Type 1 outline fonts +% for any purpose and without restriction; provided, that this notice is +% left intact on all copies of such fonts and that Bitstream's trademark +% is acknowledged as shown below on all unmodified copies of the 4 Charter +% Type 1 fonts. +% +% BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + +/CharterBT-Roman (bchr.pfa) ; +/CharterBT-Italic (bchri.pfa) ; +/CharterBT-Bold (bchb.pfa) ; +/CharterBT-BoldItalic (bchbi.pfa) ; + +% Aliases + +/Charter-Roman /CharterBT-Roman ; +/Charter-Italic /CharterBT-Italic ; +/Charter-Bold /CharterBT-Bold ; +/Charter-BoldItalic /CharterBT-BoldItalic ; + +% The following notice accompanied the Utopia font: +% +% Permission to use, reproduce, display and distribute the listed +% typefaces is hereby granted, provided that the Adobe Copyright notice +% appears in all whole and partial copies of the software and that the +% following trademark symbol and attribution appear in all unmodified +% copies of the software: +% +% Copyright (c) 1989 Adobe Systems Incorporated +% Utopia (R) +% Utopia is a registered trademark of Adobe Systems Incorporated +% +% The Adobe typefaces (Type 1 font program, bitmaps and Adobe Font +% Metric files) donated are: +% +% Utopia Regular +% Utopia Italic +% Utopia Bold +% Utopia Bold Italic + +/Utopia-Regular (putr.pfa) ; +/Utopia-Italic (putri.pfa) ; +/Utopia-Bold (putb.pfa) ; +/Utopia-BoldItalic (putbi.pfa) ; + +% +% +% Fonts contributed by URW GmbH for distribution under the GNU License. +% The following notice accompanied these fonts: +% +% U004006T URW Grotesk 2031 Bold PostScript Type 1 Font Program +% U003043T URW Antiqua 2051 Regular Condensed PostScript Type 1 Font Program +% +% Copyright (c) 1992 URW GmbH, Hamburg, Germany +% +% This program is free software; you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation; either version 2 of the License, or +% (at your option) later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; wihtout even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +% See the GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program; if not, write to the Free Software +% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 U.S.A. +% +% Address: +% URW GmbH +% PC Support +% Harksheider Strasse 102 +% 2000 Hamburg 65 +% Germany +% Phone: +49 40 60 60 50 (Reception) +% Phone: +49 40 60 60 52 30 (PC Support) +% Fax : +49 40 60 60 52 52 +% + +/URWAntiquaT-RegularCondensed (u003043t.gsf) ; +/URWGroteskT-Bold (u004006t.gsf) ; + +% +% +% Calligraphic Kana fonts. These are distributed under the OFL 1.1: +% +% Copyright (c) 1993, Kevin Hartig (kevin.hartig@gmail.com), +% with Reserved Font Name Calligraphic-Hiragana and Calligraphic-Katakana. +% This Font Software is licensed under the SIL Open Font License, Version 1.1. +% This license is available with an FAQ at: http://scripts.sil.org/OFL + +% Hiragana and Katakana fonts. The character names are inappropriate, +% and the encoding is probably not related to any known standard. + +/Calligraphic-Hiragana (fhirw.gsf) ; +/Calligraphic-Katakana (fkarw.gsf) ; + +% +% +% Public-domain fonts. These have no copyright, and are of unknown quality. + +% Cyrillic fonts. The character names are inappropriate, +% and the encoding is probably not related to any known standard. + +/Shareware-Cyrillic-Regular (fcyr.gsf) ; +/Shareware-Cyrillic-Italic (fcyri.gsf) ; + +% Aliases +/Cyrillic /Cyrillic-Regular ; +/Cyrillic-Regular /Shareware-Cyrillic-Regular ; +/Cyrillic-Italic /Shareware-Cyrillic-Italic ; + +% +% +% Fonts converted from Hershey outlines. These are constructed and +% maintained manually. These are also in the public domain. +% +% The suggested UniqueID's and filenames are constructed differently for +% these than for the ones above, because of the strange way that the Hershey +% fonts were constructed. The scheme for these looks like: +% +% 42TTXY0 +% +% TT = typeface, X = ``class'', Y = variation +% +% The typeface names and numbers are listed in fonts.mak. +% +% class: +% 0 = normal = r +% 1 = simplex = s +% 2 = complex = c +% 3 = triplex = t +% 4 = duplex = d +% +% variation: +% 0 = normal (omitted) +% 1 = oblique = o +% 2 = italic = i +% 3 = bold = b +% 4 = bold oblique = bo +% 5 = bold italic = bi +% + +% Fonts created by Thomas Wolff <wolff@inf.fu-berlin.de>, by adding +% accents, accented characters, and various other non-alphabetics +% to the original Hershey fonts. These are "freeware", not to be sold. + +/Hershey-Gothic-English (hrger.pfa) ; % 5066533 +/Hershey-Gothic-German (hrgrr.pfa) ; +/Hershey-Gothic-Italian (hritr.pfa) ; + +/Hershey-Plain-Duplex (hrpld.pfa) ; +/Hershey-Plain-Duplex-Italic (hrpldi.pfa) ; +/Hershey-Plain-Triplex (hrplt.pfa) ; +/Hershey-Plain-Triplex-Italic (hrplti.pfa) ; + +/Hershey-Script-Complex (hrscc.pfa) ; +/Hershey-Script-Simplex (hrscs.pfa) ; % 5066541 + +% Fonts created algorithmically from the above. + +/Hershey-Gothic-English-Bold (hrgerb.gsf) ; % 5066542 +/Hershey-Gothic-English-Oblique (hrgero.gsf) ; +/Hershey-Gothic-English-SemiBold (hrgerd.gsf) ; +/Hershey-Gothic-German-Bold (hrgrrb.gsf) ; +/Hershey-Gothic-German-Oblique (hrgrro.gsf) ; +/Hershey-Gothic-Italian-Bold (hritrb.gsf) ; +/Hershey-Gothic-Italian-Oblique (hritro.gsf) ; + +/Hershey-Plain-Duplex-Bold (hrpldb.gsf) ; +/Hershey-Plain-Duplex-Bold-Italic (hrpldbi.gsf) ; +/Hershey-Plain-Triplex-Bold (hrpltb.gsf) ; +/Hershey-Plain-Triplex-Bold-Italic (hrpltbi.gsf) ; + +/Hershey-Script-Complex-Bold (hrsccb.gsf) ; +/Hershey-Script-Complex-Oblique (hrscco.gsf) ; +/Hershey-Script-Simplex-Bold (hrscsb.gsf) ; +/Hershey-Script-Simplex-Oblique (hrscso.gsf) ; % 5066556 + +% Fonts consisting only of characters from the original Hershey +% distribution. These are Type 3 fonts. + +/Hershey-Greek-Complex (hrgkc.gsf) ; % 5066557 +/Hershey-Greek-Simplex (hrgks.gsf) ; + +/Hershey-Plain (hrplr.gsf) ; +/Hershey-Plain-Simplex (hrpls.gsf) ; % 5066560 + +% Fonts created algorithmically from the above. + +/Hershey-Plain-Bold (hrplrb.gsf) ; % 5066561 +/Hershey-Plain-Bold-Oblique (hrplrbo.gsf) ; +/Hershey-Plain-Oblique (hrplro.gsf) ; +/Hershey-Plain-Simplex-Bold (hrplsb.gsf) ; +/Hershey-Plain-Simplex-Bold-Oblique (hrplsbo.gsf) ; +/Hershey-Plain-Simplex-Oblique (hrplso.gsf) ; % 5066566 + +% This font, and only this font among the Hershey fonts, uses +% the SymbolEncoding. + +/Hershey-Symbol (hrsyr.gsf) ; % 5066567 + +/Arial /ArialMT ; +/Arial,Bold /Arial-BoldMT ; +/Arial,Italic /Arial-ItalicMT ; +/Arial,BoldItalic /Arial-BoldItalicMT ; + +/TimesNewRoman /TimesNewRomanPSMT ; +/TimesNewRoman,Bold /TimesNewRomanPS-BoldMT ; +/TimesNewRoman,Italic /TimesNewRomanPS-ItalicMT ; +/TimesNewRoman,BoldItalic /TimesNewRomanPS-BoldItalicMT ; + diff --git a/Master/tlpkg/tlgs/Resource/Init/cidfmap b/Master/tlpkg/tlgs/Resource/Init/cidfmap new file mode 100644 index 00000000000..bed221ac0db --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/cidfmap @@ -0,0 +1,47 @@ +%! +% This is a sample map file for CIDFont category. + +% +% The map is a set of records, which must use one of the two formats : +% +% 1. A substutution of a CIDFont font with another CIDFont : +% +% /substituted /original ; +% +% Where 'substituted' is a name being used in a document, +% 'original' is a name of an available resource. +% +% 2. A substutution of a CIDFont font with a True Type font : +% +% /substituted << /FileType /TrueType /Path (path) /SubfontID 1 /CSI [(ordering) supplement] >> ; +% +% Where 'substituted' is a name being used in a document, +% 'path' is a path to a True Type font file, +% 'ordering' is a value of Ordering required for CIDSystemInfo dictionary, +% 'supplement' is a value of Supplement required for CIDSystemInfo dictionary. +% 'SubfontID' is the index of the desired font in a TTC - ignored if the target is not a TTC. +% +% The Ordering, and Registry (if present) entries should be PostScript string types +% ie enclosed in parentheses, not PostScript name type (initial character '/'). See +% gs/doc/Use.htm#CIDFontSubstitution +% +% Alternatively: +% (substituted name) << /FileType /TrueType /Path (path) /SubfontID 1 /CSI [(ordering) supplement] >> ; +% +% This is where the CIDFont name in the document contains a space character. Using a string instead of a name +% allows this work - Ghostscript will internally convert the key string with a space to a name. +% +% +% Examples : +% +% /ShinGo-Bold /HeiseiKakuGo-W5 ; +% /Ryumin-Medium << /FileType /TrueType /Path (H:/AuxFiles/Fonts/BATANG.TTC) /SubfontID 3 /CSI [(Japan1) 2] >> ; +% /Ryumin-Medium << /FileType /TrueType /Path (windir) getenv not {(c:/windows)}if (/Fonts/BATANG.TTC)concatstrings /SubfontID 3 /CSI [(Japan1) 2] >> ; +% +% NOTE: getenv returns a boolean to indicate success of or failure, as well as the value on success. In the example, it uses this +% to include a default value should getenv fail. +% +% (Century Gothic) << /FileType /TrueType /Path (/usr/share/fonts/truetype/fonts-japanese-gothic.ttf) /CSI [(Identity) 1] >> ; +% +% Note the use of a string to cope with the name containing a space. +% diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_agl.ps b/Master/tlpkg/tlgs/Resource/Init/gs_agl.ps new file mode 100644 index 00000000000..6b9e1468f4c --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_agl.ps @@ -0,0 +1,7988 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% $Id: gs_agl.ps 10822 2010-02-27 20:24:13Z alexcher $ + +% This file was derived from the Adobe Glyph List, version 2.0, dated +% September 20, 2002. +% See http://partners.adobe.com/asn/developer/typeforum/unicodegn.html +% That file does not contain any copyright notice. + +/AdobeGlyphList mark +/A 16#0041 +/AE 16#00C6 +/AEacute 16#01FC +/AEmacron 16#01E2 +/AEsmall 16#F7E6 +/Aacute 16#00C1 +/Aacutesmall 16#F7E1 +/Abreve 16#0102 +/Abreveacute 16#1EAE +/Abrevecyrillic 16#04D0 +/Abrevedotbelow 16#1EB6 +/Abrevegrave 16#1EB0 +/Abrevehookabove 16#1EB2 +/Abrevetilde 16#1EB4 +/Acaron 16#01CD +/Acircle 16#24B6 +/Acircumflex 16#00C2 +/Acircumflexacute 16#1EA4 +/Acircumflexdotbelow 16#1EAC +/Acircumflexgrave 16#1EA6 +/Acircumflexhookabove 16#1EA8 +/Acircumflexsmall 16#F7E2 +/Acircumflextilde 16#1EAA +/Acute 16#F6C9 +/Acutesmall 16#F7B4 +/Acyrillic 16#0410 +/Adblgrave 16#0200 +/Adieresis 16#00C4 +/Adieresiscyrillic 16#04D2 +/Adieresismacron 16#01DE +/Adieresissmall 16#F7E4 +/Adotbelow 16#1EA0 +/Adotmacron 16#01E0 +/Agrave 16#00C0 +/Agravesmall 16#F7E0 +/Ahookabove 16#1EA2 +/Aiecyrillic 16#04D4 +/Ainvertedbreve 16#0202 +/Alpha 16#0391 +/Alphatonos 16#0386 +/Amacron 16#0100 +/Amonospace 16#FF21 +/Aogonek 16#0104 +/Aring 16#00C5 +/Aringacute 16#01FA +/Aringbelow 16#1E00 +/Aringsmall 16#F7E5 +/Asmall 16#F761 +/Atilde 16#00C3 +/Atildesmall 16#F7E3 +/Aybarmenian 16#0531 +/B 16#0042 +/Bcircle 16#24B7 +/Bdotaccent 16#1E02 +/Bdotbelow 16#1E04 +/Becyrillic 16#0411 +/Benarmenian 16#0532 +/Beta 16#0392 +/Bhook 16#0181 +/Blinebelow 16#1E06 +/Bmonospace 16#FF22 +/Brevesmall 16#F6F4 +/Bsmall 16#F762 +/Btopbar 16#0182 +/C 16#0043 +/Caarmenian 16#053E +/Cacute 16#0106 +/Caron 16#F6CA +/Caronsmall 16#F6F5 +/Ccaron 16#010C +/Ccedilla 16#00C7 +/Ccedillaacute 16#1E08 +/Ccedillasmall 16#F7E7 +/Ccircle 16#24B8 +/Ccircumflex 16#0108 +/Cdot 16#010A +/Cdotaccent 16#010A +/Cedillasmall 16#F7B8 +/Chaarmenian 16#0549 +/Cheabkhasiancyrillic 16#04BC +/Checyrillic 16#0427 +/Chedescenderabkhasiancyrillic 16#04BE +/Chedescendercyrillic 16#04B6 +/Chedieresiscyrillic 16#04F4 +/Cheharmenian 16#0543 +/Chekhakassiancyrillic 16#04CB +/Cheverticalstrokecyrillic 16#04B8 +/Chi 16#03A7 +/Chook 16#0187 +/Circumflexsmall 16#F6F6 +/Cmonospace 16#FF23 +/Coarmenian 16#0551 +/Csmall 16#F763 +/D 16#0044 +/DZ 16#01F1 +/DZcaron 16#01C4 +/Daarmenian 16#0534 +/Dafrican 16#0189 +/Dcaron 16#010E +/Dcedilla 16#1E10 +/Dcircle 16#24B9 +/Dcircumflexbelow 16#1E12 +/Dcroat 16#0110 +/Ddotaccent 16#1E0A +/Ddotbelow 16#1E0C +/Decyrillic 16#0414 +/Deicoptic 16#03EE +/Delta 16#2206 +/Deltagreek 16#0394 +/Dhook 16#018A +/Dieresis 16#F6CB +/DieresisAcute 16#F6CC +/DieresisGrave 16#F6CD +/Dieresissmall 16#F7A8 +/Digammagreek 16#03DC +/Djecyrillic 16#0402 +/Dlinebelow 16#1E0E +/Dmonospace 16#FF24 +/Dotaccentsmall 16#F6F7 +/Dslash 16#0110 +/Dsmall 16#F764 +/Dtopbar 16#018B +/Dz 16#01F2 +/Dzcaron 16#01C5 +/Dzeabkhasiancyrillic 16#04E0 +/Dzecyrillic 16#0405 +/Dzhecyrillic 16#040F +/E 16#0045 +/Eacute 16#00C9 +/Eacutesmall 16#F7E9 +/Ebreve 16#0114 +/Ecaron 16#011A +/Ecedillabreve 16#1E1C +/Echarmenian 16#0535 +/Ecircle 16#24BA +/Ecircumflex 16#00CA +/Ecircumflexacute 16#1EBE +/Ecircumflexbelow 16#1E18 +/Ecircumflexdotbelow 16#1EC6 +/Ecircumflexgrave 16#1EC0 +/Ecircumflexhookabove 16#1EC2 +/Ecircumflexsmall 16#F7EA +/Ecircumflextilde 16#1EC4 +/Ecyrillic 16#0404 +/Edblgrave 16#0204 +/Edieresis 16#00CB +/Edieresissmall 16#F7EB +/Edot 16#0116 +/Edotaccent 16#0116 +/Edotbelow 16#1EB8 +/Efcyrillic 16#0424 +/Egrave 16#00C8 +/Egravesmall 16#F7E8 +/Eharmenian 16#0537 +/Ehookabove 16#1EBA +/Eightroman 16#2167 +/Einvertedbreve 16#0206 +/Eiotifiedcyrillic 16#0464 +/Elcyrillic 16#041B +/Elevenroman 16#216A +/Emacron 16#0112 +/Emacronacute 16#1E16 +/Emacrongrave 16#1E14 +/Emcyrillic 16#041C +/Emonospace 16#FF25 +/Encyrillic 16#041D +/Endescendercyrillic 16#04A2 +/Eng 16#014A +/Enghecyrillic 16#04A4 +/Enhookcyrillic 16#04C7 +/Eogonek 16#0118 +/Eopen 16#0190 +/Epsilon 16#0395 +/Epsilontonos 16#0388 +/Ercyrillic 16#0420 +/Ereversed 16#018E +/Ereversedcyrillic 16#042D +/Escyrillic 16#0421 +/Esdescendercyrillic 16#04AA +/Esh 16#01A9 +/Esmall 16#F765 +/Eta 16#0397 +/Etarmenian 16#0538 +/Etatonos 16#0389 +/Eth 16#00D0 +/Ethsmall 16#F7F0 +/Etilde 16#1EBC +/Etildebelow 16#1E1A +/Euro 16#20AC +/Ezh 16#01B7 +/Ezhcaron 16#01EE +/Ezhreversed 16#01B8 +/F 16#0046 +/Fcircle 16#24BB +/Fdotaccent 16#1E1E +/Feharmenian 16#0556 +/Feicoptic 16#03E4 +/Fhook 16#0191 +/Fitacyrillic 16#0472 +/Fiveroman 16#2164 +/Fmonospace 16#FF26 +/Fourroman 16#2163 +/Fsmall 16#F766 +/G 16#0047 +/GBsquare 16#3387 +/Gacute 16#01F4 +/Gamma 16#0393 +/Gammaafrican 16#0194 +/Gangiacoptic 16#03EA +/Gbreve 16#011E +/Gcaron 16#01E6 +/Gcedilla 16#0122 +/Gcircle 16#24BC +/Gcircumflex 16#011C +/Gcommaaccent 16#0122 +/Gdot 16#0120 +/Gdotaccent 16#0120 +/Gecyrillic 16#0413 +/Ghadarmenian 16#0542 +/Ghemiddlehookcyrillic 16#0494 +/Ghestrokecyrillic 16#0492 +/Gheupturncyrillic 16#0490 +/Ghook 16#0193 +/Gimarmenian 16#0533 +/Gjecyrillic 16#0403 +/Gmacron 16#1E20 +/Gmonospace 16#FF27 +/Grave 16#F6CE +/Gravesmall 16#F760 +/Gsmall 16#F767 +/Gsmallhook 16#029B +/Gstroke 16#01E4 +/H 16#0048 +/H18533 16#25CF +/H18543 16#25AA +/H18551 16#25AB +/H22073 16#25A1 +/HPsquare 16#33CB +/Haabkhasiancyrillic 16#04A8 +/Hadescendercyrillic 16#04B2 +/Hardsigncyrillic 16#042A +/Hbar 16#0126 +/Hbrevebelow 16#1E2A +/Hcedilla 16#1E28 +/Hcircle 16#24BD +/Hcircumflex 16#0124 +/Hdieresis 16#1E26 +/Hdotaccent 16#1E22 +/Hdotbelow 16#1E24 +/Hmonospace 16#FF28 +/Hoarmenian 16#0540 +/Horicoptic 16#03E8 +/Hsmall 16#F768 +/Hungarumlaut 16#F6CF +/Hungarumlautsmall 16#F6F8 +/Hzsquare 16#3390 +/I 16#0049 +/IAcyrillic 16#042F +/IJ 16#0132 +/IUcyrillic 16#042E +/Iacute 16#00CD +/Iacutesmall 16#F7ED +/Ibreve 16#012C +/Icaron 16#01CF +/Icircle 16#24BE +/Icircumflex 16#00CE +/Icircumflexsmall 16#F7EE +/Icyrillic 16#0406 +/Idblgrave 16#0208 +/Idieresis 16#00CF +/Idieresisacute 16#1E2E +/Idieresiscyrillic 16#04E4 +/Idieresissmall 16#F7EF +/Idot 16#0130 +/Idotaccent 16#0130 +/Idotbelow 16#1ECA +/Iebrevecyrillic 16#04D6 +/Iecyrillic 16#0415 +/Ifraktur 16#2111 +/Igrave 16#00CC +/Igravesmall 16#F7EC +/Ihookabove 16#1EC8 +/Iicyrillic 16#0418 +/Iinvertedbreve 16#020A +/Iishortcyrillic 16#0419 +/Imacron 16#012A +/Imacroncyrillic 16#04E2 +/Imonospace 16#FF29 +/Iniarmenian 16#053B +/Iocyrillic 16#0401 +/Iogonek 16#012E +/Iota 16#0399 +/Iotaafrican 16#0196 +/Iotadieresis 16#03AA +/Iotatonos 16#038A +/Ismall 16#F769 +/Istroke 16#0197 +/Itilde 16#0128 +/Itildebelow 16#1E2C +/Izhitsacyrillic 16#0474 +/Izhitsadblgravecyrillic 16#0476 +/J 16#004A +/Jaarmenian 16#0541 +/Jcircle 16#24BF +/Jcircumflex 16#0134 +/Jecyrillic 16#0408 +/Jheharmenian 16#054B +/Jmonospace 16#FF2A +/Jsmall 16#F76A +/K 16#004B +/KBsquare 16#3385 +/KKsquare 16#33CD +/Kabashkircyrillic 16#04A0 +/Kacute 16#1E30 +/Kacyrillic 16#041A +/Kadescendercyrillic 16#049A +/Kahookcyrillic 16#04C3 +/Kappa 16#039A +/Kastrokecyrillic 16#049E +/Kaverticalstrokecyrillic 16#049C +/Kcaron 16#01E8 +/Kcedilla 16#0136 +/Kcircle 16#24C0 +/Kcommaaccent 16#0136 +/Kdotbelow 16#1E32 +/Keharmenian 16#0554 +/Kenarmenian 16#053F +/Khacyrillic 16#0425 +/Kheicoptic 16#03E6 +/Khook 16#0198 +/Kjecyrillic 16#040C +/Klinebelow 16#1E34 +/Kmonospace 16#FF2B +/Koppacyrillic 16#0480 +/Koppagreek 16#03DE +/Ksicyrillic 16#046E +/Ksmall 16#F76B +/L 16#004C +/LJ 16#01C7 +/LL 16#F6BF +/Lacute 16#0139 +/Lambda 16#039B +/Lcaron 16#013D +/Lcedilla 16#013B +/Lcircle 16#24C1 +/Lcircumflexbelow 16#1E3C +/Lcommaaccent 16#013B +/Ldot 16#013F +/Ldotaccent 16#013F +/Ldotbelow 16#1E36 +/Ldotbelowmacron 16#1E38 +/Liwnarmenian 16#053C +/Lj 16#01C8 +/Ljecyrillic 16#0409 +/Llinebelow 16#1E3A +/Lmonospace 16#FF2C +/Lslash 16#0141 +/Lslashsmall 16#F6F9 +/Lsmall 16#F76C +/M 16#004D +/MBsquare 16#3386 +/Macron 16#F6D0 +/Macronsmall 16#F7AF +/Macute 16#1E3E +/Mcircle 16#24C2 +/Mdotaccent 16#1E40 +/Mdotbelow 16#1E42 +/Menarmenian 16#0544 +/Mmonospace 16#FF2D +/Msmall 16#F76D +/Mturned 16#019C +/Mu 16#039C +/N 16#004E +/NJ 16#01CA +/Nacute 16#0143 +/Ncaron 16#0147 +/Ncedilla 16#0145 +/Ncircle 16#24C3 +/Ncircumflexbelow 16#1E4A +/Ncommaaccent 16#0145 +/Ndotaccent 16#1E44 +/Ndotbelow 16#1E46 +/Nhookleft 16#019D +/Nineroman 16#2168 +/Nj 16#01CB +/Njecyrillic 16#040A +/Nlinebelow 16#1E48 +/Nmonospace 16#FF2E +/Nowarmenian 16#0546 +/Nsmall 16#F76E +/Ntilde 16#00D1 +/Ntildesmall 16#F7F1 +/Nu 16#039D +/O 16#004F +/OE 16#0152 +/OEsmall 16#F6FA +/Oacute 16#00D3 +/Oacutesmall 16#F7F3 +/Obarredcyrillic 16#04E8 +/Obarreddieresiscyrillic 16#04EA +/Obreve 16#014E +/Ocaron 16#01D1 +/Ocenteredtilde 16#019F +/Ocircle 16#24C4 +/Ocircumflex 16#00D4 +/Ocircumflexacute 16#1ED0 +/Ocircumflexdotbelow 16#1ED8 +/Ocircumflexgrave 16#1ED2 +/Ocircumflexhookabove 16#1ED4 +/Ocircumflexsmall 16#F7F4 +/Ocircumflextilde 16#1ED6 +/Ocyrillic 16#041E +/Odblacute 16#0150 +/Odblgrave 16#020C +/Odieresis 16#00D6 +/Odieresiscyrillic 16#04E6 +/Odieresissmall 16#F7F6 +/Odotbelow 16#1ECC +/Ogoneksmall 16#F6FB +/Ograve 16#00D2 +/Ogravesmall 16#F7F2 +/Oharmenian 16#0555 +/Ohm 16#2126 +/Ohookabove 16#1ECE +/Ohorn 16#01A0 +/Ohornacute 16#1EDA +/Ohorndotbelow 16#1EE2 +/Ohorngrave 16#1EDC +/Ohornhookabove 16#1EDE +/Ohorntilde 16#1EE0 +/Ohungarumlaut 16#0150 +/Oi 16#01A2 +/Oinvertedbreve 16#020E +/Omacron 16#014C +/Omacronacute 16#1E52 +/Omacrongrave 16#1E50 +/Omega 16#2126 +/Omegacyrillic 16#0460 +/Omegagreek 16#03A9 +/Omegaroundcyrillic 16#047A +/Omegatitlocyrillic 16#047C +/Omegatonos 16#038F +/Omicron 16#039F +/Omicrontonos 16#038C +/Omonospace 16#FF2F +/Oneroman 16#2160 +/Oogonek 16#01EA +/Oogonekmacron 16#01EC +/Oopen 16#0186 +/Oslash 16#00D8 +/Oslashacute 16#01FE +/Oslashsmall 16#F7F8 +/Osmall 16#F76F +/Ostrokeacute 16#01FE +/Otcyrillic 16#047E +/Otilde 16#00D5 +/Otildeacute 16#1E4C +/Otildedieresis 16#1E4E +/Otildesmall 16#F7F5 +/P 16#0050 +/Pacute 16#1E54 +/Pcircle 16#24C5 +/Pdotaccent 16#1E56 +/Pecyrillic 16#041F +/Peharmenian 16#054A +/Pemiddlehookcyrillic 16#04A6 +/Phi 16#03A6 +/Phook 16#01A4 +/Pi 16#03A0 +/Piwrarmenian 16#0553 +/Pmonospace 16#FF30 +/Psi 16#03A8 +/Psicyrillic 16#0470 +/Psmall 16#F770 +/Q 16#0051 +/Qcircle 16#24C6 +/Qmonospace 16#FF31 +/Qsmall 16#F771 +/R 16#0052 +/Raarmenian 16#054C +/Racute 16#0154 +/Rcaron 16#0158 +/Rcedilla 16#0156 +/Rcircle 16#24C7 +/Rcommaaccent 16#0156 +/Rdblgrave 16#0210 +/Rdotaccent 16#1E58 +/Rdotbelow 16#1E5A +/Rdotbelowmacron 16#1E5C +/Reharmenian 16#0550 +/Rfraktur 16#211C +/Rho 16#03A1 +/Ringsmall 16#F6FC +/Rinvertedbreve 16#0212 +/Rlinebelow 16#1E5E +/Rmonospace 16#FF32 +/Rsmall 16#F772 +/Rsmallinverted 16#0281 +/Rsmallinvertedsuperior 16#02B6 +/S 16#0053 +/SF010000 16#250C +/SF020000 16#2514 +/SF030000 16#2510 +/SF040000 16#2518 +/SF050000 16#253C +/SF060000 16#252C +/SF070000 16#2534 +/SF080000 16#251C +/SF090000 16#2524 +/SF100000 16#2500 +/SF110000 16#2502 +/SF190000 16#2561 +/SF200000 16#2562 +/SF210000 16#2556 +/SF220000 16#2555 +/SF230000 16#2563 +/SF240000 16#2551 +/SF250000 16#2557 +/SF260000 16#255D +/SF270000 16#255C +/SF280000 16#255B +/SF360000 16#255E +/SF370000 16#255F +/SF380000 16#255A +/SF390000 16#2554 +/SF400000 16#2569 +/SF410000 16#2566 +/SF420000 16#2560 +/SF430000 16#2550 +/SF440000 16#256C +/SF450000 16#2567 +/SF460000 16#2568 +/SF470000 16#2564 +/SF480000 16#2565 +/SF490000 16#2559 +/SF500000 16#2558 +/SF510000 16#2552 +/SF520000 16#2553 +/SF530000 16#256B +/SF540000 16#256A +/Sacute 16#015A +/Sacutedotaccent 16#1E64 +/Sampigreek 16#03E0 +/Scaron 16#0160 +/Scarondotaccent 16#1E66 +/Scaronsmall 16#F6FD +/Scedilla 16#015E +/Schwa 16#018F +/Schwacyrillic 16#04D8 +/Schwadieresiscyrillic 16#04DA +/Scircle 16#24C8 +/Scircumflex 16#015C +/Scommaaccent 16#0218 +/Sdotaccent 16#1E60 +/Sdotbelow 16#1E62 +/Sdotbelowdotaccent 16#1E68 +/Seharmenian 16#054D +/Sevenroman 16#2166 +/Shaarmenian 16#0547 +/Shacyrillic 16#0428 +/Shchacyrillic 16#0429 +/Sheicoptic 16#03E2 +/Shhacyrillic 16#04BA +/Shimacoptic 16#03EC +/Sigma 16#03A3 +/Sixroman 16#2165 +/Smonospace 16#FF33 +/Softsigncyrillic 16#042C +/Ssmall 16#F773 +/Stigmagreek 16#03DA +/T 16#0054 +/Tau 16#03A4 +/Tbar 16#0166 +/Tcaron 16#0164 +/Tcedilla 16#0162 +/Tcircle 16#24C9 +/Tcircumflexbelow 16#1E70 +/Tcommaaccent 16#0162 +/Tdotaccent 16#1E6A +/Tdotbelow 16#1E6C +/Tecyrillic 16#0422 +/Tedescendercyrillic 16#04AC +/Tenroman 16#2169 +/Tetsecyrillic 16#04B4 +/Theta 16#0398 +/Thook 16#01AC +/Thorn 16#00DE +/Thornsmall 16#F7FE +/Threeroman 16#2162 +/Tildesmall 16#F6FE +/Tiwnarmenian 16#054F +/Tlinebelow 16#1E6E +/Tmonospace 16#FF34 +/Toarmenian 16#0539 +/Tonefive 16#01BC +/Tonesix 16#0184 +/Tonetwo 16#01A7 +/Tretroflexhook 16#01AE +/Tsecyrillic 16#0426 +/Tshecyrillic 16#040B +/Tsmall 16#F774 +/Twelveroman 16#216B +/Tworoman 16#2161 +/U 16#0055 +/Uacute 16#00DA +/Uacutesmall 16#F7FA +/Ubreve 16#016C +/Ucaron 16#01D3 +/Ucircle 16#24CA +/Ucircumflex 16#00DB +/Ucircumflexbelow 16#1E76 +/Ucircumflexsmall 16#F7FB +/Ucyrillic 16#0423 +/Udblacute 16#0170 +/Udblgrave 16#0214 +/Udieresis 16#00DC +/Udieresisacute 16#01D7 +/Udieresisbelow 16#1E72 +/Udieresiscaron 16#01D9 +/Udieresiscyrillic 16#04F0 +/Udieresisgrave 16#01DB +/Udieresismacron 16#01D5 +/Udieresissmall 16#F7FC +/Udotbelow 16#1EE4 +/Ugrave 16#00D9 +/Ugravesmall 16#F7F9 +/Uhookabove 16#1EE6 +/Uhorn 16#01AF +/Uhornacute 16#1EE8 +/Uhorndotbelow 16#1EF0 +/Uhorngrave 16#1EEA +/Uhornhookabove 16#1EEC +/Uhorntilde 16#1EEE +/Uhungarumlaut 16#0170 +/Uhungarumlautcyrillic 16#04F2 +/Uinvertedbreve 16#0216 +/Ukcyrillic 16#0478 +/Umacron 16#016A +/Umacroncyrillic 16#04EE +/Umacrondieresis 16#1E7A +/Umonospace 16#FF35 +/Uogonek 16#0172 +/Upsilon 16#03A5 +/Upsilon1 16#03D2 +/Upsilonacutehooksymbolgreek 16#03D3 +/Upsilonafrican 16#01B1 +/Upsilondieresis 16#03AB +/Upsilondieresishooksymbolgreek 16#03D4 +/Upsilonhooksymbol 16#03D2 +/Upsilontonos 16#038E +/Uring 16#016E +/Ushortcyrillic 16#040E +/Usmall 16#F775 +/Ustraightcyrillic 16#04AE +/Ustraightstrokecyrillic 16#04B0 +/Utilde 16#0168 +/Utildeacute 16#1E78 +/Utildebelow 16#1E74 +/V 16#0056 +/Vcircle 16#24CB +/Vdotbelow 16#1E7E +/Vecyrillic 16#0412 +/Vewarmenian 16#054E +/Vhook 16#01B2 +/Vmonospace 16#FF36 +/Voarmenian 16#0548 +/Vsmall 16#F776 +/Vtilde 16#1E7C +/W 16#0057 +/Wacute 16#1E82 +/Wcircle 16#24CC +/Wcircumflex 16#0174 +/Wdieresis 16#1E84 +/Wdotaccent 16#1E86 +/Wdotbelow 16#1E88 +/Wgrave 16#1E80 +/Wmonospace 16#FF37 +/Wsmall 16#F777 +/X 16#0058 +/Xcircle 16#24CD +/Xdieresis 16#1E8C +/Xdotaccent 16#1E8A +/Xeharmenian 16#053D +/Xi 16#039E +/Xmonospace 16#FF38 +/Xsmall 16#F778 +/Y 16#0059 +/Yacute 16#00DD +/Yacutesmall 16#F7FD +/Yatcyrillic 16#0462 +/Ycircle 16#24CE +/Ycircumflex 16#0176 +/Ydieresis 16#0178 +/Ydieresissmall 16#F7FF +/Ydotaccent 16#1E8E +/Ydotbelow 16#1EF4 +/Yericyrillic 16#042B +/Yerudieresiscyrillic 16#04F8 +/Ygrave 16#1EF2 +/Yhook 16#01B3 +/Yhookabove 16#1EF6 +/Yiarmenian 16#0545 +/Yicyrillic 16#0407 +/Yiwnarmenian 16#0552 +/Ymonospace 16#FF39 +/Ysmall 16#F779 +/Ytilde 16#1EF8 +/Yusbigcyrillic 16#046A +/Yusbigiotifiedcyrillic 16#046C +/Yuslittlecyrillic 16#0466 +/Yuslittleiotifiedcyrillic 16#0468 +/Z 16#005A +/Zaarmenian 16#0536 +/Zacute 16#0179 +/Zcaron 16#017D +/Zcaronsmall 16#F6FF +/Zcircle 16#24CF +/Zcircumflex 16#1E90 +/Zdot 16#017B +/Zdotaccent 16#017B +/Zdotbelow 16#1E92 +/Zecyrillic 16#0417 +/Zedescendercyrillic 16#0498 +/Zedieresiscyrillic 16#04DE +/Zeta 16#0396 +/Zhearmenian 16#053A +/Zhebrevecyrillic 16#04C1 +/Zhecyrillic 16#0416 +/Zhedescendercyrillic 16#0496 +/Zhedieresiscyrillic 16#04DC +/Zlinebelow 16#1E94 +/Zmonospace 16#FF3A +/Zsmall 16#F77A +/Zstroke 16#01B5 +/a 16#0061 +/aabengali 16#0986 +/aacute 16#00E1 +/aadeva 16#0906 +/aagujarati 16#0A86 +/aagurmukhi 16#0A06 +/aamatragurmukhi 16#0A3E +/aarusquare 16#3303 +/aavowelsignbengali 16#09BE +/aavowelsigndeva 16#093E +/aavowelsigngujarati 16#0ABE +/abbreviationmarkarmenian 16#055F +/abbreviationsigndeva 16#0970 +/abengali 16#0985 +/abopomofo 16#311A +/abreve 16#0103 +/abreveacute 16#1EAF +/abrevecyrillic 16#04D1 +/abrevedotbelow 16#1EB7 +/abrevegrave 16#1EB1 +/abrevehookabove 16#1EB3 +/abrevetilde 16#1EB5 +/acaron 16#01CE +/acircle 16#24D0 +/acircumflex 16#00E2 +/acircumflexacute 16#1EA5 +/acircumflexdotbelow 16#1EAD +/acircumflexgrave 16#1EA7 +/acircumflexhookabove 16#1EA9 +/acircumflextilde 16#1EAB +/acute 16#00B4 +/acutebelowcmb 16#0317 +/acutecmb 16#0301 +/acutecomb 16#0301 +/acutedeva 16#0954 +/acutelowmod 16#02CF +/acutetonecmb 16#0341 +/acyrillic 16#0430 +/adblgrave 16#0201 +/addakgurmukhi 16#0A71 +/adeva 16#0905 +/adieresis 16#00E4 +/adieresiscyrillic 16#04D3 +/adieresismacron 16#01DF +/adotbelow 16#1EA1 +/adotmacron 16#01E1 +/ae 16#00E6 +/aeacute 16#01FD +/aekorean 16#3150 +/aemacron 16#01E3 +/afii00208 16#2015 +/afii08941 16#20A4 +/afii10017 16#0410 +/afii10018 16#0411 +/afii10019 16#0412 +/afii10020 16#0413 +/afii10021 16#0414 +/afii10022 16#0415 +/afii10023 16#0401 +/afii10024 16#0416 +/afii10025 16#0417 +/afii10026 16#0418 +/afii10027 16#0419 +/afii10028 16#041A +/afii10029 16#041B +/afii10030 16#041C +/afii10031 16#041D +/afii10032 16#041E +/afii10033 16#041F +/afii10034 16#0420 +/afii10035 16#0421 +/afii10036 16#0422 +/afii10037 16#0423 +/afii10038 16#0424 +/afii10039 16#0425 +/afii10040 16#0426 +/afii10041 16#0427 +/afii10042 16#0428 +/afii10043 16#0429 +/afii10044 16#042A +/afii10045 16#042B +/afii10046 16#042C +/afii10047 16#042D +/afii10048 16#042E +/afii10049 16#042F +/afii10050 16#0490 +/afii10051 16#0402 +/afii10052 16#0403 +/afii10053 16#0404 +/afii10054 16#0405 +/afii10055 16#0406 +/afii10056 16#0407 +/afii10057 16#0408 +/afii10058 16#0409 +/afii10059 16#040A +/afii10060 16#040B +/afii10061 16#040C +/afii10062 16#040E +/afii10063 16#F6C4 +/afii10064 16#F6C5 +/afii10065 16#0430 +/afii10066 16#0431 +/afii10067 16#0432 +/afii10068 16#0433 +/afii10069 16#0434 +/afii10070 16#0435 +/afii10071 16#0451 +/afii10072 16#0436 +/afii10073 16#0437 +/afii10074 16#0438 +/afii10075 16#0439 +/afii10076 16#043A +/afii10077 16#043B +/afii10078 16#043C +/afii10079 16#043D +/afii10080 16#043E +/afii10081 16#043F +/afii10082 16#0440 +/afii10083 16#0441 +/afii10084 16#0442 +/afii10085 16#0443 +/afii10086 16#0444 +/afii10087 16#0445 +/afii10088 16#0446 +/afii10089 16#0447 +/afii10090 16#0448 +/afii10091 16#0449 +/afii10092 16#044A +/afii10093 16#044B +/afii10094 16#044C +/afii10095 16#044D +/afii10096 16#044E +/afii10097 16#044F +/afii10098 16#0491 +/afii10099 16#0452 +/afii10100 16#0453 +/afii10101 16#0454 +/afii10102 16#0455 +/afii10103 16#0456 +/afii10104 16#0457 +/afii10105 16#0458 +/afii10106 16#0459 +/afii10107 16#045A +/afii10108 16#045B +/afii10109 16#045C +/afii10110 16#045E +/afii10145 16#040F +/afii10146 16#0462 +/afii10147 16#0472 +/afii10148 16#0474 +/afii10192 16#F6C6 +/afii10193 16#045F +/afii10194 16#0463 +/afii10195 16#0473 +/afii10196 16#0475 +/afii10831 16#F6C7 +/afii10832 16#F6C8 +/afii10846 16#04D9 +/afii299 16#200E +/afii300 16#200F +/afii301 16#200D +/afii57381 16#066A +/afii57388 16#060C +/afii57392 16#0660 +/afii57393 16#0661 +/afii57394 16#0662 +/afii57395 16#0663 +/afii57396 16#0664 +/afii57397 16#0665 +/afii57398 16#0666 +/afii57399 16#0667 +/afii57400 16#0668 +/afii57401 16#0669 +/afii57403 16#061B +/afii57407 16#061F +/afii57409 16#0621 +/afii57410 16#0622 +/afii57411 16#0623 +/afii57412 16#0624 +/afii57413 16#0625 +/afii57414 16#0626 +/afii57415 16#0627 +/afii57416 16#0628 +/afii57417 16#0629 +/afii57418 16#062A +/afii57419 16#062B +/afii57420 16#062C +/afii57421 16#062D +/afii57422 16#062E +/afii57423 16#062F +/afii57424 16#0630 +/afii57425 16#0631 +/afii57426 16#0632 +/afii57427 16#0633 +/afii57428 16#0634 +/afii57429 16#0635 +/afii57430 16#0636 +/afii57431 16#0637 +/afii57432 16#0638 +/afii57433 16#0639 +/afii57434 16#063A +/afii57440 16#0640 +/afii57441 16#0641 +/afii57442 16#0642 +/afii57443 16#0643 +/afii57444 16#0644 +/afii57445 16#0645 +/afii57446 16#0646 +/afii57448 16#0648 +/afii57449 16#0649 +/afii57450 16#064A +/afii57451 16#064B +/afii57452 16#064C +/afii57453 16#064D +/afii57454 16#064E +/afii57455 16#064F +/afii57456 16#0650 +/afii57457 16#0651 +/afii57458 16#0652 +/afii57470 16#0647 +/afii57505 16#06A4 +/afii57506 16#067E +/afii57507 16#0686 +/afii57508 16#0698 +/afii57509 16#06AF +/afii57511 16#0679 +/afii57512 16#0688 +/afii57513 16#0691 +/afii57514 16#06BA +/afii57519 16#06D2 +/afii57534 16#06D5 +/afii57636 16#20AA +/afii57645 16#05BE +/afii57658 16#05C3 +/afii57664 16#05D0 +/afii57665 16#05D1 +/afii57666 16#05D2 +/afii57667 16#05D3 +/afii57668 16#05D4 +/afii57669 16#05D5 +/afii57670 16#05D6 +/afii57671 16#05D7 +/afii57672 16#05D8 +/afii57673 16#05D9 +/afii57674 16#05DA +/afii57675 16#05DB +/afii57676 16#05DC +/afii57677 16#05DD +/afii57678 16#05DE +/afii57679 16#05DF +/afii57680 16#05E0 +/afii57681 16#05E1 +/afii57682 16#05E2 +/afii57683 16#05E3 +/afii57684 16#05E4 +/afii57685 16#05E5 +/afii57686 16#05E6 +/afii57687 16#05E7 +/afii57688 16#05E8 +/afii57689 16#05E9 +/afii57690 16#05EA +/afii57694 16#FB2A +/afii57695 16#FB2B +/afii57700 16#FB4B +/afii57705 16#FB1F +/afii57716 16#05F0 +/afii57717 16#05F1 +/afii57718 16#05F2 +/afii57723 16#FB35 +/afii57793 16#05B4 +/afii57794 16#05B5 +/afii57795 16#05B6 +/afii57796 16#05BB +/afii57797 16#05B8 +/afii57798 16#05B7 +/afii57799 16#05B0 +/afii57800 16#05B2 +/afii57801 16#05B1 +/afii57802 16#05B3 +/afii57803 16#05C2 +/afii57804 16#05C1 +/afii57806 16#05B9 +/afii57807 16#05BC +/afii57839 16#05BD +/afii57841 16#05BF +/afii57842 16#05C0 +/afii57929 16#02BC +/afii61248 16#2105 +/afii61289 16#2113 +/afii61352 16#2116 +/afii61573 16#202C +/afii61574 16#202D +/afii61575 16#202E +/afii61664 16#200C +/afii63167 16#066D +/afii64937 16#02BD +/agrave 16#00E0 +/agujarati 16#0A85 +/agurmukhi 16#0A05 +/ahiragana 16#3042 +/ahookabove 16#1EA3 +/aibengali 16#0990 +/aibopomofo 16#311E +/aideva 16#0910 +/aiecyrillic 16#04D5 +/aigujarati 16#0A90 +/aigurmukhi 16#0A10 +/aimatragurmukhi 16#0A48 +/ainarabic 16#0639 +/ainfinalarabic 16#FECA +/aininitialarabic 16#FECB +/ainmedialarabic 16#FECC +/ainvertedbreve 16#0203 +/aivowelsignbengali 16#09C8 +/aivowelsigndeva 16#0948 +/aivowelsigngujarati 16#0AC8 +/akatakana 16#30A2 +/akatakanahalfwidth 16#FF71 +/akorean 16#314F +/alef 16#05D0 +/alefarabic 16#0627 +/alefdageshhebrew 16#FB30 +/aleffinalarabic 16#FE8E +/alefhamzaabovearabic 16#0623 +/alefhamzaabovefinalarabic 16#FE84 +/alefhamzabelowarabic 16#0625 +/alefhamzabelowfinalarabic 16#FE88 +/alefhebrew 16#05D0 +/aleflamedhebrew 16#FB4F +/alefmaddaabovearabic 16#0622 +/alefmaddaabovefinalarabic 16#FE82 +/alefmaksuraarabic 16#0649 +/alefmaksurafinalarabic 16#FEF0 +/alefmaksurainitialarabic 16#FEF3 +/alefmaksuramedialarabic 16#FEF4 +/alefpatahhebrew 16#FB2E +/alefqamatshebrew 16#FB2F +/aleph 16#2135 +/allequal 16#224C +/alpha 16#03B1 +/alphatonos 16#03AC +/amacron 16#0101 +/amonospace 16#FF41 +/ampersand 16#0026 +/ampersandmonospace 16#FF06 +/ampersandsmall 16#F726 +/amsquare 16#33C2 +/anbopomofo 16#3122 +/angbopomofo 16#3124 +/angkhankhuthai 16#0E5A +/angle 16#2220 +/anglebracketleft 16#3008 +/anglebracketleftvertical 16#FE3F +/anglebracketright 16#3009 +/anglebracketrightvertical 16#FE40 +/angleleft 16#2329 +/angleright 16#232A +/angstrom 16#212B +/anoteleia 16#0387 +/anudattadeva 16#0952 +/anusvarabengali 16#0982 +/anusvaradeva 16#0902 +/anusvaragujarati 16#0A82 +/aogonek 16#0105 +/apaatosquare 16#3300 +/aparen 16#249C +/apostrophearmenian 16#055A +/apostrophemod 16#02BC +/apple 16#F8FF +/approaches 16#2250 +/approxequal 16#2248 +/approxequalorimage 16#2252 +/approximatelyequal 16#2245 +/araeaekorean 16#318E +/araeakorean 16#318D +/arc 16#2312 +/arighthalfring 16#1E9A +/aring 16#00E5 +/aringacute 16#01FB +/aringbelow 16#1E01 +/arrowboth 16#2194 +/arrowdashdown 16#21E3 +/arrowdashleft 16#21E0 +/arrowdashright 16#21E2 +/arrowdashup 16#21E1 +/arrowdblboth 16#21D4 +/arrowdbldown 16#21D3 +/arrowdblleft 16#21D0 +/arrowdblright 16#21D2 +/arrowdblup 16#21D1 +/arrowdown 16#2193 +/arrowdownleft 16#2199 +/arrowdownright 16#2198 +/arrowdownwhite 16#21E9 +/arrowheaddownmod 16#02C5 +/arrowheadleftmod 16#02C2 +/arrowheadrightmod 16#02C3 +/arrowheadupmod 16#02C4 +/arrowhorizex 16#F8E7 +/arrowleft 16#2190 +/arrowleftdbl 16#21D0 +/arrowleftdblstroke 16#21CD +/arrowleftoverright 16#21C6 +/arrowleftwhite 16#21E6 +/arrowright 16#2192 +/arrowrightdblstroke 16#21CF +/arrowrightheavy 16#279E +/arrowrightoverleft 16#21C4 +/arrowrightwhite 16#21E8 +/arrowtableft 16#21E4 +/arrowtabright 16#21E5 +/arrowup 16#2191 +/arrowupdn 16#2195 +/arrowupdnbse 16#21A8 +/arrowupdownbase 16#21A8 +/arrowupleft 16#2196 +/arrowupleftofdown 16#21C5 +/arrowupright 16#2197 +/arrowupwhite 16#21E7 +/arrowvertex 16#F8E6 +/asciicircum 16#005E +/asciicircummonospace 16#FF3E +/asciitilde 16#007E +/asciitildemonospace 16#FF5E +/ascript 16#0251 +/ascriptturned 16#0252 +/asmallhiragana 16#3041 +/asmallkatakana 16#30A1 +/asmallkatakanahalfwidth 16#FF67 +/asterisk 16#002A +/asteriskaltonearabic 16#066D +/asteriskarabic 16#066D +/asteriskmath 16#2217 +/asteriskmonospace 16#FF0A +/asterisksmall 16#FE61 +/asterism 16#2042 +/asuperior 16#F6E9 +/asymptoticallyequal 16#2243 +/at 16#0040 +/atilde 16#00E3 +/atmonospace 16#FF20 +/atsmall 16#FE6B +/aturned 16#0250 +/aubengali 16#0994 +/aubopomofo 16#3120 +/audeva 16#0914 +/augujarati 16#0A94 +/augurmukhi 16#0A14 +/aulengthmarkbengali 16#09D7 +/aumatragurmukhi 16#0A4C +/auvowelsignbengali 16#09CC +/auvowelsigndeva 16#094C +/auvowelsigngujarati 16#0ACC +/avagrahadeva 16#093D +/aybarmenian 16#0561 +/ayin 16#05E2 +/ayinaltonehebrew 16#FB20 +/ayinhebrew 16#05E2 +/b 16#0062 +/babengali 16#09AC +/backslash 16#005C +/backslashmonospace 16#FF3C +/badeva 16#092C +/bagujarati 16#0AAC +/bagurmukhi 16#0A2C +/bahiragana 16#3070 +/bahtthai 16#0E3F +/bakatakana 16#30D0 +/bar 16#007C +/barmonospace 16#FF5C +/bbopomofo 16#3105 +/bcircle 16#24D1 +/bdotaccent 16#1E03 +/bdotbelow 16#1E05 +/beamedsixteenthnotes 16#266C +/because 16#2235 +/becyrillic 16#0431 +/beharabic 16#0628 +/behfinalarabic 16#FE90 +/behinitialarabic 16#FE91 +/behiragana 16#3079 +/behmedialarabic 16#FE92 +/behmeeminitialarabic 16#FC9F +/behmeemisolatedarabic 16#FC08 +/behnoonfinalarabic 16#FC6D +/bekatakana 16#30D9 +/benarmenian 16#0562 +/bet 16#05D1 +/beta 16#03B2 +/betasymbolgreek 16#03D0 +/betdagesh 16#FB31 +/betdageshhebrew 16#FB31 +/bethebrew 16#05D1 +/betrafehebrew 16#FB4C +/bhabengali 16#09AD +/bhadeva 16#092D +/bhagujarati 16#0AAD +/bhagurmukhi 16#0A2D +/bhook 16#0253 +/bihiragana 16#3073 +/bikatakana 16#30D3 +/bilabialclick 16#0298 +/bindigurmukhi 16#0A02 +/birusquare 16#3331 +/blackcircle 16#25CF +/blackdiamond 16#25C6 +/blackdownpointingtriangle 16#25BC +/blackleftpointingpointer 16#25C4 +/blackleftpointingtriangle 16#25C0 +/blacklenticularbracketleft 16#3010 +/blacklenticularbracketleftvertical 16#FE3B +/blacklenticularbracketright 16#3011 +/blacklenticularbracketrightvertical 16#FE3C +/blacklowerlefttriangle 16#25E3 +/blacklowerrighttriangle 16#25E2 +/blackrectangle 16#25AC +/blackrightpointingpointer 16#25BA +/blackrightpointingtriangle 16#25B6 +/blacksmallsquare 16#25AA +/blacksmilingface 16#263B +/blacksquare 16#25A0 +/blackstar 16#2605 +/blackupperlefttriangle 16#25E4 +/blackupperrighttriangle 16#25E5 +/blackuppointingsmalltriangle 16#25B4 +/blackuppointingtriangle 16#25B2 +/blank 16#2423 +/blinebelow 16#1E07 +/block 16#2588 +/bmonospace 16#FF42 +/bobaimaithai 16#0E1A +/bohiragana 16#307C +/bokatakana 16#30DC +/bparen 16#249D +/bqsquare 16#33C3 +/braceex 16#F8F4 +/braceleft 16#007B +/braceleftbt 16#F8F3 +/braceleftmid 16#F8F2 +/braceleftmonospace 16#FF5B +/braceleftsmall 16#FE5B +/bracelefttp 16#F8F1 +/braceleftvertical 16#FE37 +/braceright 16#007D +/bracerightbt 16#F8FE +/bracerightmid 16#F8FD +/bracerightmonospace 16#FF5D +/bracerightsmall 16#FE5C +/bracerighttp 16#F8FC +/bracerightvertical 16#FE38 +/bracketleft 16#005B +/bracketleftbt 16#F8F0 +/bracketleftex 16#F8EF +/bracketleftmonospace 16#FF3B +/bracketlefttp 16#F8EE +/bracketright 16#005D +/bracketrightbt 16#F8FB +/bracketrightex 16#F8FA +/bracketrightmonospace 16#FF3D +/bracketrighttp 16#F8F9 +/breve 16#02D8 +/brevebelowcmb 16#032E +/brevecmb 16#0306 +/breveinvertedbelowcmb 16#032F +/breveinvertedcmb 16#0311 +/breveinverteddoublecmb 16#0361 +/bridgebelowcmb 16#032A +/bridgeinvertedbelowcmb 16#033A +/brokenbar 16#00A6 +/bstroke 16#0180 +/bsuperior 16#F6EA +/btopbar 16#0183 +/buhiragana 16#3076 +/bukatakana 16#30D6 +/bullet 16#2022 +/bulletinverse 16#25D8 +/bulletoperator 16#2219 +/bullseye 16#25CE +/c 16#0063 +/caarmenian 16#056E +/cabengali 16#099A +/cacute 16#0107 +/cadeva 16#091A +/cagujarati 16#0A9A +/cagurmukhi 16#0A1A +/calsquare 16#3388 +/candrabindubengali 16#0981 +/candrabinducmb 16#0310 +/candrabindudeva 16#0901 +/candrabindugujarati 16#0A81 +/capslock 16#21EA +/careof 16#2105 +/caron 16#02C7 +/caronbelowcmb 16#032C +/caroncmb 16#030C +/carriagereturn 16#21B5 +/cbopomofo 16#3118 +/ccaron 16#010D +/ccedilla 16#00E7 +/ccedillaacute 16#1E09 +/ccircle 16#24D2 +/ccircumflex 16#0109 +/ccurl 16#0255 +/cdot 16#010B +/cdotaccent 16#010B +/cdsquare 16#33C5 +/cedilla 16#00B8 +/cedillacmb 16#0327 +/cent 16#00A2 +/centigrade 16#2103 +/centinferior 16#F6DF +/centmonospace 16#FFE0 +/centoldstyle 16#F7A2 +/centsuperior 16#F6E0 +/chaarmenian 16#0579 +/chabengali 16#099B +/chadeva 16#091B +/chagujarati 16#0A9B +/chagurmukhi 16#0A1B +/chbopomofo 16#3114 +/cheabkhasiancyrillic 16#04BD +/checkmark 16#2713 +/checyrillic 16#0447 +/chedescenderabkhasiancyrillic 16#04BF +/chedescendercyrillic 16#04B7 +/chedieresiscyrillic 16#04F5 +/cheharmenian 16#0573 +/chekhakassiancyrillic 16#04CC +/cheverticalstrokecyrillic 16#04B9 +/chi 16#03C7 +/chieuchacirclekorean 16#3277 +/chieuchaparenkorean 16#3217 +/chieuchcirclekorean 16#3269 +/chieuchkorean 16#314A +/chieuchparenkorean 16#3209 +/chochangthai 16#0E0A +/chochanthai 16#0E08 +/chochingthai 16#0E09 +/chochoethai 16#0E0C +/chook 16#0188 +/cieucacirclekorean 16#3276 +/cieucaparenkorean 16#3216 +/cieuccirclekorean 16#3268 +/cieuckorean 16#3148 +/cieucparenkorean 16#3208 +/cieucuparenkorean 16#321C +/circle 16#25CB +/circlemultiply 16#2297 +/circleot 16#2299 +/circleplus 16#2295 +/circlepostalmark 16#3036 +/circlewithlefthalfblack 16#25D0 +/circlewithrighthalfblack 16#25D1 +/circumflex 16#02C6 +/circumflexbelowcmb 16#032D +/circumflexcmb 16#0302 +/clear 16#2327 +/clickalveolar 16#01C2 +/clickdental 16#01C0 +/clicklateral 16#01C1 +/clickretroflex 16#01C3 +/club 16#2663 +/clubsuitblack 16#2663 +/clubsuitwhite 16#2667 +/cmcubedsquare 16#33A4 +/cmonospace 16#FF43 +/cmsquaredsquare 16#33A0 +/coarmenian 16#0581 +/colon 16#003A +/colonmonetary 16#20A1 +/colonmonospace 16#FF1A +/colonsign 16#20A1 +/colonsmall 16#FE55 +/colontriangularhalfmod 16#02D1 +/colontriangularmod 16#02D0 +/comma 16#002C +/commaabovecmb 16#0313 +/commaaboverightcmb 16#0315 +/commaaccent 16#F6C3 +/commaarabic 16#060C +/commaarmenian 16#055D +/commainferior 16#F6E1 +/commamonospace 16#FF0C +/commareversedabovecmb 16#0314 +/commareversedmod 16#02BD +/commasmall 16#FE50 +/commasuperior 16#F6E2 +/commaturnedabovecmb 16#0312 +/commaturnedmod 16#02BB +/compass 16#263C +/congruent 16#2245 +/contourintegral 16#222E +/control 16#2303 +/controlACK 16#0006 +/controlBEL 16#0007 +/controlBS 16#0008 +/controlCAN 16#0018 +/controlCR 16#000D +/controlDC1 16#0011 +/controlDC2 16#0012 +/controlDC3 16#0013 +/controlDC4 16#0014 +/controlDEL 16#007F +/controlDLE 16#0010 +/controlEM 16#0019 +/controlENQ 16#0005 +/controlEOT 16#0004 +/controlESC 16#001B +/controlETB 16#0017 +/controlETX 16#0003 +/controlFF 16#000C +/controlFS 16#001C +/controlGS 16#001D +/controlHT 16#0009 +/controlLF 16#000A +/controlNAK 16#0015 +/controlRS 16#001E +/controlSI 16#000F +/controlSO 16#000E +/controlSOT 16#0002 +/controlSTX 16#0001 +/controlSUB 16#001A +/controlSYN 16#0016 +/controlUS 16#001F +/controlVT 16#000B +/copyright 16#00A9 +/copyrightsans 16#F8E9 +/copyrightserif 16#F6D9 +/cornerbracketleft 16#300C +/cornerbracketlefthalfwidth 16#FF62 +/cornerbracketleftvertical 16#FE41 +/cornerbracketright 16#300D +/cornerbracketrighthalfwidth 16#FF63 +/cornerbracketrightvertical 16#FE42 +/corporationsquare 16#337F +/cosquare 16#33C7 +/coverkgsquare 16#33C6 +/cparen 16#249E +/cruzeiro 16#20A2 +/cstretched 16#0297 +/curlyand 16#22CF +/curlyor 16#22CE +/currency 16#00A4 +/cyrBreve 16#F6D1 +/cyrFlex 16#F6D2 +/cyrbreve 16#F6D4 +/cyrflex 16#F6D5 +/d 16#0064 +/daarmenian 16#0564 +/dabengali 16#09A6 +/dadarabic 16#0636 +/dadeva 16#0926 +/dadfinalarabic 16#FEBE +/dadinitialarabic 16#FEBF +/dadmedialarabic 16#FEC0 +/dagesh 16#05BC +/dageshhebrew 16#05BC +/dagger 16#2020 +/daggerdbl 16#2021 +/dagujarati 16#0AA6 +/dagurmukhi 16#0A26 +/dahiragana 16#3060 +/dakatakana 16#30C0 +/dalarabic 16#062F +/dalet 16#05D3 +/daletdagesh 16#FB33 +/daletdageshhebrew 16#FB33 +% /dalethatafpatah 16#05D3 16#05B2 +% /dalethatafpatahhebrew 16#05D3 16#05B2 +% /dalethatafsegol 16#05D3 16#05B1 +% /dalethatafsegolhebrew 16#05D3 16#05B1 +/dalethebrew 16#05D3 +% /dalethiriq 16#05D3 16#05B4 +% /dalethiriqhebrew 16#05D3 16#05B4 +% /daletholam 16#05D3 16#05B9 +% /daletholamhebrew 16#05D3 16#05B9 +% /daletpatah 16#05D3 16#05B7 +% /daletpatahhebrew 16#05D3 16#05B7 +% /daletqamats 16#05D3 16#05B8 +% /daletqamatshebrew 16#05D3 16#05B8 +% /daletqubuts 16#05D3 16#05BB +% /daletqubutshebrew 16#05D3 16#05BB +% /daletsegol 16#05D3 16#05B6 +% /daletsegolhebrew 16#05D3 16#05B6 +% /daletsheva 16#05D3 16#05B0 +% /daletshevahebrew 16#05D3 16#05B0 +% /dalettsere 16#05D3 16#05B5 +% /dalettserehebrew 16#05D3 16#05B5 +/dalfinalarabic 16#FEAA +/dammaarabic 16#064F +/dammalowarabic 16#064F +/dammatanaltonearabic 16#064C +/dammatanarabic 16#064C +/danda 16#0964 +/dargahebrew 16#05A7 +/dargalefthebrew 16#05A7 +/dasiapneumatacyrilliccmb 16#0485 +/dblGrave 16#F6D3 +/dblanglebracketleft 16#300A +/dblanglebracketleftvertical 16#FE3D +/dblanglebracketright 16#300B +/dblanglebracketrightvertical 16#FE3E +/dblarchinvertedbelowcmb 16#032B +/dblarrowleft 16#21D4 +/dblarrowright 16#21D2 +/dbldanda 16#0965 +/dblgrave 16#F6D6 +/dblgravecmb 16#030F +/dblintegral 16#222C +/dbllowline 16#2017 +/dbllowlinecmb 16#0333 +/dbloverlinecmb 16#033F +/dblprimemod 16#02BA +/dblverticalbar 16#2016 +/dblverticallineabovecmb 16#030E +/dbopomofo 16#3109 +/dbsquare 16#33C8 +/dcaron 16#010F +/dcedilla 16#1E11 +/dcircle 16#24D3 +/dcircumflexbelow 16#1E13 +/dcroat 16#0111 +/ddabengali 16#09A1 +/ddadeva 16#0921 +/ddagujarati 16#0AA1 +/ddagurmukhi 16#0A21 +/ddalarabic 16#0688 +/ddalfinalarabic 16#FB89 +/dddhadeva 16#095C +/ddhabengali 16#09A2 +/ddhadeva 16#0922 +/ddhagujarati 16#0AA2 +/ddhagurmukhi 16#0A22 +/ddotaccent 16#1E0B +/ddotbelow 16#1E0D +/decimalseparatorarabic 16#066B +/decimalseparatorpersian 16#066B +/decyrillic 16#0434 +/degree 16#00B0 +/dehihebrew 16#05AD +/dehiragana 16#3067 +/deicoptic 16#03EF +/dekatakana 16#30C7 +/deleteleft 16#232B +/deleteright 16#2326 +/delta 16#03B4 +/deltaturned 16#018D +/denominatorminusonenumeratorbengali 16#09F8 +/dezh 16#02A4 +/dhabengali 16#09A7 +/dhadeva 16#0927 +/dhagujarati 16#0AA7 +/dhagurmukhi 16#0A27 +/dhook 16#0257 +/dialytikatonos 16#0385 +/dialytikatonoscmb 16#0344 +/diamond 16#2666 +/diamondsuitwhite 16#2662 +/dieresis 16#00A8 +/dieresisacute 16#F6D7 +/dieresisbelowcmb 16#0324 +/dieresiscmb 16#0308 +/dieresisgrave 16#F6D8 +/dieresistonos 16#0385 +/dihiragana 16#3062 +/dikatakana 16#30C2 +/dittomark 16#3003 +/divide 16#00F7 +/divides 16#2223 +/divisionslash 16#2215 +/djecyrillic 16#0452 +/dkshade 16#2593 +/dlinebelow 16#1E0F +/dlsquare 16#3397 +/dmacron 16#0111 +/dmonospace 16#FF44 +/dnblock 16#2584 +/dochadathai 16#0E0E +/dodekthai 16#0E14 +/dohiragana 16#3069 +/dokatakana 16#30C9 +/dollar 16#0024 +/dollarinferior 16#F6E3 +/dollarmonospace 16#FF04 +/dollaroldstyle 16#F724 +/dollarsmall 16#FE69 +/dollarsuperior 16#F6E4 +/dong 16#20AB +/dorusquare 16#3326 +/dotaccent 16#02D9 +/dotaccentcmb 16#0307 +/dotbelowcmb 16#0323 +/dotbelowcomb 16#0323 +/dotkatakana 16#30FB +/dotlessi 16#0131 +/dotlessj 16#F6BE +/dotlessjstrokehook 16#0284 +/dotmath 16#22C5 +/dottedcircle 16#25CC +/doubleyodpatah 16#FB1F +/doubleyodpatahhebrew 16#FB1F +/downtackbelowcmb 16#031E +/downtackmod 16#02D5 +/dparen 16#249F +/dsuperior 16#F6EB +/dtail 16#0256 +/dtopbar 16#018C +/duhiragana 16#3065 +/dukatakana 16#30C5 +/dz 16#01F3 +/dzaltone 16#02A3 +/dzcaron 16#01C6 +/dzcurl 16#02A5 +/dzeabkhasiancyrillic 16#04E1 +/dzecyrillic 16#0455 +/dzhecyrillic 16#045F +/e 16#0065 +/eacute 16#00E9 +/earth 16#2641 +/ebengali 16#098F +/ebopomofo 16#311C +/ebreve 16#0115 +/ecandradeva 16#090D +/ecandragujarati 16#0A8D +/ecandravowelsigndeva 16#0945 +/ecandravowelsigngujarati 16#0AC5 +/ecaron 16#011B +/ecedillabreve 16#1E1D +/echarmenian 16#0565 +/echyiwnarmenian 16#0587 +/ecircle 16#24D4 +/ecircumflex 16#00EA +/ecircumflexacute 16#1EBF +/ecircumflexbelow 16#1E19 +/ecircumflexdotbelow 16#1EC7 +/ecircumflexgrave 16#1EC1 +/ecircumflexhookabove 16#1EC3 +/ecircumflextilde 16#1EC5 +/ecyrillic 16#0454 +/edblgrave 16#0205 +/edeva 16#090F +/edieresis 16#00EB +/edot 16#0117 +/edotaccent 16#0117 +/edotbelow 16#1EB9 +/eegurmukhi 16#0A0F +/eematragurmukhi 16#0A47 +/efcyrillic 16#0444 +/egrave 16#00E8 +/egujarati 16#0A8F +/eharmenian 16#0567 +/ehbopomofo 16#311D +/ehiragana 16#3048 +/ehookabove 16#1EBB +/eibopomofo 16#311F +/eight 16#0038 +/eightarabic 16#0668 +/eightbengali 16#09EE +/eightcircle 16#2467 +/eightcircleinversesansserif 16#2791 +/eightdeva 16#096E +/eighteencircle 16#2471 +/eighteenparen 16#2485 +/eighteenperiod 16#2499 +/eightgujarati 16#0AEE +/eightgurmukhi 16#0A6E +/eighthackarabic 16#0668 +/eighthangzhou 16#3028 +/eighthnotebeamed 16#266B +/eightideographicparen 16#3227 +/eightinferior 16#2088 +/eightmonospace 16#FF18 +/eightoldstyle 16#F738 +/eightparen 16#247B +/eightperiod 16#248F +/eightpersian 16#06F8 +/eightroman 16#2177 +/eightsuperior 16#2078 +/eightthai 16#0E58 +/einvertedbreve 16#0207 +/eiotifiedcyrillic 16#0465 +/ekatakana 16#30A8 +/ekatakanahalfwidth 16#FF74 +/ekonkargurmukhi 16#0A74 +/ekorean 16#3154 +/elcyrillic 16#043B +/element 16#2208 +/elevencircle 16#246A +/elevenparen 16#247E +/elevenperiod 16#2492 +/elevenroman 16#217A +/ellipsis 16#2026 +/ellipsisvertical 16#22EE +/emacron 16#0113 +/emacronacute 16#1E17 +/emacrongrave 16#1E15 +/emcyrillic 16#043C +/emdash 16#2014 +/emdashvertical 16#FE31 +/emonospace 16#FF45 +/emphasismarkarmenian 16#055B +/emptyset 16#2205 +/enbopomofo 16#3123 +/encyrillic 16#043D +/endash 16#2013 +/endashvertical 16#FE32 +/endescendercyrillic 16#04A3 +/eng 16#014B +/engbopomofo 16#3125 +/enghecyrillic 16#04A5 +/enhookcyrillic 16#04C8 +/enspace 16#2002 +/eogonek 16#0119 +/eokorean 16#3153 +/eopen 16#025B +/eopenclosed 16#029A +/eopenreversed 16#025C +/eopenreversedclosed 16#025E +/eopenreversedhook 16#025D +/eparen 16#24A0 +/epsilon 16#03B5 +/epsilontonos 16#03AD +/equal 16#003D +/equalmonospace 16#FF1D +/equalsmall 16#FE66 +/equalsuperior 16#207C +/equivalence 16#2261 +/erbopomofo 16#3126 +/ercyrillic 16#0440 +/ereversed 16#0258 +/ereversedcyrillic 16#044D +/escyrillic 16#0441 +/esdescendercyrillic 16#04AB +/esh 16#0283 +/eshcurl 16#0286 +/eshortdeva 16#090E +/eshortvowelsigndeva 16#0946 +/eshreversedloop 16#01AA +/eshsquatreversed 16#0285 +/esmallhiragana 16#3047 +/esmallkatakana 16#30A7 +/esmallkatakanahalfwidth 16#FF6A +/estimated 16#212E +/esuperior 16#F6EC +/eta 16#03B7 +/etarmenian 16#0568 +/etatonos 16#03AE +/eth 16#00F0 +/etilde 16#1EBD +/etildebelow 16#1E1B +/etnahtafoukhhebrew 16#0591 +/etnahtafoukhlefthebrew 16#0591 +/etnahtahebrew 16#0591 +/etnahtalefthebrew 16#0591 +/eturned 16#01DD +/eukorean 16#3161 +/euro 16#20AC +/evowelsignbengali 16#09C7 +/evowelsigndeva 16#0947 +/evowelsigngujarati 16#0AC7 +/exclam 16#0021 +/exclamarmenian 16#055C +/exclamdbl 16#203C +/exclamdown 16#00A1 +/exclamdownsmall 16#F7A1 +/exclammonospace 16#FF01 +/exclamsmall 16#F721 +/existential 16#2203 +/ezh 16#0292 +/ezhcaron 16#01EF +/ezhcurl 16#0293 +/ezhreversed 16#01B9 +/ezhtail 16#01BA +/f 16#0066 +/fadeva 16#095E +/fagurmukhi 16#0A5E +/fahrenheit 16#2109 +/fathaarabic 16#064E +/fathalowarabic 16#064E +/fathatanarabic 16#064B +/fbopomofo 16#3108 +/fcircle 16#24D5 +/fdotaccent 16#1E1F +/feharabic 16#0641 +/feharmenian 16#0586 +/fehfinalarabic 16#FED2 +/fehinitialarabic 16#FED3 +/fehmedialarabic 16#FED4 +/feicoptic 16#03E5 +/female 16#2640 +/ff 16#FB00 +/ffi 16#FB03 +/ffl 16#FB04 +/fi 16#FB01 +/fifteencircle 16#246E +/fifteenparen 16#2482 +/fifteenperiod 16#2496 +/figuredash 16#2012 +/filledbox 16#25A0 +/filledrect 16#25AC +/finalkaf 16#05DA +/finalkafdagesh 16#FB3A +/finalkafdageshhebrew 16#FB3A +/finalkafhebrew 16#05DA +% /finalkafqamats 16#05DA 16#05B8 +% /finalkafqamatshebrew 16#05DA 16#05B8 +% /finalkafsheva 16#05DA 16#05B0 +% /finalkafshevahebrew 16#05DA 16#05B0 +/finalmem 16#05DD +/finalmemhebrew 16#05DD +/finalnun 16#05DF +/finalnunhebrew 16#05DF +/finalpe 16#05E3 +/finalpehebrew 16#05E3 +/finaltsadi 16#05E5 +/finaltsadihebrew 16#05E5 +/firsttonechinese 16#02C9 +/fisheye 16#25C9 +/fitacyrillic 16#0473 +/five 16#0035 +/fivearabic 16#0665 +/fivebengali 16#09EB +/fivecircle 16#2464 +/fivecircleinversesansserif 16#278E +/fivedeva 16#096B +/fiveeighths 16#215D +/fivegujarati 16#0AEB +/fivegurmukhi 16#0A6B +/fivehackarabic 16#0665 +/fivehangzhou 16#3025 +/fiveideographicparen 16#3224 +/fiveinferior 16#2085 +/fivemonospace 16#FF15 +/fiveoldstyle 16#F735 +/fiveparen 16#2478 +/fiveperiod 16#248C +/fivepersian 16#06F5 +/fiveroman 16#2174 +/fivesuperior 16#2075 +/fivethai 16#0E55 +/fl 16#FB02 +/florin 16#0192 +/fmonospace 16#FF46 +/fmsquare 16#3399 +/fofanthai 16#0E1F +/fofathai 16#0E1D +/fongmanthai 16#0E4F +/forall 16#2200 +/four 16#0034 +/fourarabic 16#0664 +/fourbengali 16#09EA +/fourcircle 16#2463 +/fourcircleinversesansserif 16#278D +/fourdeva 16#096A +/fourgujarati 16#0AEA +/fourgurmukhi 16#0A6A +/fourhackarabic 16#0664 +/fourhangzhou 16#3024 +/fourideographicparen 16#3223 +/fourinferior 16#2084 +/fourmonospace 16#FF14 +/fournumeratorbengali 16#09F7 +/fouroldstyle 16#F734 +/fourparen 16#2477 +/fourperiod 16#248B +/fourpersian 16#06F4 +/fourroman 16#2173 +/foursuperior 16#2074 +/fourteencircle 16#246D +/fourteenparen 16#2481 +/fourteenperiod 16#2495 +/fourthai 16#0E54 +/fourthtonechinese 16#02CB +/fparen 16#24A1 +/fraction 16#2044 +/franc 16#20A3 +/g 16#0067 +/gabengali 16#0997 +/gacute 16#01F5 +/gadeva 16#0917 +/gafarabic 16#06AF +/gaffinalarabic 16#FB93 +/gafinitialarabic 16#FB94 +/gafmedialarabic 16#FB95 +/gagujarati 16#0A97 +/gagurmukhi 16#0A17 +/gahiragana 16#304C +/gakatakana 16#30AC +/gamma 16#03B3 +/gammalatinsmall 16#0263 +/gammasuperior 16#02E0 +/gangiacoptic 16#03EB +/gbopomofo 16#310D +/gbreve 16#011F +/gcaron 16#01E7 +/gcedilla 16#0123 +/gcircle 16#24D6 +/gcircumflex 16#011D +/gcommaaccent 16#0123 +/gdot 16#0121 +/gdotaccent 16#0121 +/gecyrillic 16#0433 +/gehiragana 16#3052 +/gekatakana 16#30B2 +/geometricallyequal 16#2251 +/gereshaccenthebrew 16#059C +/gereshhebrew 16#05F3 +/gereshmuqdamhebrew 16#059D +/germandbls 16#00DF +/gershayimaccenthebrew 16#059E +/gershayimhebrew 16#05F4 +/getamark 16#3013 +/ghabengali 16#0998 +/ghadarmenian 16#0572 +/ghadeva 16#0918 +/ghagujarati 16#0A98 +/ghagurmukhi 16#0A18 +/ghainarabic 16#063A +/ghainfinalarabic 16#FECE +/ghaininitialarabic 16#FECF +/ghainmedialarabic 16#FED0 +/ghemiddlehookcyrillic 16#0495 +/ghestrokecyrillic 16#0493 +/gheupturncyrillic 16#0491 +/ghhadeva 16#095A +/ghhagurmukhi 16#0A5A +/ghook 16#0260 +/ghzsquare 16#3393 +/gihiragana 16#304E +/gikatakana 16#30AE +/gimarmenian 16#0563 +/gimel 16#05D2 +/gimeldagesh 16#FB32 +/gimeldageshhebrew 16#FB32 +/gimelhebrew 16#05D2 +/gjecyrillic 16#0453 +/glottalinvertedstroke 16#01BE +/glottalstop 16#0294 +/glottalstopinverted 16#0296 +/glottalstopmod 16#02C0 +/glottalstopreversed 16#0295 +/glottalstopreversedmod 16#02C1 +/glottalstopreversedsuperior 16#02E4 +/glottalstopstroke 16#02A1 +/glottalstopstrokereversed 16#02A2 +/gmacron 16#1E21 +/gmonospace 16#FF47 +/gohiragana 16#3054 +/gokatakana 16#30B4 +/gparen 16#24A2 +/gpasquare 16#33AC +/gradient 16#2207 +/grave 16#0060 +/gravebelowcmb 16#0316 +/gravecmb 16#0300 +/gravecomb 16#0300 +/gravedeva 16#0953 +/gravelowmod 16#02CE +/gravemonospace 16#FF40 +/gravetonecmb 16#0340 +/greater 16#003E +/greaterequal 16#2265 +/greaterequalorless 16#22DB +/greatermonospace 16#FF1E +/greaterorequivalent 16#2273 +/greaterorless 16#2277 +/greateroverequal 16#2267 +/greatersmall 16#FE65 +/gscript 16#0261 +/gstroke 16#01E5 +/guhiragana 16#3050 +/guillemotleft 16#00AB +/guillemotright 16#00BB +/guilsinglleft 16#2039 +/guilsinglright 16#203A +/gukatakana 16#30B0 +/guramusquare 16#3318 +/gysquare 16#33C9 +/h 16#0068 +/haabkhasiancyrillic 16#04A9 +/haaltonearabic 16#06C1 +/habengali 16#09B9 +/hadescendercyrillic 16#04B3 +/hadeva 16#0939 +/hagujarati 16#0AB9 +/hagurmukhi 16#0A39 +/haharabic 16#062D +/hahfinalarabic 16#FEA2 +/hahinitialarabic 16#FEA3 +/hahiragana 16#306F +/hahmedialarabic 16#FEA4 +/haitusquare 16#332A +/hakatakana 16#30CF +/hakatakanahalfwidth 16#FF8A +/halantgurmukhi 16#0A4D +/hamzaarabic 16#0621 +% /hamzadammaarabic 16#0621 16#064F +% /hamzadammatanarabic 16#0621 16#064C +% /hamzafathaarabic 16#0621 16#064E +% /hamzafathatanarabic 16#0621 16#064B +/hamzalowarabic 16#0621 +% /hamzalowkasraarabic 16#0621 16#0650 +% /hamzalowkasratanarabic 16#0621 16#064D +% /hamzasukunarabic 16#0621 16#0652 +/hangulfiller 16#3164 +/hardsigncyrillic 16#044A +/harpoonleftbarbup 16#21BC +/harpoonrightbarbup 16#21C0 +/hasquare 16#33CA +/hatafpatah 16#05B2 +/hatafpatah16 16#05B2 +/hatafpatah23 16#05B2 +/hatafpatah2f 16#05B2 +/hatafpatahhebrew 16#05B2 +/hatafpatahnarrowhebrew 16#05B2 +/hatafpatahquarterhebrew 16#05B2 +/hatafpatahwidehebrew 16#05B2 +/hatafqamats 16#05B3 +/hatafqamats1b 16#05B3 +/hatafqamats28 16#05B3 +/hatafqamats34 16#05B3 +/hatafqamatshebrew 16#05B3 +/hatafqamatsnarrowhebrew 16#05B3 +/hatafqamatsquarterhebrew 16#05B3 +/hatafqamatswidehebrew 16#05B3 +/hatafsegol 16#05B1 +/hatafsegol17 16#05B1 +/hatafsegol24 16#05B1 +/hatafsegol30 16#05B1 +/hatafsegolhebrew 16#05B1 +/hatafsegolnarrowhebrew 16#05B1 +/hatafsegolquarterhebrew 16#05B1 +/hatafsegolwidehebrew 16#05B1 +/hbar 16#0127 +/hbopomofo 16#310F +/hbrevebelow 16#1E2B +/hcedilla 16#1E29 +/hcircle 16#24D7 +/hcircumflex 16#0125 +/hdieresis 16#1E27 +/hdotaccent 16#1E23 +/hdotbelow 16#1E25 +/he 16#05D4 +/heart 16#2665 +/heartsuitblack 16#2665 +/heartsuitwhite 16#2661 +/hedagesh 16#FB34 +/hedageshhebrew 16#FB34 +/hehaltonearabic 16#06C1 +/heharabic 16#0647 +/hehebrew 16#05D4 +/hehfinalaltonearabic 16#FBA7 +/hehfinalalttwoarabic 16#FEEA +/hehfinalarabic 16#FEEA +/hehhamzaabovefinalarabic 16#FBA5 +/hehhamzaaboveisolatedarabic 16#FBA4 +/hehinitialaltonearabic 16#FBA8 +/hehinitialarabic 16#FEEB +/hehiragana 16#3078 +/hehmedialaltonearabic 16#FBA9 +/hehmedialarabic 16#FEEC +/heiseierasquare 16#337B +/hekatakana 16#30D8 +/hekatakanahalfwidth 16#FF8D +/hekutaarusquare 16#3336 +/henghook 16#0267 +/herutusquare 16#3339 +/het 16#05D7 +/hethebrew 16#05D7 +/hhook 16#0266 +/hhooksuperior 16#02B1 +/hieuhacirclekorean 16#327B +/hieuhaparenkorean 16#321B +/hieuhcirclekorean 16#326D +/hieuhkorean 16#314E +/hieuhparenkorean 16#320D +/hihiragana 16#3072 +/hikatakana 16#30D2 +/hikatakanahalfwidth 16#FF8B +/hiriq 16#05B4 +/hiriq14 16#05B4 +/hiriq21 16#05B4 +/hiriq2d 16#05B4 +/hiriqhebrew 16#05B4 +/hiriqnarrowhebrew 16#05B4 +/hiriqquarterhebrew 16#05B4 +/hiriqwidehebrew 16#05B4 +/hlinebelow 16#1E96 +/hmonospace 16#FF48 +/hoarmenian 16#0570 +/hohipthai 16#0E2B +/hohiragana 16#307B +/hokatakana 16#30DB +/hokatakanahalfwidth 16#FF8E +/holam 16#05B9 +/holam19 16#05B9 +/holam26 16#05B9 +/holam32 16#05B9 +/holamhebrew 16#05B9 +/holamnarrowhebrew 16#05B9 +/holamquarterhebrew 16#05B9 +/holamwidehebrew 16#05B9 +/honokhukthai 16#0E2E +/hookabovecomb 16#0309 +/hookcmb 16#0309 +/hookpalatalizedbelowcmb 16#0321 +/hookretroflexbelowcmb 16#0322 +/hoonsquare 16#3342 +/horicoptic 16#03E9 +/horizontalbar 16#2015 +/horncmb 16#031B +/hotsprings 16#2668 +/house 16#2302 +/hparen 16#24A3 +/hsuperior 16#02B0 +/hturned 16#0265 +/huhiragana 16#3075 +/huiitosquare 16#3333 +/hukatakana 16#30D5 +/hukatakanahalfwidth 16#FF8C +/hungarumlaut 16#02DD +/hungarumlautcmb 16#030B +/hv 16#0195 +/hyphen 16#002D +/hypheninferior 16#F6E5 +/hyphenmonospace 16#FF0D +/hyphensmall 16#FE63 +/hyphensuperior 16#F6E6 +/hyphentwo 16#2010 +/i 16#0069 +/iacute 16#00ED +/iacyrillic 16#044F +/ibengali 16#0987 +/ibopomofo 16#3127 +/ibreve 16#012D +/icaron 16#01D0 +/icircle 16#24D8 +/icircumflex 16#00EE +/icyrillic 16#0456 +/idblgrave 16#0209 +/ideographearthcircle 16#328F +/ideographfirecircle 16#328B +/ideographicallianceparen 16#323F +/ideographiccallparen 16#323A +/ideographiccentrecircle 16#32A5 +/ideographicclose 16#3006 +/ideographiccomma 16#3001 +/ideographiccommaleft 16#FF64 +/ideographiccongratulationparen 16#3237 +/ideographiccorrectcircle 16#32A3 +/ideographicearthparen 16#322F +/ideographicenterpriseparen 16#323D +/ideographicexcellentcircle 16#329D +/ideographicfestivalparen 16#3240 +/ideographicfinancialcircle 16#3296 +/ideographicfinancialparen 16#3236 +/ideographicfireparen 16#322B +/ideographichaveparen 16#3232 +/ideographichighcircle 16#32A4 +/ideographiciterationmark 16#3005 +/ideographiclaborcircle 16#3298 +/ideographiclaborparen 16#3238 +/ideographicleftcircle 16#32A7 +/ideographiclowcircle 16#32A6 +/ideographicmedicinecircle 16#32A9 +/ideographicmetalparen 16#322E +/ideographicmoonparen 16#322A +/ideographicnameparen 16#3234 +/ideographicperiod 16#3002 +/ideographicprintcircle 16#329E +/ideographicreachparen 16#3243 +/ideographicrepresentparen 16#3239 +/ideographicresourceparen 16#323E +/ideographicrightcircle 16#32A8 +/ideographicsecretcircle 16#3299 +/ideographicselfparen 16#3242 +/ideographicsocietyparen 16#3233 +/ideographicspace 16#3000 +/ideographicspecialparen 16#3235 +/ideographicstockparen 16#3231 +/ideographicstudyparen 16#323B +/ideographicsunparen 16#3230 +/ideographicsuperviseparen 16#323C +/ideographicwaterparen 16#322C +/ideographicwoodparen 16#322D +/ideographiczero 16#3007 +/ideographmetalcircle 16#328E +/ideographmooncircle 16#328A +/ideographnamecircle 16#3294 +/ideographsuncircle 16#3290 +/ideographwatercircle 16#328C +/ideographwoodcircle 16#328D +/ideva 16#0907 +/idieresis 16#00EF +/idieresisacute 16#1E2F +/idieresiscyrillic 16#04E5 +/idotbelow 16#1ECB +/iebrevecyrillic 16#04D7 +/iecyrillic 16#0435 +/ieungacirclekorean 16#3275 +/ieungaparenkorean 16#3215 +/ieungcirclekorean 16#3267 +/ieungkorean 16#3147 +/ieungparenkorean 16#3207 +/igrave 16#00EC +/igujarati 16#0A87 +/igurmukhi 16#0A07 +/ihiragana 16#3044 +/ihookabove 16#1EC9 +/iibengali 16#0988 +/iicyrillic 16#0438 +/iideva 16#0908 +/iigujarati 16#0A88 +/iigurmukhi 16#0A08 +/iimatragurmukhi 16#0A40 +/iinvertedbreve 16#020B +/iishortcyrillic 16#0439 +/iivowelsignbengali 16#09C0 +/iivowelsigndeva 16#0940 +/iivowelsigngujarati 16#0AC0 +/ij 16#0133 +/ikatakana 16#30A4 +/ikatakanahalfwidth 16#FF72 +/ikorean 16#3163 +/ilde 16#02DC +/iluyhebrew 16#05AC +/imacron 16#012B +/imacroncyrillic 16#04E3 +/imageorapproximatelyequal 16#2253 +/imatragurmukhi 16#0A3F +/imonospace 16#FF49 +/increment 16#2206 +/infinity 16#221E +/iniarmenian 16#056B +/integral 16#222B +/integralbottom 16#2321 +/integralbt 16#2321 +/integralex 16#F8F5 +/integraltop 16#2320 +/integraltp 16#2320 +/intersection 16#2229 +/intisquare 16#3305 +/invbullet 16#25D8 +/invcircle 16#25D9 +/invsmileface 16#263B +/iocyrillic 16#0451 +/iogonek 16#012F +/iota 16#03B9 +/iotadieresis 16#03CA +/iotadieresistonos 16#0390 +/iotalatin 16#0269 +/iotatonos 16#03AF +/iparen 16#24A4 +/irigurmukhi 16#0A72 +/ismallhiragana 16#3043 +/ismallkatakana 16#30A3 +/ismallkatakanahalfwidth 16#FF68 +/issharbengali 16#09FA +/istroke 16#0268 +/isuperior 16#F6ED +/iterationhiragana 16#309D +/iterationkatakana 16#30FD +/itilde 16#0129 +/itildebelow 16#1E2D +/iubopomofo 16#3129 +/iucyrillic 16#044E +/ivowelsignbengali 16#09BF +/ivowelsigndeva 16#093F +/ivowelsigngujarati 16#0ABF +/izhitsacyrillic 16#0475 +/izhitsadblgravecyrillic 16#0477 +/j 16#006A +/jaarmenian 16#0571 +/jabengali 16#099C +/jadeva 16#091C +/jagujarati 16#0A9C +/jagurmukhi 16#0A1C +/jbopomofo 16#3110 +/jcaron 16#01F0 +/jcircle 16#24D9 +/jcircumflex 16#0135 +/jcrossedtail 16#029D +/jdotlessstroke 16#025F +/jecyrillic 16#0458 +/jeemarabic 16#062C +/jeemfinalarabic 16#FE9E +/jeeminitialarabic 16#FE9F +/jeemmedialarabic 16#FEA0 +/jeharabic 16#0698 +/jehfinalarabic 16#FB8B +/jhabengali 16#099D +/jhadeva 16#091D +/jhagujarati 16#0A9D +/jhagurmukhi 16#0A1D +/jheharmenian 16#057B +/jis 16#3004 +/jmonospace 16#FF4A +/jparen 16#24A5 +/jsuperior 16#02B2 +/k 16#006B +/kabashkircyrillic 16#04A1 +/kabengali 16#0995 +/kacute 16#1E31 +/kacyrillic 16#043A +/kadescendercyrillic 16#049B +/kadeva 16#0915 +/kaf 16#05DB +/kafarabic 16#0643 +/kafdagesh 16#FB3B +/kafdageshhebrew 16#FB3B +/kaffinalarabic 16#FEDA +/kafhebrew 16#05DB +/kafinitialarabic 16#FEDB +/kafmedialarabic 16#FEDC +/kafrafehebrew 16#FB4D +/kagujarati 16#0A95 +/kagurmukhi 16#0A15 +/kahiragana 16#304B +/kahookcyrillic 16#04C4 +/kakatakana 16#30AB +/kakatakanahalfwidth 16#FF76 +/kappa 16#03BA +/kappasymbolgreek 16#03F0 +/kapyeounmieumkorean 16#3171 +/kapyeounphieuphkorean 16#3184 +/kapyeounpieupkorean 16#3178 +/kapyeounssangpieupkorean 16#3179 +/karoriisquare 16#330D +/kashidaautoarabic 16#0640 +/kashidaautonosidebearingarabic 16#0640 +/kasmallkatakana 16#30F5 +/kasquare 16#3384 +/kasraarabic 16#0650 +/kasratanarabic 16#064D +/kastrokecyrillic 16#049F +/katahiraprolongmarkhalfwidth 16#FF70 +/kaverticalstrokecyrillic 16#049D +/kbopomofo 16#310E +/kcalsquare 16#3389 +/kcaron 16#01E9 +/kcedilla 16#0137 +/kcircle 16#24DA +/kcommaaccent 16#0137 +/kdotbelow 16#1E33 +/keharmenian 16#0584 +/kehiragana 16#3051 +/kekatakana 16#30B1 +/kekatakanahalfwidth 16#FF79 +/kenarmenian 16#056F +/kesmallkatakana 16#30F6 +/kgreenlandic 16#0138 +/khabengali 16#0996 +/khacyrillic 16#0445 +/khadeva 16#0916 +/khagujarati 16#0A96 +/khagurmukhi 16#0A16 +/khaharabic 16#062E +/khahfinalarabic 16#FEA6 +/khahinitialarabic 16#FEA7 +/khahmedialarabic 16#FEA8 +/kheicoptic 16#03E7 +/khhadeva 16#0959 +/khhagurmukhi 16#0A59 +/khieukhacirclekorean 16#3278 +/khieukhaparenkorean 16#3218 +/khieukhcirclekorean 16#326A +/khieukhkorean 16#314B +/khieukhparenkorean 16#320A +/khokhaithai 16#0E02 +/khokhonthai 16#0E05 +/khokhuatthai 16#0E03 +/khokhwaithai 16#0E04 +/khomutthai 16#0E5B +/khook 16#0199 +/khorakhangthai 16#0E06 +/khzsquare 16#3391 +/kihiragana 16#304D +/kikatakana 16#30AD +/kikatakanahalfwidth 16#FF77 +/kiroguramusquare 16#3315 +/kiromeetorusquare 16#3316 +/kirosquare 16#3314 +/kiyeokacirclekorean 16#326E +/kiyeokaparenkorean 16#320E +/kiyeokcirclekorean 16#3260 +/kiyeokkorean 16#3131 +/kiyeokparenkorean 16#3200 +/kiyeoksioskorean 16#3133 +/kjecyrillic 16#045C +/klinebelow 16#1E35 +/klsquare 16#3398 +/kmcubedsquare 16#33A6 +/kmonospace 16#FF4B +/kmsquaredsquare 16#33A2 +/kohiragana 16#3053 +/kohmsquare 16#33C0 +/kokaithai 16#0E01 +/kokatakana 16#30B3 +/kokatakanahalfwidth 16#FF7A +/kooposquare 16#331E +/koppacyrillic 16#0481 +/koreanstandardsymbol 16#327F +/koroniscmb 16#0343 +/kparen 16#24A6 +/kpasquare 16#33AA +/ksicyrillic 16#046F +/ktsquare 16#33CF +/kturned 16#029E +/kuhiragana 16#304F +/kukatakana 16#30AF +/kukatakanahalfwidth 16#FF78 +/kvsquare 16#33B8 +/kwsquare 16#33BE +/l 16#006C +/labengali 16#09B2 +/lacute 16#013A +/ladeva 16#0932 +/lagujarati 16#0AB2 +/lagurmukhi 16#0A32 +/lakkhangyaothai 16#0E45 +/lamaleffinalarabic 16#FEFC +/lamalefhamzaabovefinalarabic 16#FEF8 +/lamalefhamzaaboveisolatedarabic 16#FEF7 +/lamalefhamzabelowfinalarabic 16#FEFA +/lamalefhamzabelowisolatedarabic 16#FEF9 +/lamalefisolatedarabic 16#FEFB +/lamalefmaddaabovefinalarabic 16#FEF6 +/lamalefmaddaaboveisolatedarabic 16#FEF5 +/lamarabic 16#0644 +/lambda 16#03BB +/lambdastroke 16#019B +/lamed 16#05DC +/lameddagesh 16#FB3C +/lameddageshhebrew 16#FB3C +/lamedhebrew 16#05DC +% /lamedholam 16#05DC 16#05B9 +% /lamedholamdagesh 16#05DC 16#05B9 16#05BC +% /lamedholamdageshhebrew 16#05DC 16#05B9 16#05BC +% /lamedholamhebrew 16#05DC 16#05B9 +/lamfinalarabic 16#FEDE +/lamhahinitialarabic 16#FCCA +/laminitialarabic 16#FEDF +/lamjeeminitialarabic 16#FCC9 +/lamkhahinitialarabic 16#FCCB +/lamlamhehisolatedarabic 16#FDF2 +/lammedialarabic 16#FEE0 +/lammeemhahinitialarabic 16#FD88 +/lammeeminitialarabic 16#FCCC +% /lammeemjeeminitialarabic 16#FEDF 16#FEE4 16#FEA0 +% /lammeemkhahinitialarabic 16#FEDF 16#FEE4 16#FEA8 +/largecircle 16#25EF +/lbar 16#019A +/lbelt 16#026C +/lbopomofo 16#310C +/lcaron 16#013E +/lcedilla 16#013C +/lcircle 16#24DB +/lcircumflexbelow 16#1E3D +/lcommaaccent 16#013C +/ldot 16#0140 +/ldotaccent 16#0140 +/ldotbelow 16#1E37 +/ldotbelowmacron 16#1E39 +/leftangleabovecmb 16#031A +/lefttackbelowcmb 16#0318 +/less 16#003C +/lessequal 16#2264 +/lessequalorgreater 16#22DA +/lessmonospace 16#FF1C +/lessorequivalent 16#2272 +/lessorgreater 16#2276 +/lessoverequal 16#2266 +/lesssmall 16#FE64 +/lezh 16#026E +/lfblock 16#258C +/lhookretroflex 16#026D +/lira 16#20A4 +/liwnarmenian 16#056C +/lj 16#01C9 +/ljecyrillic 16#0459 +/ll 16#F6C0 +/lladeva 16#0933 +/llagujarati 16#0AB3 +/llinebelow 16#1E3B +/llladeva 16#0934 +/llvocalicbengali 16#09E1 +/llvocalicdeva 16#0961 +/llvocalicvowelsignbengali 16#09E3 +/llvocalicvowelsigndeva 16#0963 +/lmiddletilde 16#026B +/lmonospace 16#FF4C +/lmsquare 16#33D0 +/lochulathai 16#0E2C +/logicaland 16#2227 +/logicalnot 16#00AC +/logicalnotreversed 16#2310 +/logicalor 16#2228 +/lolingthai 16#0E25 +/longs 16#017F +/lowlinecenterline 16#FE4E +/lowlinecmb 16#0332 +/lowlinedashed 16#FE4D +/lozenge 16#25CA +/lparen 16#24A7 +/lslash 16#0142 +/lsquare 16#2113 +/lsuperior 16#F6EE +/ltshade 16#2591 +/luthai 16#0E26 +/lvocalicbengali 16#098C +/lvocalicdeva 16#090C +/lvocalicvowelsignbengali 16#09E2 +/lvocalicvowelsigndeva 16#0962 +/lxsquare 16#33D3 +/m 16#006D +/mabengali 16#09AE +/macron 16#00AF +/macronbelowcmb 16#0331 +/macroncmb 16#0304 +/macronlowmod 16#02CD +/macronmonospace 16#FFE3 +/macute 16#1E3F +/madeva 16#092E +/magujarati 16#0AAE +/magurmukhi 16#0A2E +/mahapakhhebrew 16#05A4 +/mahapakhlefthebrew 16#05A4 +/mahiragana 16#307E +/maichattawalowleftthai 16#F895 +/maichattawalowrightthai 16#F894 +/maichattawathai 16#0E4B +/maichattawaupperleftthai 16#F893 +/maieklowleftthai 16#F88C +/maieklowrightthai 16#F88B +/maiekthai 16#0E48 +/maiekupperleftthai 16#F88A +/maihanakatleftthai 16#F884 +/maihanakatthai 16#0E31 +/maitaikhuleftthai 16#F889 +/maitaikhuthai 16#0E47 +/maitholowleftthai 16#F88F +/maitholowrightthai 16#F88E +/maithothai 16#0E49 +/maithoupperleftthai 16#F88D +/maitrilowleftthai 16#F892 +/maitrilowrightthai 16#F891 +/maitrithai 16#0E4A +/maitriupperleftthai 16#F890 +/maiyamokthai 16#0E46 +/makatakana 16#30DE +/makatakanahalfwidth 16#FF8F +/male 16#2642 +/mansyonsquare 16#3347 +/maqafhebrew 16#05BE +/mars 16#2642 +/masoracirclehebrew 16#05AF +/masquare 16#3383 +/mbopomofo 16#3107 +/mbsquare 16#33D4 +/mcircle 16#24DC +/mcubedsquare 16#33A5 +/mdotaccent 16#1E41 +/mdotbelow 16#1E43 +/meemarabic 16#0645 +/meemfinalarabic 16#FEE2 +/meeminitialarabic 16#FEE3 +/meemmedialarabic 16#FEE4 +/meemmeeminitialarabic 16#FCD1 +/meemmeemisolatedarabic 16#FC48 +/meetorusquare 16#334D +/mehiragana 16#3081 +/meizierasquare 16#337E +/mekatakana 16#30E1 +/mekatakanahalfwidth 16#FF92 +/mem 16#05DE +/memdagesh 16#FB3E +/memdageshhebrew 16#FB3E +/memhebrew 16#05DE +/menarmenian 16#0574 +/merkhahebrew 16#05A5 +/merkhakefulahebrew 16#05A6 +/merkhakefulalefthebrew 16#05A6 +/merkhalefthebrew 16#05A5 +/mhook 16#0271 +/mhzsquare 16#3392 +/middledotkatakanahalfwidth 16#FF65 +/middot 16#00B7 +/mieumacirclekorean 16#3272 +/mieumaparenkorean 16#3212 +/mieumcirclekorean 16#3264 +/mieumkorean 16#3141 +/mieumpansioskorean 16#3170 +/mieumparenkorean 16#3204 +/mieumpieupkorean 16#316E +/mieumsioskorean 16#316F +/mihiragana 16#307F +/mikatakana 16#30DF +/mikatakanahalfwidth 16#FF90 +/minus 16#2212 +/minusbelowcmb 16#0320 +/minuscircle 16#2296 +/minusmod 16#02D7 +/minusplus 16#2213 +/minute 16#2032 +/miribaarusquare 16#334A +/mirisquare 16#3349 +/mlonglegturned 16#0270 +/mlsquare 16#3396 +/mmcubedsquare 16#33A3 +/mmonospace 16#FF4D +/mmsquaredsquare 16#339F +/mohiragana 16#3082 +/mohmsquare 16#33C1 +/mokatakana 16#30E2 +/mokatakanahalfwidth 16#FF93 +/molsquare 16#33D6 +/momathai 16#0E21 +/moverssquare 16#33A7 +/moverssquaredsquare 16#33A8 +/mparen 16#24A8 +/mpasquare 16#33AB +/mssquare 16#33B3 +/msuperior 16#F6EF +/mturned 16#026F +/mu 16#00B5 +/mu1 16#00B5 +/muasquare 16#3382 +/muchgreater 16#226B +/muchless 16#226A +/mufsquare 16#338C +/mugreek 16#03BC +/mugsquare 16#338D +/muhiragana 16#3080 +/mukatakana 16#30E0 +/mukatakanahalfwidth 16#FF91 +/mulsquare 16#3395 +/multiply 16#00D7 +/mumsquare 16#339B +/munahhebrew 16#05A3 +/munahlefthebrew 16#05A3 +/musicalnote 16#266A +/musicalnotedbl 16#266B +/musicflatsign 16#266D +/musicsharpsign 16#266F +/mussquare 16#33B2 +/muvsquare 16#33B6 +/muwsquare 16#33BC +/mvmegasquare 16#33B9 +/mvsquare 16#33B7 +/mwmegasquare 16#33BF +/mwsquare 16#33BD +/n 16#006E +/nabengali 16#09A8 +/nabla 16#2207 +/nacute 16#0144 +/nadeva 16#0928 +/nagujarati 16#0AA8 +/nagurmukhi 16#0A28 +/nahiragana 16#306A +/nakatakana 16#30CA +/nakatakanahalfwidth 16#FF85 +/napostrophe 16#0149 +/nasquare 16#3381 +/nbopomofo 16#310B +/nbspace 16#00A0 +/ncaron 16#0148 +/ncedilla 16#0146 +/ncircle 16#24DD +/ncircumflexbelow 16#1E4B +/ncommaaccent 16#0146 +/ndotaccent 16#1E45 +/ndotbelow 16#1E47 +/nehiragana 16#306D +/nekatakana 16#30CD +/nekatakanahalfwidth 16#FF88 +/newsheqelsign 16#20AA +/nfsquare 16#338B +/ngabengali 16#0999 +/ngadeva 16#0919 +/ngagujarati 16#0A99 +/ngagurmukhi 16#0A19 +/ngonguthai 16#0E07 +/nhiragana 16#3093 +/nhookleft 16#0272 +/nhookretroflex 16#0273 +/nieunacirclekorean 16#326F +/nieunaparenkorean 16#320F +/nieuncieuckorean 16#3135 +/nieuncirclekorean 16#3261 +/nieunhieuhkorean 16#3136 +/nieunkorean 16#3134 +/nieunpansioskorean 16#3168 +/nieunparenkorean 16#3201 +/nieunsioskorean 16#3167 +/nieuntikeutkorean 16#3166 +/nihiragana 16#306B +/nikatakana 16#30CB +/nikatakanahalfwidth 16#FF86 +/nikhahitleftthai 16#F899 +/nikhahitthai 16#0E4D +/nine 16#0039 +/ninearabic 16#0669 +/ninebengali 16#09EF +/ninecircle 16#2468 +/ninecircleinversesansserif 16#2792 +/ninedeva 16#096F +/ninegujarati 16#0AEF +/ninegurmukhi 16#0A6F +/ninehackarabic 16#0669 +/ninehangzhou 16#3029 +/nineideographicparen 16#3228 +/nineinferior 16#2089 +/ninemonospace 16#FF19 +/nineoldstyle 16#F739 +/nineparen 16#247C +/nineperiod 16#2490 +/ninepersian 16#06F9 +/nineroman 16#2178 +/ninesuperior 16#2079 +/nineteencircle 16#2472 +/nineteenparen 16#2486 +/nineteenperiod 16#249A +/ninethai 16#0E59 +/nj 16#01CC +/njecyrillic 16#045A +/nkatakana 16#30F3 +/nkatakanahalfwidth 16#FF9D +/nlegrightlong 16#019E +/nlinebelow 16#1E49 +/nmonospace 16#FF4E +/nmsquare 16#339A +/nnabengali 16#09A3 +/nnadeva 16#0923 +/nnagujarati 16#0AA3 +/nnagurmukhi 16#0A23 +/nnnadeva 16#0929 +/nohiragana 16#306E +/nokatakana 16#30CE +/nokatakanahalfwidth 16#FF89 +/nonbreakingspace 16#00A0 +/nonenthai 16#0E13 +/nonuthai 16#0E19 +/noonarabic 16#0646 +/noonfinalarabic 16#FEE6 +/noonghunnaarabic 16#06BA +/noonghunnafinalarabic 16#FB9F +% /noonhehinitialarabic 16#FEE7 16#FEEC +/nooninitialarabic 16#FEE7 +/noonjeeminitialarabic 16#FCD2 +/noonjeemisolatedarabic 16#FC4B +/noonmedialarabic 16#FEE8 +/noonmeeminitialarabic 16#FCD5 +/noonmeemisolatedarabic 16#FC4E +/noonnoonfinalarabic 16#FC8D +/notcontains 16#220C +/notelement 16#2209 +/notelementof 16#2209 +/notequal 16#2260 +/notgreater 16#226F +/notgreaternorequal 16#2271 +/notgreaternorless 16#2279 +/notidentical 16#2262 +/notless 16#226E +/notlessnorequal 16#2270 +/notparallel 16#2226 +/notprecedes 16#2280 +/notsubset 16#2284 +/notsucceeds 16#2281 +/notsuperset 16#2285 +/nowarmenian 16#0576 +/nparen 16#24A9 +/nssquare 16#33B1 +/nsuperior 16#207F +/ntilde 16#00F1 +/nu 16#03BD +/nuhiragana 16#306C +/nukatakana 16#30CC +/nukatakanahalfwidth 16#FF87 +/nuktabengali 16#09BC +/nuktadeva 16#093C +/nuktagujarati 16#0ABC +/nuktagurmukhi 16#0A3C +/numbersign 16#0023 +/numbersignmonospace 16#FF03 +/numbersignsmall 16#FE5F +/numeralsigngreek 16#0374 +/numeralsignlowergreek 16#0375 +/numero 16#2116 +/nun 16#05E0 +/nundagesh 16#FB40 +/nundageshhebrew 16#FB40 +/nunhebrew 16#05E0 +/nvsquare 16#33B5 +/nwsquare 16#33BB +/nyabengali 16#099E +/nyadeva 16#091E +/nyagujarati 16#0A9E +/nyagurmukhi 16#0A1E +/o 16#006F +/oacute 16#00F3 +/oangthai 16#0E2D +/obarred 16#0275 +/obarredcyrillic 16#04E9 +/obarreddieresiscyrillic 16#04EB +/obengali 16#0993 +/obopomofo 16#311B +/obreve 16#014F +/ocandradeva 16#0911 +/ocandragujarati 16#0A91 +/ocandravowelsigndeva 16#0949 +/ocandravowelsigngujarati 16#0AC9 +/ocaron 16#01D2 +/ocircle 16#24DE +/ocircumflex 16#00F4 +/ocircumflexacute 16#1ED1 +/ocircumflexdotbelow 16#1ED9 +/ocircumflexgrave 16#1ED3 +/ocircumflexhookabove 16#1ED5 +/ocircumflextilde 16#1ED7 +/ocyrillic 16#043E +/odblacute 16#0151 +/odblgrave 16#020D +/odeva 16#0913 +/odieresis 16#00F6 +/odieresiscyrillic 16#04E7 +/odotbelow 16#1ECD +/oe 16#0153 +/oekorean 16#315A +/ogonek 16#02DB +/ogonekcmb 16#0328 +/ograve 16#00F2 +/ogujarati 16#0A93 +/oharmenian 16#0585 +/ohiragana 16#304A +/ohookabove 16#1ECF +/ohorn 16#01A1 +/ohornacute 16#1EDB +/ohorndotbelow 16#1EE3 +/ohorngrave 16#1EDD +/ohornhookabove 16#1EDF +/ohorntilde 16#1EE1 +/ohungarumlaut 16#0151 +/oi 16#01A3 +/oinvertedbreve 16#020F +/okatakana 16#30AA +/okatakanahalfwidth 16#FF75 +/okorean 16#3157 +/olehebrew 16#05AB +/omacron 16#014D +/omacronacute 16#1E53 +/omacrongrave 16#1E51 +/omdeva 16#0950 +/omega 16#03C9 +/omega1 16#03D6 +/omegacyrillic 16#0461 +/omegalatinclosed 16#0277 +/omegaroundcyrillic 16#047B +/omegatitlocyrillic 16#047D +/omegatonos 16#03CE +/omgujarati 16#0AD0 +/omicron 16#03BF +/omicrontonos 16#03CC +/omonospace 16#FF4F +/one 16#0031 +/onearabic 16#0661 +/onebengali 16#09E7 +/onecircle 16#2460 +/onecircleinversesansserif 16#278A +/onedeva 16#0967 +/onedotenleader 16#2024 +/oneeighth 16#215B +/onefitted 16#F6DC +/onegujarati 16#0AE7 +/onegurmukhi 16#0A67 +/onehackarabic 16#0661 +/onehalf 16#00BD +/onehangzhou 16#3021 +/oneideographicparen 16#3220 +/oneinferior 16#2081 +/onemonospace 16#FF11 +/onenumeratorbengali 16#09F4 +/oneoldstyle 16#F731 +/oneparen 16#2474 +/oneperiod 16#2488 +/onepersian 16#06F1 +/onequarter 16#00BC +/oneroman 16#2170 +/onesuperior 16#00B9 +/onethai 16#0E51 +/onethird 16#2153 +/oogonek 16#01EB +/oogonekmacron 16#01ED +/oogurmukhi 16#0A13 +/oomatragurmukhi 16#0A4B +/oopen 16#0254 +/oparen 16#24AA +/openbullet 16#25E6 +/option 16#2325 +/ordfeminine 16#00AA +/ordmasculine 16#00BA +/orthogonal 16#221F +/oshortdeva 16#0912 +/oshortvowelsigndeva 16#094A +/oslash 16#00F8 +/oslashacute 16#01FF +/osmallhiragana 16#3049 +/osmallkatakana 16#30A9 +/osmallkatakanahalfwidth 16#FF6B +/ostrokeacute 16#01FF +/osuperior 16#F6F0 +/otcyrillic 16#047F +/otilde 16#00F5 +/otildeacute 16#1E4D +/otildedieresis 16#1E4F +/oubopomofo 16#3121 +/overline 16#203E +/overlinecenterline 16#FE4A +/overlinecmb 16#0305 +/overlinedashed 16#FE49 +/overlinedblwavy 16#FE4C +/overlinewavy 16#FE4B +/overscore 16#00AF +/ovowelsignbengali 16#09CB +/ovowelsigndeva 16#094B +/ovowelsigngujarati 16#0ACB +/p 16#0070 +/paampssquare 16#3380 +/paasentosquare 16#332B +/pabengali 16#09AA +/pacute 16#1E55 +/padeva 16#092A +/pagedown 16#21DF +/pageup 16#21DE +/pagujarati 16#0AAA +/pagurmukhi 16#0A2A +/pahiragana 16#3071 +/paiyannoithai 16#0E2F +/pakatakana 16#30D1 +/palatalizationcyrilliccmb 16#0484 +/palochkacyrillic 16#04C0 +/pansioskorean 16#317F +/paragraph 16#00B6 +/parallel 16#2225 +/parenleft 16#0028 +/parenleftaltonearabic 16#FD3E +/parenleftbt 16#F8ED +/parenleftex 16#F8EC +/parenleftinferior 16#208D +/parenleftmonospace 16#FF08 +/parenleftsmall 16#FE59 +/parenleftsuperior 16#207D +/parenlefttp 16#F8EB +/parenleftvertical 16#FE35 +/parenright 16#0029 +/parenrightaltonearabic 16#FD3F +/parenrightbt 16#F8F8 +/parenrightex 16#F8F7 +/parenrightinferior 16#208E +/parenrightmonospace 16#FF09 +/parenrightsmall 16#FE5A +/parenrightsuperior 16#207E +/parenrighttp 16#F8F6 +/parenrightvertical 16#FE36 +/partialdiff 16#2202 +/paseqhebrew 16#05C0 +/pashtahebrew 16#0599 +/pasquare 16#33A9 +/patah 16#05B7 +/patah11 16#05B7 +/patah1d 16#05B7 +/patah2a 16#05B7 +/patahhebrew 16#05B7 +/patahnarrowhebrew 16#05B7 +/patahquarterhebrew 16#05B7 +/patahwidehebrew 16#05B7 +/pazerhebrew 16#05A1 +/pbopomofo 16#3106 +/pcircle 16#24DF +/pdotaccent 16#1E57 +/pe 16#05E4 +/pecyrillic 16#043F +/pedagesh 16#FB44 +/pedageshhebrew 16#FB44 +/peezisquare 16#333B +/pefinaldageshhebrew 16#FB43 +/peharabic 16#067E +/peharmenian 16#057A +/pehebrew 16#05E4 +/pehfinalarabic 16#FB57 +/pehinitialarabic 16#FB58 +/pehiragana 16#307A +/pehmedialarabic 16#FB59 +/pekatakana 16#30DA +/pemiddlehookcyrillic 16#04A7 +/perafehebrew 16#FB4E +/percent 16#0025 +/percentarabic 16#066A +/percentmonospace 16#FF05 +/percentsmall 16#FE6A +/period 16#002E +/periodarmenian 16#0589 +/periodcentered 16#00B7 +/periodhalfwidth 16#FF61 +/periodinferior 16#F6E7 +/periodmonospace 16#FF0E +/periodsmall 16#FE52 +/periodsuperior 16#F6E8 +/perispomenigreekcmb 16#0342 +/perpendicular 16#22A5 +/perthousand 16#2030 +/peseta 16#20A7 +/pfsquare 16#338A +/phabengali 16#09AB +/phadeva 16#092B +/phagujarati 16#0AAB +/phagurmukhi 16#0A2B +/phi 16#03C6 +/phi1 16#03D5 +/phieuphacirclekorean 16#327A +/phieuphaparenkorean 16#321A +/phieuphcirclekorean 16#326C +/phieuphkorean 16#314D +/phieuphparenkorean 16#320C +/philatin 16#0278 +/phinthuthai 16#0E3A +/phisymbolgreek 16#03D5 +/phook 16#01A5 +/phophanthai 16#0E1E +/phophungthai 16#0E1C +/phosamphaothai 16#0E20 +/pi 16#03C0 +/pieupacirclekorean 16#3273 +/pieupaparenkorean 16#3213 +/pieupcieuckorean 16#3176 +/pieupcirclekorean 16#3265 +/pieupkiyeokkorean 16#3172 +/pieupkorean 16#3142 +/pieupparenkorean 16#3205 +/pieupsioskiyeokkorean 16#3174 +/pieupsioskorean 16#3144 +/pieupsiostikeutkorean 16#3175 +/pieupthieuthkorean 16#3177 +/pieuptikeutkorean 16#3173 +/pihiragana 16#3074 +/pikatakana 16#30D4 +/pisymbolgreek 16#03D6 +/piwrarmenian 16#0583 +/plus 16#002B +/plusbelowcmb 16#031F +/pluscircle 16#2295 +/plusminus 16#00B1 +/plusmod 16#02D6 +/plusmonospace 16#FF0B +/plussmall 16#FE62 +/plussuperior 16#207A +/pmonospace 16#FF50 +/pmsquare 16#33D8 +/pohiragana 16#307D +/pointingindexdownwhite 16#261F +/pointingindexleftwhite 16#261C +/pointingindexrightwhite 16#261E +/pointingindexupwhite 16#261D +/pokatakana 16#30DD +/poplathai 16#0E1B +/postalmark 16#3012 +/postalmarkface 16#3020 +/pparen 16#24AB +/precedes 16#227A +/prescription 16#211E +/primemod 16#02B9 +/primereversed 16#2035 +/product 16#220F +/projective 16#2305 +/prolongedkana 16#30FC +/propellor 16#2318 +/propersubset 16#2282 +/propersuperset 16#2283 +/proportion 16#2237 +/proportional 16#221D +/psi 16#03C8 +/psicyrillic 16#0471 +/psilipneumatacyrilliccmb 16#0486 +/pssquare 16#33B0 +/puhiragana 16#3077 +/pukatakana 16#30D7 +/pvsquare 16#33B4 +/pwsquare 16#33BA +/q 16#0071 +/qadeva 16#0958 +/qadmahebrew 16#05A8 +/qafarabic 16#0642 +/qaffinalarabic 16#FED6 +/qafinitialarabic 16#FED7 +/qafmedialarabic 16#FED8 +/qamats 16#05B8 +/qamats10 16#05B8 +/qamats1a 16#05B8 +/qamats1c 16#05B8 +/qamats27 16#05B8 +/qamats29 16#05B8 +/qamats33 16#05B8 +/qamatsde 16#05B8 +/qamatshebrew 16#05B8 +/qamatsnarrowhebrew 16#05B8 +/qamatsqatanhebrew 16#05B8 +/qamatsqatannarrowhebrew 16#05B8 +/qamatsqatanquarterhebrew 16#05B8 +/qamatsqatanwidehebrew 16#05B8 +/qamatsquarterhebrew 16#05B8 +/qamatswidehebrew 16#05B8 +/qarneyparahebrew 16#059F +/qbopomofo 16#3111 +/qcircle 16#24E0 +/qhook 16#02A0 +/qmonospace 16#FF51 +/qof 16#05E7 +/qofdagesh 16#FB47 +/qofdageshhebrew 16#FB47 +% /qofhatafpatah 16#05E7 16#05B2 +% /qofhatafpatahhebrew 16#05E7 16#05B2 +% /qofhatafsegol 16#05E7 16#05B1 +% /qofhatafsegolhebrew 16#05E7 16#05B1 +/qofhebrew 16#05E7 +% /qofhiriq 16#05E7 16#05B4 +% /qofhiriqhebrew 16#05E7 16#05B4 +% /qofholam 16#05E7 16#05B9 +% /qofholamhebrew 16#05E7 16#05B9 +% /qofpatah 16#05E7 16#05B7 +% /qofpatahhebrew 16#05E7 16#05B7 +% /qofqamats 16#05E7 16#05B8 +% /qofqamatshebrew 16#05E7 16#05B8 +% /qofqubuts 16#05E7 16#05BB +% /qofqubutshebrew 16#05E7 16#05BB +% /qofsegol 16#05E7 16#05B6 +% /qofsegolhebrew 16#05E7 16#05B6 +% /qofsheva 16#05E7 16#05B0 +% /qofshevahebrew 16#05E7 16#05B0 +% /qoftsere 16#05E7 16#05B5 +% /qoftserehebrew 16#05E7 16#05B5 +/qparen 16#24AC +/quarternote 16#2669 +/qubuts 16#05BB +/qubuts18 16#05BB +/qubuts25 16#05BB +/qubuts31 16#05BB +/qubutshebrew 16#05BB +/qubutsnarrowhebrew 16#05BB +/qubutsquarterhebrew 16#05BB +/qubutswidehebrew 16#05BB +/question 16#003F +/questionarabic 16#061F +/questionarmenian 16#055E +/questiondown 16#00BF +/questiondownsmall 16#F7BF +/questiongreek 16#037E +/questionmonospace 16#FF1F +/questionsmall 16#F73F +/quotedbl 16#0022 +/quotedblbase 16#201E +/quotedblleft 16#201C +/quotedblmonospace 16#FF02 +/quotedblprime 16#301E +/quotedblprimereversed 16#301D +/quotedblright 16#201D +/quoteleft 16#2018 +/quoteleftreversed 16#201B +/quotereversed 16#201B +/quoteright 16#2019 +/quoterightn 16#0149 +/quotesinglbase 16#201A +/quotesingle 16#0027 +/quotesinglemonospace 16#FF07 +/r 16#0072 +/raarmenian 16#057C +/rabengali 16#09B0 +/racute 16#0155 +/radeva 16#0930 +/radical 16#221A +/radicalex 16#F8E5 +/radoverssquare 16#33AE +/radoverssquaredsquare 16#33AF +/radsquare 16#33AD +/rafe 16#05BF +/rafehebrew 16#05BF +/ragujarati 16#0AB0 +/ragurmukhi 16#0A30 +/rahiragana 16#3089 +/rakatakana 16#30E9 +/rakatakanahalfwidth 16#FF97 +/ralowerdiagonalbengali 16#09F1 +/ramiddlediagonalbengali 16#09F0 +/ramshorn 16#0264 +/ratio 16#2236 +/rbopomofo 16#3116 +/rcaron 16#0159 +/rcedilla 16#0157 +/rcircle 16#24E1 +/rcommaaccent 16#0157 +/rdblgrave 16#0211 +/rdotaccent 16#1E59 +/rdotbelow 16#1E5B +/rdotbelowmacron 16#1E5D +/referencemark 16#203B +/reflexsubset 16#2286 +/reflexsuperset 16#2287 +/registered 16#00AE +/registersans 16#F8E8 +/registerserif 16#F6DA +/reharabic 16#0631 +/reharmenian 16#0580 +/rehfinalarabic 16#FEAE +/rehiragana 16#308C +% /rehyehaleflamarabic 16#0631 16#FEF3 16#FE8E 16#0644 +/rekatakana 16#30EC +/rekatakanahalfwidth 16#FF9A +/resh 16#05E8 +/reshdageshhebrew 16#FB48 +% /reshhatafpatah 16#05E8 16#05B2 +% /reshhatafpatahhebrew 16#05E8 16#05B2 +% /reshhatafsegol 16#05E8 16#05B1 +% /reshhatafsegolhebrew 16#05E8 16#05B1 +/reshhebrew 16#05E8 +% /reshhiriq 16#05E8 16#05B4 +% /reshhiriqhebrew 16#05E8 16#05B4 +% /reshholam 16#05E8 16#05B9 +% /reshholamhebrew 16#05E8 16#05B9 +% /reshpatah 16#05E8 16#05B7 +% /reshpatahhebrew 16#05E8 16#05B7 +% /reshqamats 16#05E8 16#05B8 +% /reshqamatshebrew 16#05E8 16#05B8 +% /reshqubuts 16#05E8 16#05BB +% /reshqubutshebrew 16#05E8 16#05BB +% /reshsegol 16#05E8 16#05B6 +% /reshsegolhebrew 16#05E8 16#05B6 +% /reshsheva 16#05E8 16#05B0 +% /reshshevahebrew 16#05E8 16#05B0 +% /reshtsere 16#05E8 16#05B5 +% /reshtserehebrew 16#05E8 16#05B5 +/reversedtilde 16#223D +/reviahebrew 16#0597 +/reviamugrashhebrew 16#0597 +/revlogicalnot 16#2310 +/rfishhook 16#027E +/rfishhookreversed 16#027F +/rhabengali 16#09DD +/rhadeva 16#095D +/rho 16#03C1 +/rhook 16#027D +/rhookturned 16#027B +/rhookturnedsuperior 16#02B5 +/rhosymbolgreek 16#03F1 +/rhotichookmod 16#02DE +/rieulacirclekorean 16#3271 +/rieulaparenkorean 16#3211 +/rieulcirclekorean 16#3263 +/rieulhieuhkorean 16#3140 +/rieulkiyeokkorean 16#313A +/rieulkiyeoksioskorean 16#3169 +/rieulkorean 16#3139 +/rieulmieumkorean 16#313B +/rieulpansioskorean 16#316C +/rieulparenkorean 16#3203 +/rieulphieuphkorean 16#313F +/rieulpieupkorean 16#313C +/rieulpieupsioskorean 16#316B +/rieulsioskorean 16#313D +/rieulthieuthkorean 16#313E +/rieultikeutkorean 16#316A +/rieulyeorinhieuhkorean 16#316D +/rightangle 16#221F +/righttackbelowcmb 16#0319 +/righttriangle 16#22BF +/rihiragana 16#308A +/rikatakana 16#30EA +/rikatakanahalfwidth 16#FF98 +/ring 16#02DA +/ringbelowcmb 16#0325 +/ringcmb 16#030A +/ringhalfleft 16#02BF +/ringhalfleftarmenian 16#0559 +/ringhalfleftbelowcmb 16#031C +/ringhalfleftcentered 16#02D3 +/ringhalfright 16#02BE +/ringhalfrightbelowcmb 16#0339 +/ringhalfrightcentered 16#02D2 +/rinvertedbreve 16#0213 +/rittorusquare 16#3351 +/rlinebelow 16#1E5F +/rlongleg 16#027C +/rlonglegturned 16#027A +/rmonospace 16#FF52 +/rohiragana 16#308D +/rokatakana 16#30ED +/rokatakanahalfwidth 16#FF9B +/roruathai 16#0E23 +/rparen 16#24AD +/rrabengali 16#09DC +/rradeva 16#0931 +/rragurmukhi 16#0A5C +/rreharabic 16#0691 +/rrehfinalarabic 16#FB8D +/rrvocalicbengali 16#09E0 +/rrvocalicdeva 16#0960 +/rrvocalicgujarati 16#0AE0 +/rrvocalicvowelsignbengali 16#09C4 +/rrvocalicvowelsigndeva 16#0944 +/rrvocalicvowelsigngujarati 16#0AC4 +/rsuperior 16#F6F1 +/rtblock 16#2590 +/rturned 16#0279 +/rturnedsuperior 16#02B4 +/ruhiragana 16#308B +/rukatakana 16#30EB +/rukatakanahalfwidth 16#FF99 +/rupeemarkbengali 16#09F2 +/rupeesignbengali 16#09F3 +/rupiah 16#F6DD +/ruthai 16#0E24 +/rvocalicbengali 16#098B +/rvocalicdeva 16#090B +/rvocalicgujarati 16#0A8B +/rvocalicvowelsignbengali 16#09C3 +/rvocalicvowelsigndeva 16#0943 +/rvocalicvowelsigngujarati 16#0AC3 +/s 16#0073 +/sabengali 16#09B8 +/sacute 16#015B +/sacutedotaccent 16#1E65 +/sadarabic 16#0635 +/sadeva 16#0938 +/sadfinalarabic 16#FEBA +/sadinitialarabic 16#FEBB +/sadmedialarabic 16#FEBC +/sagujarati 16#0AB8 +/sagurmukhi 16#0A38 +/sahiragana 16#3055 +/sakatakana 16#30B5 +/sakatakanahalfwidth 16#FF7B +/sallallahoualayhewasallamarabic 16#FDFA +/samekh 16#05E1 +/samekhdagesh 16#FB41 +/samekhdageshhebrew 16#FB41 +/samekhhebrew 16#05E1 +/saraaathai 16#0E32 +/saraaethai 16#0E41 +/saraaimaimalaithai 16#0E44 +/saraaimaimuanthai 16#0E43 +/saraamthai 16#0E33 +/saraathai 16#0E30 +/saraethai 16#0E40 +/saraiileftthai 16#F886 +/saraiithai 16#0E35 +/saraileftthai 16#F885 +/saraithai 16#0E34 +/saraothai 16#0E42 +/saraueeleftthai 16#F888 +/saraueethai 16#0E37 +/saraueleftthai 16#F887 +/sarauethai 16#0E36 +/sarauthai 16#0E38 +/sarauuthai 16#0E39 +/sbopomofo 16#3119 +/scaron 16#0161 +/scarondotaccent 16#1E67 +/scedilla 16#015F +/schwa 16#0259 +/schwacyrillic 16#04D9 +/schwadieresiscyrillic 16#04DB +/schwahook 16#025A +/scircle 16#24E2 +/scircumflex 16#015D +/scommaaccent 16#0219 +/sdotaccent 16#1E61 +/sdotbelow 16#1E63 +/sdotbelowdotaccent 16#1E69 +/seagullbelowcmb 16#033C +/second 16#2033 +/secondtonechinese 16#02CA +/section 16#00A7 +/seenarabic 16#0633 +/seenfinalarabic 16#FEB2 +/seeninitialarabic 16#FEB3 +/seenmedialarabic 16#FEB4 +/segol 16#05B6 +/segol13 16#05B6 +/segol1f 16#05B6 +/segol2c 16#05B6 +/segolhebrew 16#05B6 +/segolnarrowhebrew 16#05B6 +/segolquarterhebrew 16#05B6 +/segoltahebrew 16#0592 +/segolwidehebrew 16#05B6 +/seharmenian 16#057D +/sehiragana 16#305B +/sekatakana 16#30BB +/sekatakanahalfwidth 16#FF7E +/semicolon 16#003B +/semicolonarabic 16#061B +/semicolonmonospace 16#FF1B +/semicolonsmall 16#FE54 +/semivoicedmarkkana 16#309C +/semivoicedmarkkanahalfwidth 16#FF9F +/sentisquare 16#3322 +/sentosquare 16#3323 +/seven 16#0037 +/sevenarabic 16#0667 +/sevenbengali 16#09ED +/sevencircle 16#2466 +/sevencircleinversesansserif 16#2790 +/sevendeva 16#096D +/seveneighths 16#215E +/sevengujarati 16#0AED +/sevengurmukhi 16#0A6D +/sevenhackarabic 16#0667 +/sevenhangzhou 16#3027 +/sevenideographicparen 16#3226 +/seveninferior 16#2087 +/sevenmonospace 16#FF17 +/sevenoldstyle 16#F737 +/sevenparen 16#247A +/sevenperiod 16#248E +/sevenpersian 16#06F7 +/sevenroman 16#2176 +/sevensuperior 16#2077 +/seventeencircle 16#2470 +/seventeenparen 16#2484 +/seventeenperiod 16#2498 +/seventhai 16#0E57 +/sfthyphen 16#00AD +/shaarmenian 16#0577 +/shabengali 16#09B6 +/shacyrillic 16#0448 +/shaddaarabic 16#0651 +/shaddadammaarabic 16#FC61 +/shaddadammatanarabic 16#FC5E +/shaddafathaarabic 16#FC60 +% /shaddafathatanarabic 16#0651 16#064B +/shaddakasraarabic 16#FC62 +/shaddakasratanarabic 16#FC5F +/shade 16#2592 +/shadedark 16#2593 +/shadelight 16#2591 +/shademedium 16#2592 +/shadeva 16#0936 +/shagujarati 16#0AB6 +/shagurmukhi 16#0A36 +/shalshelethebrew 16#0593 +/shbopomofo 16#3115 +/shchacyrillic 16#0449 +/sheenarabic 16#0634 +/sheenfinalarabic 16#FEB6 +/sheeninitialarabic 16#FEB7 +/sheenmedialarabic 16#FEB8 +/sheicoptic 16#03E3 +/sheqel 16#20AA +/sheqelhebrew 16#20AA +/sheva 16#05B0 +/sheva115 16#05B0 +/sheva15 16#05B0 +/sheva22 16#05B0 +/sheva2e 16#05B0 +/shevahebrew 16#05B0 +/shevanarrowhebrew 16#05B0 +/shevaquarterhebrew 16#05B0 +/shevawidehebrew 16#05B0 +/shhacyrillic 16#04BB +/shimacoptic 16#03ED +/shin 16#05E9 +/shindagesh 16#FB49 +/shindageshhebrew 16#FB49 +/shindageshshindot 16#FB2C +/shindageshshindothebrew 16#FB2C +/shindageshsindot 16#FB2D +/shindageshsindothebrew 16#FB2D +/shindothebrew 16#05C1 +/shinhebrew 16#05E9 +/shinshindot 16#FB2A +/shinshindothebrew 16#FB2A +/shinsindot 16#FB2B +/shinsindothebrew 16#FB2B +/shook 16#0282 +/sigma 16#03C3 +/sigma1 16#03C2 +/sigmafinal 16#03C2 +/sigmalunatesymbolgreek 16#03F2 +/sihiragana 16#3057 +/sikatakana 16#30B7 +/sikatakanahalfwidth 16#FF7C +/siluqhebrew 16#05BD +/siluqlefthebrew 16#05BD +/similar 16#223C +/sindothebrew 16#05C2 +/siosacirclekorean 16#3274 +/siosaparenkorean 16#3214 +/sioscieuckorean 16#317E +/sioscirclekorean 16#3266 +/sioskiyeokkorean 16#317A +/sioskorean 16#3145 +/siosnieunkorean 16#317B +/siosparenkorean 16#3206 +/siospieupkorean 16#317D +/siostikeutkorean 16#317C +/six 16#0036 +/sixarabic 16#0666 +/sixbengali 16#09EC +/sixcircle 16#2465 +/sixcircleinversesansserif 16#278F +/sixdeva 16#096C +/sixgujarati 16#0AEC +/sixgurmukhi 16#0A6C +/sixhackarabic 16#0666 +/sixhangzhou 16#3026 +/sixideographicparen 16#3225 +/sixinferior 16#2086 +/sixmonospace 16#FF16 +/sixoldstyle 16#F736 +/sixparen 16#2479 +/sixperiod 16#248D +/sixpersian 16#06F6 +/sixroman 16#2175 +/sixsuperior 16#2076 +/sixteencircle 16#246F +/sixteencurrencydenominatorbengali 16#09F9 +/sixteenparen 16#2483 +/sixteenperiod 16#2497 +/sixthai 16#0E56 +/slash 16#002F +/slashmonospace 16#FF0F +/slong 16#017F +/slongdotaccent 16#1E9B +/smileface 16#263A +/smonospace 16#FF53 +/sofpasuqhebrew 16#05C3 +/softhyphen 16#00AD +/softsigncyrillic 16#044C +/sohiragana 16#305D +/sokatakana 16#30BD +/sokatakanahalfwidth 16#FF7F +/soliduslongoverlaycmb 16#0338 +/solidusshortoverlaycmb 16#0337 +/sorusithai 16#0E29 +/sosalathai 16#0E28 +/sosothai 16#0E0B +/sosuathai 16#0E2A +/space 16#0020 +/spacehackarabic 16#0020 +/spade 16#2660 +/spadesuitblack 16#2660 +/spadesuitwhite 16#2664 +/sparen 16#24AE +/squarebelowcmb 16#033B +/squarecc 16#33C4 +/squarecm 16#339D +/squarediagonalcrosshatchfill 16#25A9 +/squarehorizontalfill 16#25A4 +/squarekg 16#338F +/squarekm 16#339E +/squarekmcapital 16#33CE +/squareln 16#33D1 +/squarelog 16#33D2 +/squaremg 16#338E +/squaremil 16#33D5 +/squaremm 16#339C +/squaremsquared 16#33A1 +/squareorthogonalcrosshatchfill 16#25A6 +/squareupperlefttolowerrightfill 16#25A7 +/squareupperrighttolowerleftfill 16#25A8 +/squareverticalfill 16#25A5 +/squarewhitewithsmallblack 16#25A3 +/srsquare 16#33DB +/ssabengali 16#09B7 +/ssadeva 16#0937 +/ssagujarati 16#0AB7 +/ssangcieuckorean 16#3149 +/ssanghieuhkorean 16#3185 +/ssangieungkorean 16#3180 +/ssangkiyeokkorean 16#3132 +/ssangnieunkorean 16#3165 +/ssangpieupkorean 16#3143 +/ssangsioskorean 16#3146 +/ssangtikeutkorean 16#3138 +/ssuperior 16#F6F2 +/sterling 16#00A3 +/sterlingmonospace 16#FFE1 +/strokelongoverlaycmb 16#0336 +/strokeshortoverlaycmb 16#0335 +/subset 16#2282 +/subsetnotequal 16#228A +/subsetorequal 16#2286 +/succeeds 16#227B +/suchthat 16#220B +/suhiragana 16#3059 +/sukatakana 16#30B9 +/sukatakanahalfwidth 16#FF7D +/sukunarabic 16#0652 +/summation 16#2211 +/sun 16#263C +/superset 16#2283 +/supersetnotequal 16#228B +/supersetorequal 16#2287 +/svsquare 16#33DC +/syouwaerasquare 16#337C +/t 16#0074 +/tabengali 16#09A4 +/tackdown 16#22A4 +/tackleft 16#22A3 +/tadeva 16#0924 +/tagujarati 16#0AA4 +/tagurmukhi 16#0A24 +/taharabic 16#0637 +/tahfinalarabic 16#FEC2 +/tahinitialarabic 16#FEC3 +/tahiragana 16#305F +/tahmedialarabic 16#FEC4 +/taisyouerasquare 16#337D +/takatakana 16#30BF +/takatakanahalfwidth 16#FF80 +/tatweelarabic 16#0640 +/tau 16#03C4 +/tav 16#05EA +/tavdages 16#FB4A +/tavdagesh 16#FB4A +/tavdageshhebrew 16#FB4A +/tavhebrew 16#05EA +/tbar 16#0167 +/tbopomofo 16#310A +/tcaron 16#0165 +/tccurl 16#02A8 +/tcedilla 16#0163 +/tcheharabic 16#0686 +/tchehfinalarabic 16#FB7B +/tchehinitialarabic 16#FB7C +/tchehmedialarabic 16#FB7D +% /tchehmeeminitialarabic 16#FB7C 16#FEE4 +/tcircle 16#24E3 +/tcircumflexbelow 16#1E71 +/tcommaaccent 16#0163 +/tdieresis 16#1E97 +/tdotaccent 16#1E6B +/tdotbelow 16#1E6D +/tecyrillic 16#0442 +/tedescendercyrillic 16#04AD +/teharabic 16#062A +/tehfinalarabic 16#FE96 +/tehhahinitialarabic 16#FCA2 +/tehhahisolatedarabic 16#FC0C +/tehinitialarabic 16#FE97 +/tehiragana 16#3066 +/tehjeeminitialarabic 16#FCA1 +/tehjeemisolatedarabic 16#FC0B +/tehmarbutaarabic 16#0629 +/tehmarbutafinalarabic 16#FE94 +/tehmedialarabic 16#FE98 +/tehmeeminitialarabic 16#FCA4 +/tehmeemisolatedarabic 16#FC0E +/tehnoonfinalarabic 16#FC73 +/tekatakana 16#30C6 +/tekatakanahalfwidth 16#FF83 +/telephone 16#2121 +/telephoneblack 16#260E +/telishagedolahebrew 16#05A0 +/telishaqetanahebrew 16#05A9 +/tencircle 16#2469 +/tenideographicparen 16#3229 +/tenparen 16#247D +/tenperiod 16#2491 +/tenroman 16#2179 +/tesh 16#02A7 +/tet 16#05D8 +/tetdagesh 16#FB38 +/tetdageshhebrew 16#FB38 +/tethebrew 16#05D8 +/tetsecyrillic 16#04B5 +/tevirhebrew 16#059B +/tevirlefthebrew 16#059B +/thabengali 16#09A5 +/thadeva 16#0925 +/thagujarati 16#0AA5 +/thagurmukhi 16#0A25 +/thalarabic 16#0630 +/thalfinalarabic 16#FEAC +/thanthakhatlowleftthai 16#F898 +/thanthakhatlowrightthai 16#F897 +/thanthakhatthai 16#0E4C +/thanthakhatupperleftthai 16#F896 +/theharabic 16#062B +/thehfinalarabic 16#FE9A +/thehinitialarabic 16#FE9B +/thehmedialarabic 16#FE9C +/thereexists 16#2203 +/therefore 16#2234 +/theta 16#03B8 +/theta1 16#03D1 +/thetasymbolgreek 16#03D1 +/thieuthacirclekorean 16#3279 +/thieuthaparenkorean 16#3219 +/thieuthcirclekorean 16#326B +/thieuthkorean 16#314C +/thieuthparenkorean 16#320B +/thirteencircle 16#246C +/thirteenparen 16#2480 +/thirteenperiod 16#2494 +/thonangmonthothai 16#0E11 +/thook 16#01AD +/thophuthaothai 16#0E12 +/thorn 16#00FE +/thothahanthai 16#0E17 +/thothanthai 16#0E10 +/thothongthai 16#0E18 +/thothungthai 16#0E16 +/thousandcyrillic 16#0482 +/thousandsseparatorarabic 16#066C +/thousandsseparatorpersian 16#066C +/three 16#0033 +/threearabic 16#0663 +/threebengali 16#09E9 +/threecircle 16#2462 +/threecircleinversesansserif 16#278C +/threedeva 16#0969 +/threeeighths 16#215C +/threegujarati 16#0AE9 +/threegurmukhi 16#0A69 +/threehackarabic 16#0663 +/threehangzhou 16#3023 +/threeideographicparen 16#3222 +/threeinferior 16#2083 +/threemonospace 16#FF13 +/threenumeratorbengali 16#09F6 +/threeoldstyle 16#F733 +/threeparen 16#2476 +/threeperiod 16#248A +/threepersian 16#06F3 +/threequarters 16#00BE +/threequartersemdash 16#F6DE +/threeroman 16#2172 +/threesuperior 16#00B3 +/threethai 16#0E53 +/thzsquare 16#3394 +/tihiragana 16#3061 +/tikatakana 16#30C1 +/tikatakanahalfwidth 16#FF81 +/tikeutacirclekorean 16#3270 +/tikeutaparenkorean 16#3210 +/tikeutcirclekorean 16#3262 +/tikeutkorean 16#3137 +/tikeutparenkorean 16#3202 +/tilde 16#02DC +/tildebelowcmb 16#0330 +/tildecmb 16#0303 +/tildecomb 16#0303 +/tildedoublecmb 16#0360 +/tildeoperator 16#223C +/tildeoverlaycmb 16#0334 +/tildeverticalcmb 16#033E +/timescircle 16#2297 +/tipehahebrew 16#0596 +/tipehalefthebrew 16#0596 +/tippigurmukhi 16#0A70 +/titlocyrilliccmb 16#0483 +/tiwnarmenian 16#057F +/tlinebelow 16#1E6F +/tmonospace 16#FF54 +/toarmenian 16#0569 +/tohiragana 16#3068 +/tokatakana 16#30C8 +/tokatakanahalfwidth 16#FF84 +/tonebarextrahighmod 16#02E5 +/tonebarextralowmod 16#02E9 +/tonebarhighmod 16#02E6 +/tonebarlowmod 16#02E8 +/tonebarmidmod 16#02E7 +/tonefive 16#01BD +/tonesix 16#0185 +/tonetwo 16#01A8 +/tonos 16#0384 +/tonsquare 16#3327 +/topatakthai 16#0E0F +/tortoiseshellbracketleft 16#3014 +/tortoiseshellbracketleftsmall 16#FE5D +/tortoiseshellbracketleftvertical 16#FE39 +/tortoiseshellbracketright 16#3015 +/tortoiseshellbracketrightsmall 16#FE5E +/tortoiseshellbracketrightvertical 16#FE3A +/totaothai 16#0E15 +/tpalatalhook 16#01AB +/tparen 16#24AF +/trademark 16#2122 +/trademarksans 16#F8EA +/trademarkserif 16#F6DB +/tretroflexhook 16#0288 +/triagdn 16#25BC +/triaglf 16#25C4 +/triagrt 16#25BA +/triagup 16#25B2 +/ts 16#02A6 +/tsadi 16#05E6 +/tsadidagesh 16#FB46 +/tsadidageshhebrew 16#FB46 +/tsadihebrew 16#05E6 +/tsecyrillic 16#0446 +/tsere 16#05B5 +/tsere12 16#05B5 +/tsere1e 16#05B5 +/tsere2b 16#05B5 +/tserehebrew 16#05B5 +/tserenarrowhebrew 16#05B5 +/tserequarterhebrew 16#05B5 +/tserewidehebrew 16#05B5 +/tshecyrillic 16#045B +/tsuperior 16#F6F3 +/ttabengali 16#099F +/ttadeva 16#091F +/ttagujarati 16#0A9F +/ttagurmukhi 16#0A1F +/tteharabic 16#0679 +/ttehfinalarabic 16#FB67 +/ttehinitialarabic 16#FB68 +/ttehmedialarabic 16#FB69 +/tthabengali 16#09A0 +/tthadeva 16#0920 +/tthagujarati 16#0AA0 +/tthagurmukhi 16#0A20 +/tturned 16#0287 +/tuhiragana 16#3064 +/tukatakana 16#30C4 +/tukatakanahalfwidth 16#FF82 +/tusmallhiragana 16#3063 +/tusmallkatakana 16#30C3 +/tusmallkatakanahalfwidth 16#FF6F +/twelvecircle 16#246B +/twelveparen 16#247F +/twelveperiod 16#2493 +/twelveroman 16#217B +/twentycircle 16#2473 +/twentyhangzhou 16#5344 +/twentyparen 16#2487 +/twentyperiod 16#249B +/two 16#0032 +/twoarabic 16#0662 +/twobengali 16#09E8 +/twocircle 16#2461 +/twocircleinversesansserif 16#278B +/twodeva 16#0968 +/twodotenleader 16#2025 +/twodotleader 16#2025 +/twodotleadervertical 16#FE30 +/twogujarati 16#0AE8 +/twogurmukhi 16#0A68 +/twohackarabic 16#0662 +/twohangzhou 16#3022 +/twoideographicparen 16#3221 +/twoinferior 16#2082 +/twomonospace 16#FF12 +/twonumeratorbengali 16#09F5 +/twooldstyle 16#F732 +/twoparen 16#2475 +/twoperiod 16#2489 +/twopersian 16#06F2 +/tworoman 16#2171 +/twostroke 16#01BB +/twosuperior 16#00B2 +/twothai 16#0E52 +/twothirds 16#2154 +/u 16#0075 +/uacute 16#00FA +/ubar 16#0289 +/ubengali 16#0989 +/ubopomofo 16#3128 +/ubreve 16#016D +/ucaron 16#01D4 +/ucircle 16#24E4 +/ucircumflex 16#00FB +/ucircumflexbelow 16#1E77 +/ucyrillic 16#0443 +/udattadeva 16#0951 +/udblacute 16#0171 +/udblgrave 16#0215 +/udeva 16#0909 +/udieresis 16#00FC +/udieresisacute 16#01D8 +/udieresisbelow 16#1E73 +/udieresiscaron 16#01DA +/udieresiscyrillic 16#04F1 +/udieresisgrave 16#01DC +/udieresismacron 16#01D6 +/udotbelow 16#1EE5 +/ugrave 16#00F9 +/ugujarati 16#0A89 +/ugurmukhi 16#0A09 +/uhiragana 16#3046 +/uhookabove 16#1EE7 +/uhorn 16#01B0 +/uhornacute 16#1EE9 +/uhorndotbelow 16#1EF1 +/uhorngrave 16#1EEB +/uhornhookabove 16#1EED +/uhorntilde 16#1EEF +/uhungarumlaut 16#0171 +/uhungarumlautcyrillic 16#04F3 +/uinvertedbreve 16#0217 +/ukatakana 16#30A6 +/ukatakanahalfwidth 16#FF73 +/ukcyrillic 16#0479 +/ukorean 16#315C +/umacron 16#016B +/umacroncyrillic 16#04EF +/umacrondieresis 16#1E7B +/umatragurmukhi 16#0A41 +/umonospace 16#FF55 +/underscore 16#005F +/underscoredbl 16#2017 +/underscoremonospace 16#FF3F +/underscorevertical 16#FE33 +/underscorewavy 16#FE4F +/union 16#222A +/universal 16#2200 +/uogonek 16#0173 +/uparen 16#24B0 +/upblock 16#2580 +/upperdothebrew 16#05C4 +/upsilon 16#03C5 +/upsilondieresis 16#03CB +/upsilondieresistonos 16#03B0 +/upsilonlatin 16#028A +/upsilontonos 16#03CD +/uptackbelowcmb 16#031D +/uptackmod 16#02D4 +/uragurmukhi 16#0A73 +/uring 16#016F +/ushortcyrillic 16#045E +/usmallhiragana 16#3045 +/usmallkatakana 16#30A5 +/usmallkatakanahalfwidth 16#FF69 +/ustraightcyrillic 16#04AF +/ustraightstrokecyrillic 16#04B1 +/utilde 16#0169 +/utildeacute 16#1E79 +/utildebelow 16#1E75 +/uubengali 16#098A +/uudeva 16#090A +/uugujarati 16#0A8A +/uugurmukhi 16#0A0A +/uumatragurmukhi 16#0A42 +/uuvowelsignbengali 16#09C2 +/uuvowelsigndeva 16#0942 +/uuvowelsigngujarati 16#0AC2 +/uvowelsignbengali 16#09C1 +/uvowelsigndeva 16#0941 +/uvowelsigngujarati 16#0AC1 +/v 16#0076 +/vadeva 16#0935 +/vagujarati 16#0AB5 +/vagurmukhi 16#0A35 +/vakatakana 16#30F7 +/vav 16#05D5 +/vavdagesh 16#FB35 +/vavdagesh65 16#FB35 +/vavdageshhebrew 16#FB35 +/vavhebrew 16#05D5 +/vavholam 16#FB4B +/vavholamhebrew 16#FB4B +/vavvavhebrew 16#05F0 +/vavyodhebrew 16#05F1 +/vcircle 16#24E5 +/vdotbelow 16#1E7F +/vecyrillic 16#0432 +/veharabic 16#06A4 +/vehfinalarabic 16#FB6B +/vehinitialarabic 16#FB6C +/vehmedialarabic 16#FB6D +/vekatakana 16#30F9 +/venus 16#2640 +/verticalbar 16#007C +/verticallineabovecmb 16#030D +/verticallinebelowcmb 16#0329 +/verticallinelowmod 16#02CC +/verticallinemod 16#02C8 +/vewarmenian 16#057E +/vhook 16#028B +/vikatakana 16#30F8 +/viramabengali 16#09CD +/viramadeva 16#094D +/viramagujarati 16#0ACD +/visargabengali 16#0983 +/visargadeva 16#0903 +/visargagujarati 16#0A83 +/vmonospace 16#FF56 +/voarmenian 16#0578 +/voicediterationhiragana 16#309E +/voicediterationkatakana 16#30FE +/voicedmarkkana 16#309B +/voicedmarkkanahalfwidth 16#FF9E +/vokatakana 16#30FA +/vparen 16#24B1 +/vtilde 16#1E7D +/vturned 16#028C +/vuhiragana 16#3094 +/vukatakana 16#30F4 +/w 16#0077 +/wacute 16#1E83 +/waekorean 16#3159 +/wahiragana 16#308F +/wakatakana 16#30EF +/wakatakanahalfwidth 16#FF9C +/wakorean 16#3158 +/wasmallhiragana 16#308E +/wasmallkatakana 16#30EE +/wattosquare 16#3357 +/wavedash 16#301C +/wavyunderscorevertical 16#FE34 +/wawarabic 16#0648 +/wawfinalarabic 16#FEEE +/wawhamzaabovearabic 16#0624 +/wawhamzaabovefinalarabic 16#FE86 +/wbsquare 16#33DD +/wcircle 16#24E6 +/wcircumflex 16#0175 +/wdieresis 16#1E85 +/wdotaccent 16#1E87 +/wdotbelow 16#1E89 +/wehiragana 16#3091 +/weierstrass 16#2118 +/wekatakana 16#30F1 +/wekorean 16#315E +/weokorean 16#315D +/wgrave 16#1E81 +/whitebullet 16#25E6 +/whitecircle 16#25CB +/whitecircleinverse 16#25D9 +/whitecornerbracketleft 16#300E +/whitecornerbracketleftvertical 16#FE43 +/whitecornerbracketright 16#300F +/whitecornerbracketrightvertical 16#FE44 +/whitediamond 16#25C7 +/whitediamondcontainingblacksmalldiamond 16#25C8 +/whitedownpointingsmalltriangle 16#25BF +/whitedownpointingtriangle 16#25BD +/whiteleftpointingsmalltriangle 16#25C3 +/whiteleftpointingtriangle 16#25C1 +/whitelenticularbracketleft 16#3016 +/whitelenticularbracketright 16#3017 +/whiterightpointingsmalltriangle 16#25B9 +/whiterightpointingtriangle 16#25B7 +/whitesmallsquare 16#25AB +/whitesmilingface 16#263A +/whitesquare 16#25A1 +/whitestar 16#2606 +/whitetelephone 16#260F +/whitetortoiseshellbracketleft 16#3018 +/whitetortoiseshellbracketright 16#3019 +/whiteuppointingsmalltriangle 16#25B5 +/whiteuppointingtriangle 16#25B3 +/wihiragana 16#3090 +/wikatakana 16#30F0 +/wikorean 16#315F +/wmonospace 16#FF57 +/wohiragana 16#3092 +/wokatakana 16#30F2 +/wokatakanahalfwidth 16#FF66 +/won 16#20A9 +/wonmonospace 16#FFE6 +/wowaenthai 16#0E27 +/wparen 16#24B2 +/wring 16#1E98 +/wsuperior 16#02B7 +/wturned 16#028D +/wynn 16#01BF +/x 16#0078 +/xabovecmb 16#033D +/xbopomofo 16#3112 +/xcircle 16#24E7 +/xdieresis 16#1E8D +/xdotaccent 16#1E8B +/xeharmenian 16#056D +/xi 16#03BE +/xmonospace 16#FF58 +/xparen 16#24B3 +/xsuperior 16#02E3 +/y 16#0079 +/yaadosquare 16#334E +/yabengali 16#09AF +/yacute 16#00FD +/yadeva 16#092F +/yaekorean 16#3152 +/yagujarati 16#0AAF +/yagurmukhi 16#0A2F +/yahiragana 16#3084 +/yakatakana 16#30E4 +/yakatakanahalfwidth 16#FF94 +/yakorean 16#3151 +/yamakkanthai 16#0E4E +/yasmallhiragana 16#3083 +/yasmallkatakana 16#30E3 +/yasmallkatakanahalfwidth 16#FF6C +/yatcyrillic 16#0463 +/ycircle 16#24E8 +/ycircumflex 16#0177 +/ydieresis 16#00FF +/ydotaccent 16#1E8F +/ydotbelow 16#1EF5 +/yeharabic 16#064A +/yehbarreearabic 16#06D2 +/yehbarreefinalarabic 16#FBAF +/yehfinalarabic 16#FEF2 +/yehhamzaabovearabic 16#0626 +/yehhamzaabovefinalarabic 16#FE8A +/yehhamzaaboveinitialarabic 16#FE8B +/yehhamzaabovemedialarabic 16#FE8C +/yehinitialarabic 16#FEF3 +/yehmedialarabic 16#FEF4 +/yehmeeminitialarabic 16#FCDD +/yehmeemisolatedarabic 16#FC58 +/yehnoonfinalarabic 16#FC94 +/yehthreedotsbelowarabic 16#06D1 +/yekorean 16#3156 +/yen 16#00A5 +/yenmonospace 16#FFE5 +/yeokorean 16#3155 +/yeorinhieuhkorean 16#3186 +/yerahbenyomohebrew 16#05AA +/yerahbenyomolefthebrew 16#05AA +/yericyrillic 16#044B +/yerudieresiscyrillic 16#04F9 +/yesieungkorean 16#3181 +/yesieungpansioskorean 16#3183 +/yesieungsioskorean 16#3182 +/yetivhebrew 16#059A +/ygrave 16#1EF3 +/yhook 16#01B4 +/yhookabove 16#1EF7 +/yiarmenian 16#0575 +/yicyrillic 16#0457 +/yikorean 16#3162 +/yinyang 16#262F +/yiwnarmenian 16#0582 +/ymonospace 16#FF59 +/yod 16#05D9 +/yoddagesh 16#FB39 +/yoddageshhebrew 16#FB39 +/yodhebrew 16#05D9 +/yodyodhebrew 16#05F2 +/yodyodpatahhebrew 16#FB1F +/yohiragana 16#3088 +/yoikorean 16#3189 +/yokatakana 16#30E8 +/yokatakanahalfwidth 16#FF96 +/yokorean 16#315B +/yosmallhiragana 16#3087 +/yosmallkatakana 16#30E7 +/yosmallkatakanahalfwidth 16#FF6E +/yotgreek 16#03F3 +/yoyaekorean 16#3188 +/yoyakorean 16#3187 +/yoyakthai 16#0E22 +/yoyingthai 16#0E0D +/yparen 16#24B4 +/ypogegrammeni 16#037A +/ypogegrammenigreekcmb 16#0345 +/yr 16#01A6 +/yring 16#1E99 +/ysuperior 16#02B8 +/ytilde 16#1EF9 +/yturned 16#028E +/yuhiragana 16#3086 +/yuikorean 16#318C +/yukatakana 16#30E6 +/yukatakanahalfwidth 16#FF95 +/yukorean 16#3160 +/yusbigcyrillic 16#046B +/yusbigiotifiedcyrillic 16#046D +/yuslittlecyrillic 16#0467 +/yuslittleiotifiedcyrillic 16#0469 +/yusmallhiragana 16#3085 +/yusmallkatakana 16#30E5 +/yusmallkatakanahalfwidth 16#FF6D +/yuyekorean 16#318B +/yuyeokorean 16#318A +/yyabengali 16#09DF +/yyadeva 16#095F +/z 16#007A +/zaarmenian 16#0566 +/zacute 16#017A +/zadeva 16#095B +/zagurmukhi 16#0A5B +/zaharabic 16#0638 +/zahfinalarabic 16#FEC6 +/zahinitialarabic 16#FEC7 +/zahiragana 16#3056 +/zahmedialarabic 16#FEC8 +/zainarabic 16#0632 +/zainfinalarabic 16#FEB0 +/zakatakana 16#30B6 +/zaqefgadolhebrew 16#0595 +/zaqefqatanhebrew 16#0594 +/zarqahebrew 16#0598 +/zayin 16#05D6 +/zayindagesh 16#FB36 +/zayindageshhebrew 16#FB36 +/zayinhebrew 16#05D6 +/zbopomofo 16#3117 +/zcaron 16#017E +/zcircle 16#24E9 +/zcircumflex 16#1E91 +/zcurl 16#0291 +/zdot 16#017C +/zdotaccent 16#017C +/zdotbelow 16#1E93 +/zecyrillic 16#0437 +/zedescendercyrillic 16#0499 +/zedieresiscyrillic 16#04DF +/zehiragana 16#305C +/zekatakana 16#30BC +/zero 16#0030 +/zeroarabic 16#0660 +/zerobengali 16#09E6 +/zerodeva 16#0966 +/zerogujarati 16#0AE6 +/zerogurmukhi 16#0A66 +/zerohackarabic 16#0660 +/zeroinferior 16#2080 +/zeromonospace 16#FF10 +/zerooldstyle 16#F730 +/zeropersian 16#06F0 +/zerosuperior 16#2070 +/zerothai 16#0E50 +/zerowidthjoiner 16#FEFF +/zerowidthnonjoiner 16#200C +/zerowidthspace 16#200B +/zeta 16#03B6 +/zhbopomofo 16#3113 +/zhearmenian 16#056A +/zhebrevecyrillic 16#04C2 +/zhecyrillic 16#0436 +/zhedescendercyrillic 16#0497 +/zhedieresiscyrillic 16#04DD +/zihiragana 16#3058 +/zikatakana 16#30B8 +/zinorhebrew 16#05AE +/zlinebelow 16#1E95 +/zmonospace 16#FF5A +/zohiragana 16#305E +/zokatakana 16#30BE +/zparen 16#24B5 +/zretroflexhook 16#0290 +/zstroke 16#01B6 +/zuhiragana 16#305A +/zukatakana 16#30BA +.dicttomark readonly def + +/ReverseAdobeGlyphList mark + 16#F769 [/Ismall] + 16#263B [/invsmileface /blacksmilingface] + 16#FB48 [/reshdageshhebrew] + 16#A1A [/cagurmukhi] + 16#183 [/btopbar] + 16#F8EC [/parenleftex] + 16#3055 [/sahiragana] + 16#FF27 [/Gmonospace] + 16#562 [/benarmenian] + 16#FCCB [/lamkhahinitialarabic] + 16#2562 [/SF200000] + 16#306 [/brevecmb] + 16#941 [/uvowelsigndeva] + 16#20AA [/sheqelhebrew /sheqel /newsheqelsign /afii57636] + 16#AA [/ordfeminine] + 16#FE4E [/lowlinecenterline] + 16#1E4E [/Otildedieresis] + 16#2489 [/twoperiod] + 16#AC4 [/rrvocalicvowelsigngujarati] + 16#60C [/commaarabic /afii57388] + 16#3B0 [/upsilondieresistonos] + 16#9EB [/fivebengali] + 16#2154 [/twothirds] + 16#154 [/Racute] + 16#3026 [/sixhangzhou] + 16#278F [/sixcircleinversesansserif] + 16#FEF8 [/lamalefhamzaabovefinalarabic] + 16#1EF8 [/Ytilde] + 16#533 [/Gimarmenian] + 16#2D7 [/minusmod] + 16#912 [/oshortdeva] + 16#7B [/braceleft] + 16#F7E4 [/Adieresissmall] + 16#1E1F [/fdotaccent] + 16#45A [/njecyrillic /afii10107] + 16#A95 [/kagujarati] + 16#1FE [/Ostrokeacute /Oslashacute] + 16#30D0 [/bakatakana] + 16#5DD [/finalmemhebrew /finalmem /afii57677] + 16#9BC [/nuktabengali] + 16#125 [/hcircumflex] + 16#F88E [/maitholowrightthai] + 16#1EC9 [/ihookabove] + 16#FC6D [/behnoonfinalarabic] + 16#33D6 [/molsquare] + 16#2A8 [/tccurl] + 16#317A [/sioskiyeokkorean] + 16#4C [/L] + 16#42B [/Yericyrillic /afii10045] + 16#FB94 [/gafinitialarabic] + 16#A66 [/zerogurmukhi] + 16#21CF [/arrowrightdblstroke] + 16#1CF [/Icaron] + 16#30A1 [/asmallkatakana] + 16#FF73 [/ukatakanahalfwidth] + 16#F6DC [/onefitted] + 16#E45 [/lakkhangyaothai] + 16#5AE [/zinorhebrew] + 16#3224 [/fiveideographicparen] + 16#F6 [/odieresis] + 16#FE9A [/thehfinalarabic] + 16#1E9A [/arighthalfring] + 16#24D5 [/fcircle] + 16#4D5 [/aiecyrillic] + 16#33A7 [/moverssquare] + 16#279 [/rturned] + 16#2279 [/notgreaternorless] + 16#314B [/khieukhkorean] + 16#1D [/controlGS] + 16#201D [/quotedblright] + 16#1A0 [/Ohorn] + 16#3072 [/hihiragana] + 16#FF44 [/dmonospace] + 16#E16 [/thothungthai] + 16#57F [/tiwnarmenian] + 16#323 [/dotbelowcomb /dotbelowcmb] + 16#95E [/fadeva] + 16#C7 [/Ccedilla] + 16#1E6B [/tdotaccent] + 16#FE6B [/atsmall] + 16#24A6 [/kparen] + 16#4A6 [/Pemiddlehookcyrillic] + 16#311C [/ebopomofo] + 16#629 [/tehmarbutaarabic /afii57417] + 16#3CD [/upsilontonos] + 16#FB36 [/zayindageshhebrew /zayindagesh] + 16#A08 [/iigurmukhi] + 16#2171 [/tworoman] + 16#171 [/udblacute /uhungarumlaut] + 16#3043 [/ismallhiragana] + 16#FF15 [/fivemonospace] + 16#2550 [/SF430000] + 16#550 [/Reharmenian] + 16#92F [/yadeva] + 16#FE3C [/blacklenticularbracketrightvertical] + 16#1E3C [/Lcircumflexbelow] + 16#477 [/izhitsadblgravecyrillic] + 16#2477 [/fourparen] + 16#3349 [/mirisquare] + 16#AB2 [/lagujarati] + 16#30ED [/rokatakana] + 16#39E [/Xi] + 16#3270 [/tikeutacirclekorean] + 16#142 [/lslash] + 16#3014 [/tortoiseshellbracketleft] + 16#FEE6 [/noonfinalarabic] + 16#1EE6 [/Uhookabove] + 16#2C5 [/arrowheaddownmod] + 16#22C5 [/dotmath] + 16#69 [/i] + 16#6A4 [/veharabic /afii57505] + 16#1E0D [/ddotbelow] + 16#448 [/shacyrillic /afii10090] + 16#A83 [/visargagujarati] + 16#1EC [/Oogonekmacron] + 16#30BE [/zokatakana] + 16#FF90 [/mikatakanahalfwidth] + 16#F6F9 [/Lslashsmall] + 16#25CB [/whitecircle /circle] + 16#9AA [/pabengali] + 16#2113 [/lsquare /afii61289] + 16#113 [/emacron] + 16#FEB7 [/sheeninitialarabic] + 16#1EB7 [/abrevedotbelow] + 16#4F2 [/Uhungarumlautcyrillic] + 16#33C4 [/squarecc] + 16#2296 [/minuscircle] + 16#296 [/glottalstopinverted] + 16#3168 [/nieunpansioskorean] + 16#203A [/guilsinglright] + 16#3A [/colon] + 16#419 [/afii10027 /Iishortcyrillic] + 16#1BD [/tonefive] + 16#308F [/wahiragana] + 16#FF61 [/periodhalfwidth] + 16#F6CA [/Caron] + 16#E33 [/saraamthai] + 16#59C [/gereshaccenthebrew] + 16#340 [/gravetonecmb] + 16#3212 [/mieumaparenkorean] + 16#E4 [/adieresis] + 16#FE88 [/alefhamzabelowfinalarabic] + 16#1E88 [/Wdotbelow] + 16#24C3 [/Ncircle] + 16#4C3 [/Kahookcyrillic] + 16#3395 [/mulsquare] + 16#2267 [/greateroverequal] + 16#267 [/henghook] + 16#3139 [/rieulkorean] + 16#200B [/zerowidthspace] + 16#B [/controlVT] + 16#F774 [/Tsmall] + 16#646 [/noonarabic /afii57446] + 16#3EA [/Gangiacoptic] + 16#A25 [/thagurmukhi] + 16#18E [/Ereversed] + 16#F8F7 [/parenrightex] + 16#3060 [/dahiragana] + 16#FF32 [/Rmonospace] + 16#E04 [/khokhwaithai] + 16#56D [/xeharmenian] + 16#311 [/breveinvertedcmb] + 16#94C [/auvowelsigndeva] + 16#B5 [/mu1 /mu] + 16#6F0 [/zeropersian] + 16#FE59 [/parenleftsmall] + 16#1E59 [/rdotaccent] + 16#2494 [/thirteenperiod] + 16#494 [/Ghemiddlehookcyrillic] + 16#310A [/tbopomofo] + 16#3BB [/lambda] + 16#328D [/ideographwoodcircle] + 16#9F6 [/threenumeratorbengali] + 16#15F [/scedilla] + 16#FF03 [/numbersignmonospace] + 16#53E [/Caarmenian] + 16#91D [/jhadeva] + 16#2086 [/sixinferior] + 16#F7EF [/Idieresissmall] + 16#6C1 [/haaltonearabic /hehaltonearabic] + 16#1E2A [/Hbrevebelow] + 16#2465 [/sixcircle] + 16#465 [/eiotifiedcyrillic] + 16#AA0 [/tthagujarati] + 16#2209 [/notelementof /notelement] + 16#209 [/idblgrave] + 16#30DB [/hokatakana] + 16#5E8 [/resh /reshhebrew /afii57688] + 16#38C [/Omicrontonos] + 16#9C7 [/evowelsignbengali] + 16#130 [/Idotaccent /Idot] + 16#F899 [/nikhahitleftthai] + 16#3002 [/ideographicperiod] + 16#FED4 [/fehmedialarabic] + 16#1ED4 [/Ocircumflexhookabove] + 16#3185 [/ssanghieuhkorean] + 16#57 [/W] + 16#436 [/zhecyrillic /afii10072] + 16#FB9F [/noonghunnafinalarabic] + 16#A71 [/addakgurmukhi] + 16#1DA [/udieresiscaron] + 16#30AC [/gakatakana] + 16#FF7E [/sekatakanahalfwidth] + 16#F6E7 [/periodinferior] + 16#E50 [/zerothai] + 16#25B9 [/whiterightpointingsmalltriangle] + 16#5B9 [/holamwidehebrew /holamquarterhebrew /holamnarrowhebrew /holamhebrew /holam32 /holam26 /holam19 /holam /afii57806] + 16#322F [/ideographicearthparen] + 16#998 [/ghabengali] + 16#101 [/amacron] + 16#1EA5 [/acircumflexacute] + 16#24E0 [/qcircle] + 16#4E0 [/Dzeabkhasiancyrillic] + 16#33B2 [/mussquare] + 16#284 [/dotlessjstrokehook] + 16#2284 [/notsubset] + 16#3156 [/yekorean] + 16#28 [/parenleft] + 16#663 [/threehackarabic /threearabic /afii57395] + 16#2663 [/clubsuitblack /club] + 16#407 [/afii10056 /Yicyrillic] + 16#A42 [/uumatragurmukhi] + 16#1AB [/tpalatalhook] + 16#307D [/pohiragana] + 16#FF4F [/omonospace] + 16#E21 [/momathai] + 16#32E [/brevebelowcmb] + 16#3200 [/kiyeokparenkorean] + 16#969 [/threedeva] + 16#D2 [/Ograve] + 16#1E76 [/Ucircumflexbelow] + 16#4B1 [/ustraightstrokecyrillic] + 16#24B1 [/vparen] + 16#3383 [/masquare] + 16#AEC [/sixgujarati] + 16#255 [/ccurl] + 16#3127 [/ibopomofo] + 16#F762 [/Bsmall] + 16#634 [/sheenarabic /afii57428] + 16#FB41 [/samekhdageshhebrew /samekhdagesh] + 16#A13 [/oogurmukhi] + 16#17C [/zdotaccent /zdot] + 16#F8E5 [/radicalex] + 16#304E [/gihiragana] + 16#FF20 [/atmonospace] + 16#55B [/emphasismarkarmenian] + 16#255B [/SF280000] + 16#20A3 [/franc] + 16#A3 [/sterling] + 16#1E47 [/ndotbelow] + 16#482 [/thousandcyrillic] + 16#2482 [/fifteenparen] + 16#2226 [/notparallel] + 16#30F8 [/vikatakana] + 16#F733 [/threeoldstyle] + 16#2605 [/blackstar] + 16#3A9 [/Omegagreek] + 16#327B [/hieuhacirclekorean] + 16#14D [/omacron] + 16#1EF1 [/uhorndotbelow] + 16#252C [/SF060000] + 16#2D0 [/colontriangularmod] + 16#90B [/rvocalicdeva] + 16#2074 [/foursuperior] + 16#74 [/t] + 16#6AF [/gafarabic /afii57509] + 16#1E18 [/Ecircumflexbelow] + 16#453 [/gjecyrillic /afii10100] + 16#30C9 [/dokatakana] + 16#FF9B [/rokatakanahalfwidth] + 16#5D6 [/zayinhebrew /zayin /afii57670] + 16#FD3F [/parenrightaltonearabic] + 16#37A [/ypogegrammeni] + 16#211E [/prescription] + 16#F887 [/saraueleftthai] + 16#11E [/Gbreve] + 16#FEC2 [/tahfinalarabic] + 16#1EC2 [/Ecircumflexhookabove] + 16#33CF [/ktsquare] + 16#2A1 [/glottalstopstroke] + 16#3173 [/pieuptikeutkorean] + 16#45 [/E] + 16#424 [/afii10038 /Efcyrillic] + 16#FB8D [/rrehfinalarabic] + 16#1C8 [/Lj] + 16#FF6C [/yasmallkatakanahalfwidth] + 16#F6D5 [/cyrflex] + 16#25A7 [/squareupperlefttolowerrightfill] + 16#5A7 [/dargalefthebrew /dargahebrew] + 16#986 [/aabengali] + 16#EF [/idieresis] + 16#1E93 [/zdotbelow] + 16#24CE [/Ycircle] + 16#33A0 [/cmsquaredsquare] + 16#272 [/nhookleft] + 16#2272 [/lessorequivalent] + 16#3144 [/pieupsioskorean] + 16#16 [/controlSYN] + 16#2016 [/dblverticalbar] + 16#651 [/shaddaarabic /afii57457] + 16#A30 [/ragurmukhi] + 16#199 [/khook] + 16#2199 [/arrowdownleft] + 16#306B [/nihiragana] + 16#FF3D [/bracketrightmonospace] + 16#E0F [/topatakthai] + 16#578 [/voarmenian] + 16#31C [/ringhalfleftbelowcmb] + 16#C0 [/Agrave] + 16#FE64 [/lesssmall] + 16#1E64 [/Sacutedotaccent] + 16#49F [/kastrokecyrillic] + 16#249F [/dparen] + 16#FC08 [/behmeemisolatedarabic] + 16#2243 [/asymptoticallyequal] + 16#3115 [/shbopomofo] + 16#622 [/afii57410 /alefmaddaabovearabic] + 16#3C6 [/phi] + 16#FB2F [/alefqamatshebrew] + 16#3298 [/ideographiclaborcircle] + 16#16A [/Umacron] + 16#216A [/Elevenroman] + 16#FF0E [/periodmonospace] + 16#549 [/Chaarmenian] + 16#928 [/nadeva] + 16#F7FA [/Uacutesmall] + 16#FE35 [/parenleftvertical] + 16#1E35 [/klinebelow] + 16#2470 [/seventeencircle] + 16#470 [/Psicyrillic] + 16#3342 [/hoonsquare] + 16#AAB [/phagujarati] + 16#214 [/Udblgrave] + 16#30E6 [/yukatakana] + 16#F721 [/exclamsmall] + 16#5F3 [/gereshhebrew] + 16#397 [/Eta] + 16#FB00 [/ff] + 16#3269 [/chieuchcirclekorean] + 16#13B [/Lcommaaccent /Lcedilla] + 16#300D [/cornerbracketright] + 16#1EDF [/ohornhookabove] + 16#FEDF [/laminitialarabic] + 16#2BE [/ringhalfright] + 16#62 [/b] + 16#1E06 [/Blinebelow] + 16#441 [/escyrillic /afii10083] + 16#1E5 [/gstroke] + 16#21E5 [/arrowtabright] + 16#30B7 [/sikatakana] + 16#FF89 [/nokatakanahalfwidth] + 16#F6F2 [/ssuperior] + 16#E5B [/khomutthai] + 16#5C4 [/upperdothebrew] + 16#25C4 [/triaglf /blackleftpointingpointer] + 16#323A [/ideographiccallparen] + 16#9A3 [/nnabengali] + 16#10C [/Ccaron] + 16#FEB0 [/zainfinalarabic] + 16#1EB0 [/Abrevegrave] + 16#4EB [/obarreddieresiscyrillic] + 16#33BD [/mwsquare] + 16#3161 [/eukorean] + 16#2033 [/second] + 16#33 [/three] + 16#412 [/afii10019 /Vecyrillic] + 16#FB7B [/tchehfinalarabic] + 16#A4D [/halantgurmukhi] + 16#1B6 [/zstroke] + 16#3088 [/yohiragana] + 16#FF5A [/zmonospace] + 16#F6C3 [/commaaccent] + 16#E2C [/lochulathai] + 16#595 [/zaqefgadolhebrew] + 16#339 [/ringhalfrightbelowcmb] + 16#320B [/thieuthparenkorean] + 16#DD [/Yacute] + 16#1E81 [/wgrave] + 16#24BC [/Gcircle] + 16#4BC [/Cheabkhasiancyrillic] + 16#338E [/squaremg] + 16#260 [/ghook] + 16#2260 [/notequal] + 16#3132 [/ssangkiyeokkorean] + 16#4 [/controlEOT] + 16#F76D [/Msmall] + 16#3E3 [/sheicoptic] + 16#FB4C [/betrafehebrew] + 16#A1E [/nyagurmukhi] + 16#187 [/Chook] + 16#F8F0 [/bracketleftbt] + 16#3059 [/suhiragana] + 16#FF2B [/Kmonospace] + 16#566 [/zaarmenian] + 16#2566 [/SF410000] + 16#30A [/ringcmb] + 16#945 [/ecandravowelsigndeva] + 16#AE [/registered] + 16#FE52 [/periodsmall] + 16#1E52 [/Omacronacute] + 16#248D [/sixperiod] + 16#AC8 [/aivowelsigngujarati] + 16#3B4 [/delta] + 16#9EF [/ninebengali] + 16#158 [/Rcaron] + 16#FEFC [/lamaleffinalarabic] + 16#537 [/Eharmenian] + 16#22DB [/greaterequalorless] + 16#2DB [/ogonek] + 16#916 [/khadeva] + 16#207F [/nsuperior] + 16#7F [/controlDEL] + 16#F7E8 [/Egravesmall] + 16#6BA [/noonghunnaarabic /afii57514] + 16#1E23 [/hdotaccent] + 16#45E [/ushortcyrillic /afii10110] + 16#A99 [/ngagujarati] + 16#202 [/Ainvertedbreve] + 16#2202 [/partialdiff] + 16#30D4 [/pikatakana] + 16#5E1 [/samekhhebrew /samekh /afii57681] + 16#385 [/dialytikatonos /dieresistonos] + 16#9C0 [/iivowelsignbengali] + 16#129 [/itilde] + 16#F892 [/maitrilowleftthai] + 16#1ECD [/odotbelow] + 16#317E [/sioscieuckorean] + 16#50 [/P] + 16#42F [/afii10049 /IAcyrillic] + 16#A6A [/fourgurmukhi] + 16#1D3 [/Ucaron] + 16#21D3 [/arrowdbldown] + 16#30A5 [/usmallkatakana] + 16#FF77 [/kikatakanahalfwidth] + 16#F6E0 [/centsuperior] + 16#E49 [/maithothai] + 16#25B2 [/triagup /blackuppointingtriangle] + 16#5B2 [/hatafpatahquarterhebrew /hatafpatahnarrowhebrew /hatafpatahhebrew /hatafpatah2f /hatafpatah23 /hatafpatah16 /hatafpatah /hatafpatahwidehebrew /afii57800] + 16#3228 [/nineideographicparen] + 16#FA [/uacute] + 16#FE9E [/jeemfinalarabic] + 16#4D9 [/schwacyrillic /afii10846] + 16#24D9 [/jcircle] + 16#33AB [/mpasquare] + 16#27D [/rhook] + 16#314F [/akorean] + 16#2021 [/daggerdbl] + 16#21 [/exclam] + 16#FB69 [/ttehmedialarabic] + 16#1A4 [/Phook] + 16#3076 [/buhiragana] + 16#FF48 [/hmonospace] + 16#E1A [/bobaimaithai] + 16#583 [/piwrarmenian] + 16#327 [/cedillacmb] + 16#2327 [/clear] + 16#962 [/lvocalicvowelsigndeva] + 16#CB [/Edieresis] + 16#1E6F [/tlinebelow] + 16#24AA [/oparen] + 16#4AA [/Esdescendercyrillic] + 16#337C [/syouwaerasquare] + 16#3120 [/aubopomofo] + 16#62D [/haharabic /afii57421] + 16#3D1 [/thetasymbolgreek /theta1] + 16#FB3A [/finalkafdageshhebrew /finalkafdagesh] + 16#32A3 [/ideographiccorrectcircle] + 16#175 [/wcircumflex] + 16#2175 [/sixroman] + 16#3047 [/esmallhiragana] + 16#FF19 [/ninemonospace] + 16#554 [/Keharmenian] + 16#2554 [/SF390000] + 16#933 [/lladeva] + 16#FE40 [/anglebracketrightvertical] + 16#1E40 [/Mdotaccent] + 16#47B [/omegaroundcyrillic] + 16#247B [/eightparen] + 16#334D [/meetorusquare] + 16#AB6 [/shagujarati] + 16#221F [/rightangle /orthogonal] + 16#30F1 [/wekatakana] + 16#3274 [/siosacirclekorean] + 16#9DD [/rhabengali] + 16#146 [/ncommaaccent /ncedilla] + 16#3018 [/whitetortoiseshellbracketleft] + 16#FEEA [/hehfinalarabic /hehfinalalttwoarabic] + 16#1EEA [/Uhorngrave] + 16#2C9 [/firsttonechinese] + 16#6D [/m] + 16#1E11 [/dcedilla] + 16#44C [/softsigncyrillic /afii10094] + 16#331E [/kooposquare] + 16#A87 [/igujarati] + 16#1F0 [/jcaron] + 16#30C2 [/dikatakana] + 16#FF94 [/yakatakanahalfwidth] + 16#F6FD [/Scaronsmall] + 16#25CF [/blackcircle /H18533] + 16#9AE [/mabengali] + 16#117 [/edotaccent /edot] + 16#FEBB [/sadinitialarabic] + 16#1EBB [/ehookabove] + 16#FC5F [/shaddakasratanarabic] + 16#33C8 [/dbsquare] + 16#29A [/eopenclosed] + 16#316C [/rieulpansioskorean] + 16#203E [/overline] + 16#3E [/greater] + 16#679 [/tteharabic /afii57511] + 16#41D [/afii10031 /Encyrillic] + 16#1C1 [/clicklateral] + 16#3093 [/nhiragana] + 16#FF65 [/middledotkatakanahalfwidth] + 16#F6CE [/Grave] + 16#E37 [/saraueethai] + 16#5A0 [/telishagedolahebrew] + 16#25A0 [/blacksquare /filledbox] + 16#344 [/dialytikatonoscmb] + 16#3216 [/cieucaparenkorean] + 16#E8 [/egrave] + 16#FE8C [/yehhamzaabovemedialarabic] + 16#1E8C [/Xdieresis] + 16#24C7 [/Rcircle] + 16#4C7 [/Enhookcyrillic] + 16#3399 [/fmsquare] + 16#226B [/muchgreater] + 16#26B [/lmiddletilde] + 16#313D [/rieulsioskorean] + 16#F [/controlSI] + 16#200F [/afii300] + 16#F778 [/Xsmall] + 16#64A [/yeharabic /afii57450] + 16#3EE [/Deicoptic] + 16#FB57 [/pehfinalarabic] + 16#192 [/florin] + 16#F8FB [/bracketrightbt] + 16#3064 [/tuhiragana] + 16#2192 [/arrowright] + 16#FF36 [/Vmonospace] + 16#E08 [/chochanthai] + 16#571 [/jaarmenian] + 16#315 [/commaaboverightcmb] + 16#950 [/omdeva] + 16#B9 [/onesuperior] + 16#6F4 [/fourpersian] + 16#FE5D [/tortoiseshellbracketleftsmall] + 16#1E5D [/rdotbelowmacron] + 16#2498 [/seventeenperiod] + 16#498 [/Zedescendercyrillic] + 16#223C [/tildeoperator /similar] + 16#310E [/kbopomofo] + 16#FFE0 [/centmonospace] + 16#61B [/semicolonarabic /afii57403] + 16#3BF [/omicron] + 16#9FA [/issharbengali] + 16#163 [/tcedilla /tcommaaccent] + 16#2163 [/Fourroman] + 16#279E [/arrowrightheavy] + 16#FF07 [/quotesinglemonospace] + 16#542 [/Ghadarmenian] + 16#2E6 [/tonebarhighmod] + 16#921 [/ddadeva] + 16#F7F3 [/Oacutesmall] + 16#1E2E [/Idieresisacute] + 16#469 [/yuslittleiotifiedcyrillic] + 16#2469 [/tencircle] + 16#333B [/peezisquare] + 16#AA4 [/tagujarati] + 16#20D [/odblgrave] + 16#30DF [/mikatakana] + 16#390 [/iotadieresistonos] + 16#3262 [/tikeutcirclekorean] + 16#9CB [/ovowelsignbengali] + 16#134 [/Jcircumflex] + 16#3006 [/ideographicclose] + 16#FED8 [/qafmedialarabic] + 16#1ED8 [/Ocircumflexdotbelow] + 16#2B7 [/wsuperior] + 16#3189 [/yoikorean] + 16#5B [/bracketleft] + 16#43A [/kacyrillic /afii10076] + 16#21DE [/pageup] + 16#1DE [/Adieresismacron] + 16#30B0 [/gukatakana] + 16#FF82 [/tukatakanahalfwidth] + 16#F6EB [/dsuperior] + 16#E54 [/fourthai] + 16#25BD [/whitedownpointingtriangle] + 16#5BD [/siluqlefthebrew /siluqhebrew /afii57839] + 16#361 [/breveinverteddoublecmb] + 16#3233 [/ideographicsocietyparen] + 16#99C [/jabengali] + 16#2105 [/careof /afii61248] + 16#105 [/aogonek] + 16#1EA9 [/acircumflexhookabove] + 16#24E4 [/ucircle] + 16#4E4 [/Idieresiscyrillic] + 16#33B6 [/muvsquare] + 16#288 [/tretroflexhook] + 16#315A [/oekorean] + 16#202C [/afii61573] + 16#2C [/comma] + 16#667 [/sevenhackarabic /sevenarabic /afii57399] + 16#2667 [/clubsuitwhite] + 16#40B [/afii10060 /Tshecyrillic] + 16#1AF [/Uhorn] + 16#3081 [/mehiragana] + 16#FF53 [/smonospace] + 16#E25 [/lolingthai] + 16#332 [/lowlinecmb] + 16#3204 [/mieumparenkorean] + 16#96D [/sevendeva] + 16#D6 [/Odieresis] + 16#1E7A [/Umacrondieresis] + 16#24B5 [/zparen] + 16#4B5 [/tetsecyrillic] + 16#3387 [/GBsquare] + 16#259 [/schwa] + 16#F766 [/Fsmall] + 16#638 [/zaharabic /afii57432] + 16#3DC [/Digammagreek] + 16#A17 [/gagurmukhi] + 16#180 [/bstroke] + 16#F8E9 [/copyrightsans] + 16#3052 [/gehiragana] + 16#FF24 [/Dmonospace] + 16#55F [/abbreviationmarkarmenian] + 16#255F [/SF370000] + 16#303 [/tildecomb /tildecmb] + 16#2303 [/control] + 16#93E [/aavowelsigndeva] + 16#20A7 [/peseta] + 16#A7 [/section] + 16#FE4B [/overlinewavy] + 16#1E4B [/ncircumflexbelow] + 16#486 [/psilipneumatacyrilliccmb] + 16#2486 [/nineteenparen] + 16#AC1 [/uvowelsigngujarati] + 16#222A [/union] + 16#30FC [/prolongedkana] + 16#F737 [/sevenoldstyle] + 16#3AD [/epsilontonos] + 16#327F [/koreanstandardsymbol] + 16#9E8 [/twobengali] + 16#151 [/odblacute /ohungarumlaut] + 16#3023 [/threehangzhou] + 16#278C [/threecircleinversesansserif] + 16#1EF5 [/ydotbelow] + 16#FEF5 [/lamalefmaddaaboveisolatedarabic] + 16#2D4 [/uptackmod] + 16#90F [/edeva] + 16#2078 [/eightsuperior] + 16#F7E1 [/Aacutesmall] + 16#78 [/x] + 16#1E1C [/Ecedillabreve] + 16#457 [/yicyrillic /afii10104] + 16#1FB [/aringacute] + 16#30CD [/nekatakana] + 16#FF9F [/semivoicedmarkkanahalfwidth] + 16#5DA [/finalkafhebrew /finalkaf /afii57674] + 16#37E [/questiongreek] + 16#9B9 [/habengali] + 16#2122 [/trademark] + 16#F88B [/maieklowrightthai] + 16#122 [/Gcommaaccent /Gcedilla] + 16#FEC6 [/zahfinalarabic] + 16#1EC6 [/Ecircumflexdotbelow] + 16#33D3 [/lxsquare] + 16#2A5 [/dzcurl] + 16#22A5 [/perpendicular] + 16#3177 [/pieupthieuthkorean] + 16#49 [/I] + 16#428 [/afii10042 /Shacyrillic] + 16#1CC [/nj] + 16#309E [/voicediterationhiragana] + 16#FF70 [/katahiraprolongmarkhalfwidth] + 16#F6D9 [/copyrightserif] + 16#E42 [/saraothai] + 16#25AB [/whitesmallsquare /H18551] + 16#5AB [/olehebrew] + 16#3221 [/twoideographicparen] + 16#98A [/uubengali] + 16#F3 [/oacute] + 16#FE97 [/tehinitialarabic] + 16#1E97 [/tdieresis] + 16#24D2 [/ccircle] + 16#4D2 [/Adieresiscyrillic] + 16#33A4 [/cmcubedsquare] + 16#2276 [/lessorgreater] + 16#3148 [/cieuckorean] + 16#1A [/controlSUB] + 16#201A [/quotesinglbase] + 16#19D [/Nhookleft] + 16#306F [/hahiragana] + 16#FF41 [/amonospace] + 16#E13 [/nonenthai] + 16#57C [/raarmenian] + 16#320 [/minusbelowcmb] + 16#2320 [/integraltop /integraltp] + 16#95B [/zadeva] + 16#C4 [/Adieresis] + 16#1E68 [/Sdotbelowdotaccent] + 16#24A3 [/hparen] + 16#FC0C [/tehhahisolatedarabic] + 16#4A3 [/endescendercyrillic] + 16#3119 [/sbopomofo] + 16#626 [/yehhamzaabovearabic /afii57414] + 16#3CA [/iotadieresis] + 16#FB33 [/daletdageshhebrew /daletdagesh] + 16#A05 [/agurmukhi] + 16#16E [/Uring] + 16#FF12 [/twomonospace] + 16#54D [/Seharmenian] + 16#92C [/badeva] + 16#F7FE [/Thornsmall] + 16#FE39 [/tortoiseshellbracketleftvertical] + 16#1E39 [/ldotbelowmacron] + 16#2474 [/oneparen] + 16#474 [/afii10148 /Izhitsacyrillic] + 16#AAF [/yagujarati] + 16#218 [/Scommaaccent] + 16#30EA [/rikatakana] + 16#39B [/Lambda] + 16#FB04 [/ffl] + 16#326D [/hieuhcirclekorean] + 16#13F [/Ldotaccent /Ldot] + 16#3011 [/blacklenticularbracketright] + 16#1EE3 [/ohorndotbelow] + 16#FEE3 [/meeminitialarabic] + 16#2C2 [/arrowheadleftmod] + 16#66 [/f] + 16#1E0A [/Ddotaccent] + 16#445 [/khacyrillic /afii10087] + 16#1E9 [/kcaron] + 16#21E9 [/arrowdownwhite] + 16#30BB [/sekatakana] + 16#FF8D [/hekatakanahalfwidth] + 16#F6F6 [/Circumflexsmall] + 16#25C8 [/whitediamondcontainingblacksmalldiamond] + 16#323E [/ideographicresourceparen] + 16#9A7 [/dhabengali] + 16#110 [/Dslash /Dcroat] + 16#FEB4 [/seenmedialarabic] + 16#1EB4 [/Abrevetilde] + 16#4EF [/umacroncyrillic] + 16#FC58 [/yehmeemisolatedarabic] + 16#33C1 [/mohmsquare] + 16#293 [/ezhcurl] + 16#3165 [/ssangnieunkorean] + 16#37 [/seven] + 16#416 [/Zhecyrillic /afii10024] + 16#1BA [/ezhtail] + 16#308C [/rehiragana] + 16#FF5E [/asciitildemonospace] + 16#F6C7 [/afii10831] + 16#E30 [/saraathai] + 16#599 [/pashtahebrew] + 16#33D [/xabovecmb] + 16#320F [/nieunaparenkorean] + 16#E1 [/aacute] + 16#1E85 [/wdieresis] + 16#4C0 [/palochkacyrillic] + 16#24C0 [/Kcircle] + 16#3392 [/mhzsquare] + 16#264 [/ramshorn] + 16#2264 [/lessequal] + 16#3136 [/nieunhieuhkorean] + 16#8 [/controlBS] + 16#F771 [/Qsmall] + 16#643 [/kafarabic /afii57443] + 16#3E7 [/kheicoptic] + 16#A22 [/ddhagurmukhi] + 16#18B [/Dtopbar] + 16#F8F4 [/braceex] + 16#305D [/sohiragana] + 16#FF2F [/Omonospace] + 16#E01 [/kokaithai] + 16#56A [/zhearmenian] + 16#256A [/SF540000] + 16#30E [/dblverticallineabovecmb] + 16#949 [/ocandravowelsigndeva] + 16#B2 [/twosuperior] + 16#1E56 [/Pdotaccent] + 16#2491 [/tenperiod] + 16#491 [/gheupturncyrillic /afii10098] + 16#ACC [/auvowelsigngujarati] + 16#2235 [/because] + 16#3107 [/mbopomofo] + 16#3B8 [/theta] + 16#328A [/ideographmooncircle] + 16#9F3 [/rupeesignbengali] + 16#215C [/threeeighths] + 16#15C [/Scircumflex] + 16#53B [/Iniarmenian] + 16#FCA4 [/tehmeeminitialarabic] + 16#91A [/cadeva] + 16#2083 [/threeinferior] + 16#F7EC [/Igravesmall] + 16#1E27 [/hdieresis] + 16#2462 [/threecircle] + 16#462 [/afii10146 /Yatcyrillic] + 16#A9D [/jhagujarati] + 16#2206 [/increment /Delta] + 16#206 [/Einvertedbreve] + 16#30D8 [/hekatakana] + 16#5E5 [/finaltsadihebrew /finaltsadi /afii57685] + 16#25E5 [/blackupperrighttriangle] + 16#389 [/Etatonos] + 16#9C4 [/rrvocalicvowelsignbengali] + 16#12D [/ibreve] + 16#F896 [/thanthakhatupperleftthai] + 16#1ED1 [/ocircumflexacute] + 16#250C [/SF010000] + 16#2B0 [/hsuperior] + 16#3182 [/yesieungsioskorean] + 16#54 [/T] + 16#433 [/gecyrillic /afii10068] + 16#3305 [/intisquare] + 16#A6E [/eightgurmukhi] + 16#1D7 [/Udieresisacute] + 16#30A9 [/osmallkatakana] + 16#FF7B [/sakatakanahalfwidth] + 16#F6E4 [/dollarsuperior] + 16#E4D [/nikhahitthai] + 16#5B6 [/segolwidehebrew /segolquarterhebrew /segolnarrowhebrew /segolhebrew /segol2c /segol1f /segol13 /segol /afii57795] + 16#25B6 [/blackrightpointingtriangle] + 16#322C [/ideographicwaterparen] + 16#995 [/kabengali] + 16#FE [/thorn] + 16#FEA2 [/hahfinalarabic] + 16#1EA2 [/Ahookabove] + 16#4DD [/zhedieresiscyrillic] + 16#24DD [/ncircle] + 16#33AF [/radoverssquaredsquare] + 16#2281 [/notsucceeds] + 16#281 [/Rsmallinverted] + 16#3153 [/eokorean] + 16#2025 [/twodotleader /twodotenleader] + 16#25 [/percent] + 16#660 [/zerohackarabic /zeroarabic /afii57392] + 16#2660 [/spadesuitblack /spade] + 16#404 [/afii10053 /Ecyrillic] + 16#FB6D [/vehmedialarabic] + 16#A3F [/imatragurmukhi] + 16#1A8 [/tonetwo] + 16#21A8 [/arrowupdownbase /arrowupdnbse] + 16#307A [/pehiragana] + 16#FF4C [/lmonospace] + 16#E1E [/phophanthai] + 16#587 [/echyiwnarmenian] + 16#32B [/dblarchinvertedbelowcmb] + 16#232B [/deleteleft] + 16#966 [/zerodeva] + 16#CF [/Idieresis] + 16#1E73 [/udieresisbelow] + 16#24AE [/sparen] + 16#4AE [/Ustraightcyrillic] + 16#3380 [/paampssquare] + 16#AE9 [/threegujarati] + 16#252 [/ascriptturned] + 16#2252 [/approxequalorimage] + 16#3124 [/angbopomofo] + 16#631 [/reharabic /afii57425] + 16#3D5 [/phisymbolgreek /phi1] + 16#FB3E [/memdageshhebrew /memdagesh] + 16#32A7 [/ideographicleftcircle] + 16#A10 [/aigurmukhi] + 16#2179 [/tenroman] + 16#179 [/Zacute] + 16#304B [/kahiragana] + 16#FF1D [/equalmonospace] + 16#2558 [/SF500000] + 16#937 [/ssadeva] + 16#A0 [/nonbreakingspace /nbspace] + 16#FE44 [/whitecornerbracketrightvertical] + 16#1E44 [/Ndotaccent] + 16#247F [/twelveparen] + 16#47F [/otcyrillic] + 16#3351 [/rittorusquare] + 16#2223 [/divides] + 16#30F5 [/kasmallkatakana] + 16#F730 [/zerooldstyle] + 16#3A6 [/Phi] + 16#3278 [/khieukhacirclekorean] + 16#9E1 [/llvocalicbengali] + 16#14A [/Eng] + 16#301C [/wavedash] + 16#FEEE [/wawfinalarabic] + 16#1EEE [/Uhorntilde] + 16#2CD [/macronlowmod] + 16#908 [/iideva] + 16#71 [/q] + 16#1E15 [/emacrongrave] + 16#3322 [/sentisquare] + 16#A8B [/rvocalicgujarati] + 16#1F4 [/Gacute] + 16#30C6 [/tekatakana] + 16#FF98 [/rikatakanahalfwidth] + 16#5D3 [/dalethebrew /dalet /afii57667] + 16#9B2 [/labengali] + 16#11B [/ecaron] + 16#F884 [/maihanakatleftthai] + 16#1EBF [/ecircumflexacute] + 16#FEBF [/dadinitialarabic] + 16#29E [/kturned] + 16#3170 [/mieumpansioskorean] + 16#2042 [/asterism] + 16#42 [/B] + 16#421 [/afii10035 /Escyrillic] + 16#A5C [/rragurmukhi] + 16#21C5 [/arrowupleftofdown] + 16#1C5 [/Dzcaron] + 16#FF69 [/usmallkatakanahalfwidth] + 16#F6D2 [/cyrFlex] + 16#25A4 [/squarehorizontalfill] + 16#5A4 [/mahapakhlefthebrew /mahapakhhebrew] + 16#321A [/phieuphaparenkorean] + 16#983 [/visargabengali] + 16#EC [/igrave] + 16#FE90 [/behfinalarabic] + 16#1E90 [/Zcircumflex] + 16#24CB [/Vcircle] + 16#4CB [/Chekhakassiancyrillic] + 16#339D [/squarecm] + 16#26F [/mturned] + 16#226F [/notgreater] + 16#3141 [/mieumkorean] + 16#13 [/controlDC3] + 16#2013 [/endash] + 16#64E [/fathalowarabic /fathaarabic /afii57454] + 16#3F2 [/sigmalunatesymbolgreek] + 16#A2D [/bhagurmukhi] + 16#2196 [/arrowupleft] + 16#F8FF [/apple] + 16#3068 [/tohiragana] + 16#196 [/Iotaafrican] + 16#FF3A [/Zmonospace] + 16#E0C [/chochoethai] + 16#575 [/yiarmenian] + 16#319 [/righttackbelowcmb] + 16#954 [/acutedeva] + 16#BD [/onehalf] + 16#6F8 [/eightpersian] + 16#1E61 [/sdotaccent] + 16#FE61 [/asterisksmall] + 16#249C [/aparen] + 16#49C [/Kaverticalstrokecyrillic] + 16#3112 [/xbopomofo] + 16#261F [/pointingindexdownwhite] + 16#61F [/questionarabic /afii57407] + 16#FD88 [/lammeemhahinitialarabic] + 16#3C3 [/sigma] + 16#FB2C [/shindageshshindothebrew /shindageshshindot] + 16#167 [/tbar] + 16#2167 [/Eightroman] + 16#FF0B [/plusmonospace] + 16#546 [/Nowarmenian] + 16#925 [/thadeva] + 16#208E [/parenrightinferior] + 16#FE32 [/endashvertical] + 16#1E32 [/Kdotbelow] + 16#46D [/yusbigiotifiedcyrillic] + 16#246D [/fourteencircle] + 16#AA8 [/nagujarati] + 16#211 [/rdblgrave] + 16#2211 [/summation] + 16#30E3 [/yasmallkatakana] + 16#5F0 [/vavvavhebrew /afii57716] + 16#394 [/Deltagreek] + 16#3266 [/sioscirclekorean] + 16#138 [/kgreenlandic] + 16#300A [/dblanglebracketleft] + 16#FEDC [/kafmedialarabic] + 16#1EDC [/Ohorngrave] + 16#2BB [/commaturnedmod] + 16#318D [/araeakorean] + 16#5F [/underscore] + 16#1E03 [/bdotaccent] + 16#43E [/ocyrillic /afii10080] + 16#FBA7 [/hehfinalaltonearabic] + 16#21E2 [/arrowdashright] + 16#1E2 [/AEmacron] + 16#30B4 [/gokatakana] + 16#FF86 [/nikatakanahalfwidth] + 16#F6EF [/msuperior] + 16#E58 [/eightthai] + 16#25C1 [/whiteleftpointingtriangle] + 16#5C1 [/shindothebrew /afii57804] + 16#3237 [/ideographiccongratulationparen] + 16#9A0 [/tthabengali] + 16#2109 [/fahrenheit] + 16#109 [/ccircumflex] + 16#1EAD [/acircumflexdotbelow] + 16#24E8 [/ycircle] + 16#4E8 [/Obarredcyrillic] + 16#33BA [/pwsquare] + 16#28C [/vturned] + 16#315E [/wekorean] + 16#2030 [/perthousand] + 16#30 [/zero] + 16#266B [/musicalnotedbl /eighthnotebeamed] + 16#66B [/decimalseparatorpersian /decimalseparatorarabic] + 16#40F [/afii10145 /Dzhecyrillic] + 16#1B3 [/Yhook] + 16#3085 [/yusmallhiragana] + 16#FF57 [/wmonospace] + 16#F6C0 [/ll] + 16#E29 [/sorusithai] + 16#2592 [/shademedium /shade] + 16#592 [/segoltahebrew] + 16#336 [/strokelongoverlaycmb] + 16#3208 [/cieucparenkorean] + 16#DA [/Uacute] + 16#1E7E [/Vdotbelow] + 16#4B9 [/cheverticalstrokecyrillic] + 16#24B9 [/Dcircle] + 16#338B [/nfsquare] + 16#25D [/eopenreversedhook] + 16#1 [/controlSTX] + 16#F76A [/Jsmall] + 16#263C [/sun /compass] + 16#3E0 [/Sampigreek] + 16#FB49 [/shindageshhebrew /shindagesh] + 16#A1B [/chagurmukhi] + 16#184 [/Tonesix] + 16#F8ED [/parenleftbt] + 16#3056 [/zahiragana] + 16#FF28 [/Hmonospace] + 16#563 [/gimarmenian] + 16#FCCC [/lammeeminitialarabic] + 16#2563 [/SF230000] + 16#307 [/dotaccentcmb] + 16#942 [/uuvowelsigndeva] + 16#20AB [/dong] + 16#AB [/guillemotleft] + 16#FE4F [/underscorewavy] + 16#1E4F [/otildedieresis] + 16#248A [/threeperiod] + 16#AC5 [/ecandravowelsigngujarati] + 16#222E [/contourintegral] + 16#3B1 [/alpha] + 16#9EC [/sixbengali] + 16#155 [/racute] + 16#3027 [/sevenhangzhou] + 16#2790 [/sevencircleinversesansserif] + 16#1EF9 [/ytilde] + 16#FEF9 [/lamalefhamzabelowisolatedarabic] + 16#2534 [/SF070000] + 16#534 [/Daarmenian] + 16#2D8 [/breve] + 16#913 [/odeva] + 16#7C [/verticalbar /bar] + 16#207C [/equalsuperior] + 16#F7E5 [/Aringsmall] + 16#1E20 [/Gmacron] + 16#45B [/tshecyrillic /afii10108] + 16#A96 [/khagujarati] + 16#1FF [/ostrokeacute /oslashacute] + 16#30D1 [/pakatakana] + 16#5DE [/memhebrew /mem /afii57678] + 16#2126 [/Ohm /Omega] + 16#F88F [/maitholowleftthai] + 16#126 [/Hbar] + 16#FECA [/ainfinalarabic] + 16#1ECA [/Idotbelow] + 16#317B [/siosnieunkorean] + 16#4D [/M] + 16#688 [/ddalarabic /afii57512] + 16#42C [/afii10046 /Softsigncyrillic] + 16#FB95 [/gafmedialarabic] + 16#A67 [/onegurmukhi] + 16#1D0 [/icaron] + 16#21D0 [/arrowleftdbl /arrowdblleft] + 16#30A2 [/akatakana] + 16#FF74 [/ekatakanahalfwidth] + 16#F6DD [/rupiah] + 16#E46 [/maiyamokthai] + 16#5AF [/masoracirclehebrew] + 16#3225 [/sixideographicparen] + 16#F7 [/divide] + 16#FE9B [/thehinitialarabic] + 16#1E9B [/slongdotaccent] + 16#24D6 [/gcircle] + 16#4D6 [/Iebrevecyrillic] + 16#33A8 [/moverssquaredsquare] + 16#227A [/precedes] + 16#27A [/rlonglegturned] + 16#314C [/thieuthkorean] + 16#1E [/controlRS] + 16#201E [/quotedblbase] + 16#A38 [/sagurmukhi] + 16#1A1 [/ohorn] + 16#3073 [/bihiragana] + 16#FF45 [/emonospace] + 16#E17 [/thothahanthai] + 16#2580 [/upblock] + 16#580 [/reharmenian] + 16#324 [/dieresisbelowcmb] + 16#95F [/yyadeva] + 16#C8 [/Egrave] + 16#1E6C [/Tdotbelow] + 16#4A7 [/pemiddlehookcyrillic] + 16#24A7 [/lparen] + 16#311D [/ehbopomofo] + 16#62A [/teharabic /afii57418] + 16#3CE [/omegatonos] + 16#A09 [/ugurmukhi] + 16#2172 [/threeroman] + 16#172 [/Uogonek] + 16#3044 [/ihiragana] + 16#FF16 [/sixmonospace] + 16#2551 [/SF240000] + 16#551 [/Coarmenian] + 16#930 [/radeva] + 16#1E3D [/lcircumflexbelow] + 16#FE3D [/dblanglebracketleftvertical] + 16#2478 [/fiveparen] + 16#478 [/Ukcyrillic] + 16#334A [/miribaarusquare] + 16#AB3 [/llagujarati] + 16#30EE [/wasmallkatakana] + 16#39F [/Omicron] + 16#3271 [/rieulacirclekorean] + 16#143 [/Nacute] + 16#3015 [/tortoiseshellbracketright] + 16#1EE7 [/uhookabove] + 16#FEE7 [/nooninitialarabic] + 16#2C6 [/circumflex] + 16#901 [/candrabindudeva] + 16#6A [/j] + 16#1E0E [/Dlinebelow] + 16#449 [/shchacyrillic /afii10091] + 16#1ED [/oogonekmacron] + 16#30BF [/takatakana] + 16#FF91 [/mukatakanahalfwidth] + 16#F6FA [/OEsmall] + 16#25CC [/dottedcircle] + 16#3242 [/ideographicselfparen] + 16#9AB [/phabengali] + 16#114 [/Ebreve] + 16#FEB8 [/sheenmedialarabic] + 16#1EB8 [/Edotbelow] + 16#4F3 [/uhungarumlautcyrillic] + 16#33C5 [/cdsquare] + 16#2297 [/timescircle /circlemultiply] + 16#297 [/cstretched] + 16#3169 [/rieulkiyeoksioskorean] + 16#203B [/referencemark] + 16#3B [/semicolon] + 16#41A [/afii10028 /Kacyrillic] + 16#1BE [/glottalinvertedstroke] + 16#3090 [/wihiragana] + 16#FF62 [/cornerbracketlefthalfwidth] + 16#F6CB [/Dieresis] + 16#E34 [/saraithai] + 16#59D [/gereshmuqdamhebrew] + 16#341 [/acutetonecmb] + 16#3213 [/pieupaparenkorean] + 16#E5 [/aring] + 16#1E89 [/wdotbelow] + 16#4C4 [/kahookcyrillic] + 16#24C4 [/Ocircle] + 16#3396 [/mlsquare] + 16#268 [/istroke] + 16#313A [/rieulkiyeokkorean] + 16#200C [/zerowidthnonjoiner /afii61664] + 16#C [/controlFF] + 16#F775 [/Usmall] + 16#647 [/heharabic /afii57470] + 16#3EB [/gangiacoptic] + 16#A26 [/dagurmukhi] + 16#18F [/Schwa] + 16#F8F8 [/parenrightbt] + 16#3061 [/tihiragana] + 16#FF33 [/Smonospace] + 16#E05 [/khokhonthai] + 16#56E [/caarmenian] + 16#312 [/commaturnedabovecmb] + 16#2312 [/arc] + 16#94D [/viramadeva] + 16#B6 [/paragraph] + 16#6F1 [/onepersian] + 16#FE5A [/parenrightsmall] + 16#1E5A [/Rdotbelow] + 16#495 [/ghemiddlehookcyrillic] + 16#2495 [/fourteenperiod] + 16#AD0 [/omgujarati] + 16#310B [/nbopomofo] + 16#3BC [/mugreek] + 16#328E [/ideographmetalcircle] + 16#9F7 [/fournumeratorbengali] + 16#2160 [/Oneroman] + 16#160 [/Scaron] + 16#FF04 [/dollarmonospace] + 16#53F [/Kenarmenian] + 16#2E3 [/xsuperior] + 16#91E [/nyadeva] + 16#2087 [/seveninferior] + 16#F7F0 [/Ethsmall] + 16#1E2B [/hbrevebelow] + 16#2466 [/sevencircle] + 16#466 [/Yuslittlecyrillic] + 16#AA1 [/ddagujarati] + 16#20A [/Iinvertedbreve] + 16#30DC [/bokatakana] + 16#5E9 [/shinhebrew /shin /afii57689] + 16#9C8 [/aivowelsignbengali] + 16#131 [/dotlessi] + 16#3003 [/dittomark] + 16#1ED5 [/ocircumflexhookabove] + 16#2510 [/SF030000] + 16#2B4 [/rturnedsuperior] + 16#3186 [/yeorinhieuhkorean] + 16#58 [/X] + 16#437 [/zecyrillic /afii10073] + 16#A72 [/irigurmukhi] + 16#1DB [/Udieresisgrave] + 16#30AD [/kikatakana] + 16#FF7F [/sokatakanahalfwidth] + 16#F6E8 [/periodsuperior] + 16#E51 [/onethai] + 16#25BA [/triagrt /blackrightpointingpointer] + 16#3230 [/ideographicsunparen] + 16#999 [/ngabengali] + 16#102 [/Abreve] + 16#FEA6 [/khahfinalarabic] + 16#1EA6 [/Acircumflexgrave] + 16#24E1 [/rcircle] + 16#4E1 [/dzeabkhasiancyrillic] + 16#33B3 [/mssquare] + 16#2285 [/notsuperset] + 16#285 [/eshsquatreversed] + 16#3157 [/okorean] + 16#29 [/parenright] + 16#2664 [/spadesuitwhite] + 16#664 [/fourhackarabic /fourarabic /afii57396] + 16#408 [/afii10057 /Jecyrillic] + 16#1AC [/Thook] + 16#307E [/mahiragana] + 16#FF50 [/pmonospace] + 16#E22 [/yoyakthai] + 16#32F [/breveinvertedbelowcmb] + 16#3201 [/nieunparenkorean] + 16#96A [/fourdeva] + 16#D3 [/Oacute] + 16#1E77 [/ucircumflexbelow] + 16#24B2 [/wparen] + 16#4B2 [/Hadescendercyrillic] + 16#3384 [/kasquare] + 16#AED [/sevengujarati] + 16#256 [/dtail] + 16#3128 [/ubopomofo] + 16#F763 [/Csmall] + 16#635 [/sadarabic /afii57429] + 16#A14 [/augurmukhi] + 16#17D [/Zcaron] + 16#F8E6 [/arrowvertex] + 16#304F [/kuhiragana] + 16#FF21 [/Amonospace] + 16#55C [/exclamarmenian] + 16#255C [/SF270000] + 16#300 [/gravecomb /gravecmb] + 16#20A4 [/lira /afii08941] + 16#A4 [/currency] + 16#1E48 [/Nlinebelow] + 16#483 [/titlocyrilliccmb] + 16#2483 [/sixteenparen] + 16#ABE [/aavowelsigngujarati] + 16#2227 [/logicaland] + 16#30F9 [/vekatakana] + 16#F734 [/fouroldstyle] + 16#2606 [/whitestar] + 16#3AA [/Iotadieresis] + 16#14E [/Obreve] + 16#3020 [/postalmarkface] + 16#FEF2 [/yehfinalarabic] + 16#1EF2 [/Ygrave] + 16#2D1 [/colontriangularhalfmod] + 16#90C [/lvocalicdeva] + 16#2075 [/fivesuperior] + 16#75 [/u] + 16#1E19 [/ecircumflexbelow] + 16#454 [/ecyrillic /afii10101] + 16#3326 [/dorusquare] + 16#A8F [/egujarati] + 16#30CA [/nakatakana] + 16#FF9C [/wakatakanahalfwidth] + 16#5D7 [/hethebrew /het /afii57671] + 16#9B6 [/shabengali] + 16#11F [/gbreve] + 16#F888 [/saraueeleftthai] + 16#FEC3 [/tahinitialarabic] + 16#1EC3 [/ecircumflexhookabove] + 16#33D0 [/lmsquare] + 16#2A2 [/glottalstopstrokereversed] + 16#3174 [/pieupsioskiyeokkorean] + 16#46 [/F] + 16#F7AF [/Macronsmall] + 16#425 [/afii10039 /Khacyrillic] + 16#1C9 [/lj] + 16#309B [/voicedmarkkana] + 16#FF6D [/yusmallkatakanahalfwidth] + 16#F6D6 [/dblgrave] + 16#E3F [/bahtthai] + 16#25A8 [/squareupperrighttolowerleftfill] + 16#5A8 [/qadmahebrew] + 16#987 [/ibengali] + 16#F0 [/eth] + 16#FE94 [/tehmarbutafinalarabic] + 16#1E94 [/Zlinebelow] + 16#24CF [/Zcircle] + 16#33A1 [/squaremsquared] + 16#273 [/nhookretroflex] + 16#2273 [/greaterorequivalent] + 16#3145 [/sioskorean] + 16#2017 [/underscoredbl /dbllowline] + 16#17 [/controlETB] + 16#652 [/sukunarabic /afii57458] + 16#19A [/lbar] + 16#306C [/nuhiragana] + 16#FF3E [/asciicircummonospace] + 16#E10 [/thothanthai] + 16#579 [/chaarmenian] + 16#31D [/uptackbelowcmb] + 16#958 [/qadeva] + 16#C1 [/Aacute] + 16#1E65 [/sacutedotaccent] + 16#FE65 [/greatersmall] + 16#24A0 [/eparen] + 16#4A0 [/Kabashkircyrillic] + 16#3116 [/rbopomofo] + 16#623 [/afii57411 /alefhamzaabovearabic] + 16#3C7 [/chi] + 16#FB30 [/alefdageshhebrew] + 16#3299 [/ideographicsecretcircle] + 16#A02 [/bindigurmukhi] + 16#16B [/umacron] + 16#216B [/Twelveroman] + 16#FF0F [/slashmonospace] + 16#54A [/Peharmenian] + 16#22EE [/ellipsisvertical] + 16#929 [/nnnadeva] + 16#F7FB [/Ucircumflexsmall] + 16#FE36 [/parenrightvertical] + 16#1E36 [/Ldotbelow] + 16#471 [/psicyrillic] + 16#2471 [/eighteencircle] + 16#AAC [/bagujarati] + 16#215 [/udblgrave] + 16#2215 [/divisionslash] + 16#30E7 [/yosmallkatakana] + 16#5F4 [/gershayimhebrew] + 16#398 [/Theta] + 16#FB01 [/fi] + 16#326A [/khieukhcirclekorean] + 16#13C [/lcommaaccent /lcedilla] + 16#300E [/whitecornerbracketleft] + 16#FEE0 [/lammedialarabic] + 16#1EE0 [/Ohorntilde] + 16#2BF [/ringhalfleft] + 16#22BF [/righttriangle] + 16#63 [/c] + 16#1E07 [/blinebelow] + 16#442 [/tecyrillic /afii10084] + 16#3314 [/kirosquare] + 16#21E6 [/arrowleftwhite] + 16#1E6 [/Gcaron] + 16#30B8 [/zikatakana] + 16#FF8A [/hakatakanahalfwidth] + 16#F6F3 [/tsuperior] + 16#323B [/ideographicstudyparen] + 16#9A4 [/tabengali] + 16#10D [/ccaron] + 16#1EB1 [/abrevegrave] + 16#33BE [/kwsquare] + 16#290 [/zretroflexhook] + 16#3162 [/yikorean] + 16#34 [/four] + 16#266F [/musicsharpsign] + 16#413 [/afii10020 /Gecyrillic] + 16#FB7C [/tchehinitialarabic] + 16#1B7 [/Ezh] + 16#3089 [/rahiragana] + 16#FF5B [/braceleftmonospace] + 16#F6C4 [/afii10063] + 16#E2D [/oangthai] + 16#596 [/tipehalefthebrew /tipehahebrew] + 16#33A [/bridgeinvertedbelowcmb] + 16#320C [/phieuphparenkorean] + 16#DE [/Thorn] + 16#FE82 [/alefmaddaabovefinalarabic] + 16#1E82 [/Wacute] + 16#4BD [/cheabkhasiancyrillic] + 16#24BD [/Hcircle] + 16#338F [/squarekg] + 16#261 [/gscript] + 16#2261 [/equivalence] + 16#3133 [/kiyeoksioskorean] + 16#5 [/controlENQ] + 16#F76E [/Nsmall] + 16#640 [/tatweelarabic /kashidaautonosidebearingarabic /kashidaautoarabic /afii57440] + 16#2640 [/venus /female] + 16#3E4 [/Feicoptic] + 16#FB4D [/kafrafehebrew] + 16#A1F [/ttagurmukhi] + 16#188 [/chook] + 16#F8F1 [/bracelefttp] + 16#305A [/zuhiragana] + 16#FF2C [/Lmonospace] + 16#567 [/eharmenian] + 16#2567 [/SF450000] + 16#30B [/hungarumlautcmb] + 16#946 [/eshortvowelsigndeva] + 16#AF [/overscore /macron] + 16#1E53 [/omacronacute] + 16#248E [/sevenperiod] + 16#AC9 [/ocandravowelsigngujarati] + 16#F73F [/questionsmall] + 16#3B5 [/epsilon] + 16#9F0 [/ramiddlediagonalbengali] + 16#159 [/rcaron] + 16#538 [/Etarmenian] + 16#FCA1 [/tehjeeminitialarabic] + 16#2DC [/ilde /tilde] + 16#917 [/gadeva] + 16#2080 [/zeroinferior] + 16#F7E9 [/Eacutesmall] + 16#1E24 [/Hdotbelow] + 16#45F [/dzhecyrillic /afii10193] + 16#3331 [/birusquare] + 16#A9A [/cagujarati] + 16#2203 [/thereexists /existential] + 16#203 [/ainvertedbreve] + 16#30D5 [/hukatakana] + 16#25E2 [/blacklowerrighttriangle] + 16#5E2 [/ayin /afii57682 /ayinhebrew] + 16#386 [/Alphatonos] + 16#9C1 [/uvowelsignbengali] + 16#12A [/Imacron] + 16#F893 [/maichattawaupperleftthai] + 16#FECE [/ghainfinalarabic] + 16#1ECE [/Ohookabove] + 16#33DB [/srsquare] + 16#317F [/pansioskorean] + 16#51 [/Q] + 16#430 [/acyrillic /afii10065] + 16#A6B [/fivegurmukhi] + 16#1D4 [/ucaron] + 16#21D4 [/dblarrowleft /arrowdblboth] + 16#30A6 [/ukatakana] + 16#FF78 [/kukatakanahalfwidth] + 16#F6E1 [/commainferior] + 16#E4A [/maitrithai] + 16#25B3 [/whiteuppointingtriangle] + 16#5B3 [/hatafqamatswidehebrew /hatafqamatsquarterhebrew /hatafqamatsnarrowhebrew /hatafqamatshebrew /hatafqamats34 /hatafqamats28 /hatafqamats1b /hatafqamats /afii57802] + 16#3229 [/tenideographicparen] + 16#FB [/ucircumflex] + 16#FE9F [/jeeminitialarabic] + 16#24DA [/kcircle] + 16#4DA [/Schwadieresiscyrillic] + 16#33AC [/gpasquare] + 16#27E [/rfishhook] + 16#3150 [/aekorean] + 16#22 [/quotedbl] + 16#2022 [/bullet] + 16#401 [/afii10023 /Iocyrillic] + 16#A3C [/nuktagurmukhi] + 16#1A5 [/phook] + 16#3077 [/puhiragana] + 16#FF49 [/imonospace] + 16#E1B [/poplathai] + 16#584 [/keharmenian] + 16#2584 [/dnblock] + 16#328 [/ogonekcmb] + 16#963 [/llvocalicvowelsigndeva] + 16#CC [/Igrave] + 16#1E70 [/Tcircumflexbelow] + 16#24AB [/pparen] + 16#4AB [/esdescendercyrillic] + 16#337D [/taisyouerasquare] + 16#AE6 [/zerogujarati] + 16#3121 [/oubopomofo] + 16#62E [/khaharabic /afii57422] + 16#3D2 [/Upsilonhooksymbol /Upsilon1] + 16#FB3B [/kafdageshhebrew /kafdagesh] + 16#32A4 [/ideographichighcircle] + 16#2176 [/sevenroman] + 16#176 [/Ycircumflex] + 16#3048 [/ehiragana] + 16#FF1A [/colonmonospace] + 16#555 [/Oharmenian] + 16#2555 [/SF220000] + 16#934 [/llladeva] + 16#1E41 [/mdotaccent] + 16#FE41 [/cornerbracketleftvertical] + 16#247C [/nineparen] + 16#47C [/Omegatitlocyrillic] + 16#334E [/yaadosquare] + 16#AB7 [/ssagujarati] + 16#2220 [/angle] + 16#30F2 [/wokatakana] + 16#3A3 [/Sigma] + 16#3275 [/ieungacirclekorean] + 16#147 [/Ncaron] + 16#3019 [/whitetortoiseshellbracketright] + 16#1EEB [/uhorngrave] + 16#FEEB [/hehinitialarabic] + 16#2CA [/secondtonechinese] + 16#905 [/adeva] + 16#6E [/n] + 16#1E12 [/Dcircumflexbelow] + 16#44D [/ereversedcyrillic /afii10095] + 16#A88 [/iigujarati] + 16#1F1 [/DZ] + 16#30C3 [/tusmallkatakana] + 16#FF95 [/yukatakanahalfwidth] + 16#F6FE [/Tildesmall] + 16#25D0 [/circlewithlefthalfblack] + 16#5D0 [/alefhebrew /afii57664 /alef] + 16#374 [/numeralsigngreek] + 16#9AF [/yabengali] + 16#118 [/Eogonek] + 16#2118 [/weierstrass] + 16#FEBC [/sadmedialarabic] + 16#1EBC [/Etilde] + 16#FC60 [/shaddafathaarabic] + 16#33C9 [/gysquare] + 16#29B [/Gsmallhook] + 16#316D [/rieulyeorinhieuhkorean] + 16#3F [/question] + 16#F7A8 [/Dieresissmall] + 16#41E [/afii10032 /Ocyrillic] + 16#A59 [/khhagurmukhi] + 16#1C2 [/clickalveolar] + 16#3094 [/vuhiragana] + 16#FF66 [/wokatakanahalfwidth] + 16#F6CF [/Hungarumlaut] + 16#E38 [/sarauthai] + 16#25A1 [/whitesquare /H22073] + 16#5A1 [/pazerhebrew] + 16#345 [/ypogegrammenigreekcmb] + 16#3217 [/chieuchaparenkorean] + 16#E9 [/eacute] + 16#1E8D [/xdieresis] + 16#4C8 [/enhookcyrillic] + 16#24C8 [/Scircle] + 16#339A [/nmsquare] + 16#26C [/lbelt] + 16#313E [/rieulthieuthkorean] + 16#2010 [/hyphentwo] + 16#10 [/controlDLE] + 16#F779 [/Ysmall] + 16#64B [/fathatanarabic /afii57451] + 16#3EF [/deicoptic] + 16#FB58 [/pehinitialarabic] + 16#A2A [/pagurmukhi] + 16#193 [/Ghook] + 16#F8FC [/bracerighttp] + 16#3065 [/duhiragana] + 16#2193 [/arrowdown] + 16#FF37 [/Wmonospace] + 16#E09 [/chochingthai] + 16#572 [/ghadarmenian] + 16#316 [/gravebelowcmb] + 16#951 [/udattadeva] + 16#BA [/ordmasculine] + 16#6F5 [/fivepersian] + 16#FE5E [/tortoiseshellbracketrightsmall] + 16#1E5E [/Rlinebelow] + 16#499 [/zedescendercyrillic] + 16#2499 [/eighteenperiod] + 16#223D [/reversedtilde] + 16#310F [/hbopomofo] + 16#FFE1 [/sterlingmonospace] + 16#261C [/pointingindexleftwhite] + 16#3C0 [/pi] + 16#2164 [/Fiveroman] + 16#164 [/Tcaron] + 16#3036 [/circlepostalmark] + 16#FF08 [/parenleftmonospace] + 16#543 [/Cheharmenian] + 16#2E7 [/tonebarmidmod] + 16#922 [/ddhadeva] + 16#F7F4 [/Ocircumflexsmall] + 16#1E2F [/idieresisacute] + 16#246A [/elevencircle] + 16#46A [/Yusbigcyrillic] + 16#AA5 [/thagujarati] + 16#20E [/Oinvertedbreve] + 16#30E0 [/mukatakana] + 16#391 [/Alpha] + 16#3263 [/rieulcirclekorean] + 16#9CC [/auvowelsignbengali] + 16#135 [/jcircumflex] + 16#2135 [/aleph] + 16#3007 [/ideographiczero] + 16#1ED9 [/ocircumflexdotbelow] + 16#2514 [/SF020000] + 16#2B8 [/ysuperior] + 16#318A [/yuyeokorean] + 16#5C [/backslash] + 16#1E00 [/Aringbelow] + 16#43B [/elcyrillic /afii10077] + 16#FBA4 [/hehhamzaaboveisolatedarabic] + 16#330D [/karoriisquare] + 16#21DF [/pagedown] + 16#1DF [/adieresismacron] + 16#30B1 [/kekatakana] + 16#FF83 [/tekatakanahalfwidth] + 16#F6EC [/esuperior] + 16#E55 [/fivethai] + 16#5BE [/maqafhebrew /afii57645] + 16#3234 [/ideographicnameparen] + 16#99D [/jhabengali] + 16#106 [/Cacute] + 16#FEAA [/dalfinalarabic] + 16#1EAA [/Acircumflextilde] + 16#24E5 [/vcircle] + 16#FC4E [/noonmeemisolatedarabic] + 16#33B7 [/mvsquare] + 16#4E5 [/idieresiscyrillic] + 16#289 [/ubar] + 16#315B [/yokorean] + 16#202D [/afii61574] + 16#2D [/hyphen] + 16#2668 [/hotsprings] + 16#668 [/eightarabic /eighthackarabic /afii57400] + 16#40C [/afii10061 /Kjecyrillic] + 16#A47 [/eematragurmukhi] + 16#1B0 [/uhorn] + 16#3082 [/mohiragana] + 16#FF54 [/tmonospace] + 16#E26 [/luthai] + 16#333 [/dbllowlinecmb] + 16#3205 [/pieupparenkorean] + 16#96E [/eightdeva] + 16#D7 [/multiply] + 16#1E7B [/umacrondieresis] + 16#24B6 [/Acircle] + 16#4B6 [/Chedescendercyrillic] + 16#3388 [/calsquare] + 16#25A [/schwahook] + 16#F767 [/Gsmall] + 16#639 [/afii57433 /ainarabic] + 16#FB46 [/tsadidageshhebrew /tsadidagesh] + 16#A18 [/ghagurmukhi] + 16#181 [/Bhook] + 16#F8EA [/trademarksans] + 16#3053 [/kohiragana] + 16#FF25 [/Emonospace] + 16#2560 [/SF420000] + 16#FCC9 [/lamjeeminitialarabic] + 16#304 [/macroncmb] + 16#93F [/ivowelsigndeva] + 16#A8 [/dieresis] + 16#FE4C [/overlinedblwavy] + 16#1E4C [/Otildeacute] + 16#2487 [/twentyparen] + 16#AC2 [/uuvowelsigngujarati] + 16#222B [/integral] + 16#30FD [/iterationkatakana] + 16#F738 [/eightoldstyle] + 16#3AE [/etatonos] + 16#9E9 [/threebengali] + 16#152 [/OE] + 16#3024 [/fourhangzhou] + 16#278D [/fourcircleinversesansserif] + 16#FEF6 [/lamalefmaddaabovefinalarabic] + 16#1EF6 [/Yhookabove] + 16#531 [/Aybarmenian] + 16#2D5 [/downtackmod] + 16#910 [/aideva] + 16#2079 [/ninesuperior] + 16#F7E2 [/Acircumflexsmall] + 16#79 [/y] + 16#1E1D [/ecedillabreve] + 16#458 [/jecyrillic /afii10105] + 16#332A [/haitusquare] + 16#A93 [/ogujarati] + 16#1FC [/AEacute] + 16#30CE [/nokatakana] + 16#5DB [/kafhebrew /kaf /afii57675] + 16#123 [/gcommaaccent /gcedilla] + 16#F88C [/maieklowleftthai] + 16#FEC7 [/zahinitialarabic] + 16#1EC7 [/ecircumflexdotbelow] + 16#2502 [/SF110000] + 16#33D4 [/mbsquare] + 16#2A6 [/ts] + 16#3178 [/kapyeounpieupkorean] + 16#4A [/J] + 16#429 [/afii10043 /Shchacyrillic] + 16#21CD [/arrowleftdblstroke] + 16#1CD [/Acaron] + 16#FF71 [/akatakanahalfwidth] + 16#F6DA [/registerserif] + 16#E43 [/saraaimaimuanthai] + 16#5AC [/iluyhebrew] + 16#25AC [/filledrect /blackrectangle] + 16#3222 [/threeideographicparen] + 16#98B [/rvocalicbengali] + 16#F4 [/ocircumflex] + 16#FE98 [/tehmedialarabic] + 16#1E98 [/wring] + 16#24D3 [/dcircle] + 16#4D3 [/adieresiscyrillic] + 16#33A5 [/mcubedsquare] + 16#277 [/omegalatinclosed] + 16#2277 [/greaterorless] + 16#3149 [/ssangcieuckorean] + 16#201B [/quotereversed /quoteleftreversed] + 16#1B [/controlESC] + 16#A35 [/vagurmukhi] + 16#19E [/nlegrightlong] + 16#3070 [/bahiragana] + 16#FF42 [/bmonospace] + 16#E14 [/dodekthai] + 16#57D [/seharmenian] + 16#321 [/hookpalatalizedbelowcmb] + 16#2321 [/integralbottom /integralbt] + 16#95C [/dddhadeva] + 16#C5 [/Aring] + 16#1E69 [/sdotbelowdotaccent] + 16#FE69 [/dollarsmall] + 16#24A4 [/iparen] + 16#4A4 [/Enghecyrillic] + 16#2248 [/approxequal] + 16#311A [/abopomofo] + 16#627 [/afii57415 /alefarabic] + 16#3CB [/upsilondieresis] + 16#FB34 [/hedageshhebrew /hedagesh] + 16#329D [/ideographicexcellentcircle] + 16#A06 [/aagurmukhi] + 16#16F [/uring] + 16#3041 [/asmallhiragana] + 16#FF13 [/threemonospace] + 16#54E [/Vewarmenian] + 16#92D [/bhadeva] + 16#F7FF [/Ydieresissmall] + 16#6D1 [/yehthreedotsbelowarabic] + 16#FE3A [/tortoiseshellbracketrightvertical] + 16#1E3A [/Llinebelow] + 16#2475 [/twoparen] + 16#475 [/izhitsacyrillic /afii10196] + 16#3347 [/mansyonsquare] + 16#AB0 [/ragujarati] + 16#219 [/scommaaccent] + 16#2219 [/bulletoperator] + 16#30EB [/rukatakana] + 16#F726 [/ampersandsmall] + 16#39C [/Mu] + 16#326E [/kiyeokacirclekorean] + 16#9D7 [/aulengthmarkbengali] + 16#140 [/ldotaccent /ldot] + 16#3012 [/postalmark] + 16#FEE4 [/meemmedialarabic] + 16#1EE4 [/Udotbelow] + 16#2C3 [/arrowheadrightmod] + 16#67 [/g] + 16#1E0B [/ddotaccent] + 16#446 [/tsecyrillic /afii10088] + 16#FBAF [/yehbarreefinalarabic] + 16#3318 [/guramusquare] + 16#A81 [/candrabindugujarati] + 16#21EA [/capslock] + 16#1EA [/Oogonek] + 16#30BC [/zekatakana] + 16#FF8E [/hokatakanahalfwidth] + 16#F6F7 [/Dotaccentsmall] + 16#25C9 [/fisheye] + 16#323F [/ideographicallianceparen] + 16#9A8 [/nabengali] + 16#111 [/dmacron /dcroat] + 16#2111 [/Ifraktur] + 16#1EB5 [/abrevetilde] + 16#4F0 [/Udieresiscyrillic] + 16#33C2 [/amsquare] + 16#294 [/glottalstop] + 16#3166 [/nieuntikeutkorean] + 16#38 [/eight] + 16#F7A1 [/exclamdownsmall] + 16#417 [/Zecyrillic /afii10025] + 16#1BB [/twostroke] + 16#308D [/rohiragana] + 16#F6C8 [/afii10832] + 16#E31 [/maihanakatthai] + 16#59A [/yetivhebrew] + 16#33E [/tildeverticalcmb] + 16#3210 [/tikeutaparenkorean] + 16#E2 [/acircumflex] + 16#FE86 [/wawhamzaabovefinalarabic] + 16#1E86 [/Wdotaccent] + 16#4C1 [/Zhebrevecyrillic] + 16#24C1 [/Lcircle] + 16#3393 [/ghzsquare] + 16#265 [/hturned] + 16#2265 [/greaterequal] + 16#3137 [/tikeutkorean] + 16#9 [/controlHT] + 16#F772 [/Rsmall] + 16#644 [/lamarabic /afii57444] + 16#3E8 [/Horicoptic] + 16#A23 [/nnagurmukhi] + 16#18C [/dtopbar] + 16#F8F5 [/integralex] + 16#305E [/zohiragana] + 16#FF30 [/Pmonospace] + 16#E02 [/khokhaithai] + 16#56B [/iniarmenian] + 16#256B [/SF530000] + 16#30F [/dblgravecmb] + 16#94A [/oshortvowelsigndeva] + 16#B3 [/threesuperior] + 16#1E57 [/pdotaccent] + 16#2492 [/elevenperiod] + 16#492 [/Ghestrokecyrillic] + 16#ACD [/viramagujarati] + 16#2236 [/ratio] + 16#3108 [/fbopomofo] + 16#3B9 [/iota] + 16#328B [/ideographfirecircle] + 16#9F4 [/onenumeratorbengali] + 16#15D [/scircumflex] + 16#215D [/fiveeighths] + 16#FF01 [/exclammonospace] + 16#53C [/Liwnarmenian] + 16#253C [/SF050000] + 16#2E0 [/gammasuperior] + 16#91B [/chadeva] + 16#2084 [/fourinferior] + 16#F7ED [/Iacutesmall] + 16#1E28 [/Hcedilla] + 16#463 [/yatcyrillic /afii10194] + 16#2463 [/fourcircle] + 16#A9E [/nyagujarati] + 16#2207 [/nabla /gradient] + 16#207 [/einvertedbreve] + 16#30D9 [/bekatakana] + 16#5E6 [/tsadihebrew /tsadi /afii57686] + 16#25E6 [/whitebullet /openbullet] + 16#38A [/Iotatonos] + 16#12E [/Iogonek] + 16#212E [/estimated] + 16#F897 [/thanthakhatlowrightthai] + 16#3000 [/ideographicspace] + 16#FED2 [/fehfinalarabic] + 16#1ED2 [/Ocircumflexgrave] + 16#2B1 [/hhooksuperior] + 16#3183 [/yesieungpansioskorean] + 16#55 [/U] + 16#434 [/decyrillic /afii10069] + 16#A6F [/ninegurmukhi] + 16#1D8 [/udieresisacute] + 16#30AA [/okatakana] + 16#FF7C [/sikatakanahalfwidth] + 16#F6E5 [/hypheninferior] + 16#E4E [/yamakkanthai] + 16#25B7 [/whiterightpointingtriangle] + 16#5B7 [/patahwidehebrew /patahquarterhebrew /patahnarrowhebrew /patahhebrew /patah2a /patah1d /patah11 /patah /afii57798] + 16#322D [/ideographicwoodparen] + 16#996 [/khabengali] + 16#FF [/ydieresis] + 16#FEA3 [/hahinitialarabic] + 16#1EA3 [/ahookabove] + 16#24DE [/ocircle] + 16#4DE [/Zedieresiscyrillic] + 16#33B0 [/pssquare] + 16#2282 [/subset /propersubset] + 16#282 [/shook] + 16#3154 [/ekorean] + 16#26 [/ampersand] + 16#2026 [/ellipsis] + 16#661 [/onehackarabic /onearabic /afii57393] + 16#2661 [/heartsuitwhite] + 16#405 [/afii10054 /Dzecyrillic] + 16#A40 [/iimatragurmukhi] + 16#1A9 [/Esh] + 16#307B [/hohiragana] + 16#FF4D [/mmonospace] + 16#E1F [/fofanthai] + 16#2588 [/block] + 16#32C [/caronbelowcmb] + 16#967 [/onedeva] + 16#D0 [/Eth] + 16#1E74 [/Utildebelow] + 16#4AF [/ustraightcyrillic] + 16#24AF [/tparen] + 16#3381 [/nasquare] + 16#AEA [/fourgujarati] + 16#2253 [/imageorapproximatelyequal] + 16#253 [/bhook] + 16#3125 [/engbopomofo] + 16#F760 [/Gravesmall] + 16#632 [/zainarabic /afii57426] + 16#3D6 [/pisymbolgreek /omega1] + 16#32A8 [/ideographicrightcircle] + 16#17A [/zacute] + 16#217A [/elevenroman] + 16#304C [/gahiragana] + 16#FF1E [/greatermonospace] + 16#559 [/ringhalfleftarmenian] + 16#2559 [/SF490000] + 16#938 [/sadeva] + 16#20A1 [/colonmonetary /colonsign] + 16#A1 [/exclamdown] + 16#1E45 [/ndotaccent] + 16#2480 [/thirteenparen] + 16#480 [/Koppacyrillic] + 16#30F6 [/kesmallkatakana] + 16#F731 [/oneoldstyle] + 16#3A7 [/Chi] + 16#3279 [/thieuthacirclekorean] + 16#9E2 [/lvocalicvowelsignbengali] + 16#14B [/eng] + 16#301D [/quotedblprimereversed] + 16#1EEF [/uhorntilde] + 16#2CE [/gravelowmod] + 16#22CE [/curlyor] + 16#909 [/udeva] + 16#72 [/r] + 16#1E16 [/Emacronacute] + 16#451 [/iocyrillic /afii10071] + 16#3323 [/sentosquare] + 16#1F5 [/gacute] + 16#30C7 [/dekatakana] + 16#FF99 [/rukatakanahalfwidth] + 16#5D4 [/hehebrew /he /afii57668] + 16#11C [/Gcircumflex] + 16#F885 [/saraileftthai] + 16#211C [/Rfraktur] + 16#FEC0 [/dadmedialarabic] + 16#1EC0 [/Ecircumflexgrave] + 16#33CD [/KKsquare] + 16#3171 [/kapyeounmieumkorean] + 16#43 [/C] + 16#67E [/peharabic /afii57506] + 16#422 [/afii10036 /Tecyrillic] + 16#FB8B [/jehfinalarabic] + 16#1C6 [/dzcaron] + 16#21C6 [/arrowleftoverright] + 16#FF6A [/esmallkatakanahalfwidth] + 16#F6D3 [/dblGrave] + 16#25A5 [/squareverticalfill] + 16#5A5 [/merkhalefthebrew /merkhahebrew] + 16#321B [/hieuhaparenkorean] + 16#ED [/iacute] + 16#1E91 [/zcircumflex] + 16#FE91 [/behinitialarabic] + 16#4CC [/chekhakassiancyrillic] + 16#24CC [/Wcircle] + 16#339E [/squarekm] + 16#270 [/mlonglegturned] + 16#2270 [/notlessnorequal] + 16#3142 [/pieupkorean] + 16#14 [/controlDC4] + 16#2014 [/emdash] + 16#64F [/dammalowarabic /dammaarabic /afii57455] + 16#3F3 [/yotgreek] + 16#A2E [/magurmukhi] + 16#2197 [/arrowupright] + 16#197 [/Istroke] + 16#3069 [/dohiragana] + 16#FF3B [/bracketleftmonospace] + 16#E0D [/yoyingthai] + 16#576 [/nowarmenian] + 16#31A [/leftangleabovecmb] + 16#BE [/threequarters] + 16#6F9 [/ninepersian] + 16#FE62 [/plussmall] + 16#1E62 [/Sdotbelow] + 16#49D [/kaverticalstrokecyrillic] + 16#249D [/bparen] + 16#3113 [/zhbopomofo] + 16#FFE5 [/yenmonospace] + 16#3C4 [/tau] + 16#FB2D [/shindageshsindothebrew /shindageshsindot] + 16#3296 [/ideographicfinancialcircle] + 16#168 [/Utilde] + 16#2168 [/Nineroman] + 16#FF0C [/commamonospace] + 16#547 [/Shaarmenian] + 16#926 [/dadeva] + 16#F7F8 [/Oslashsmall] + 16#FE33 [/underscorevertical] + 16#1E33 [/kdotbelow] + 16#246E [/fifteencircle] + 16#46E [/Ksicyrillic] + 16#212 [/Rinvertedbreve] + 16#2212 [/minus] + 16#30E4 [/yakatakana] + 16#5F1 [/vavyodhebrew /afii57717] + 16#395 [/Epsilon] + 16#3267 [/ieungcirclekorean] + 16#139 [/Lacute] + 16#300B [/dblanglebracketright] + 16#1EDD [/ohorngrave] + 16#2518 [/SF040000] + 16#2BC [/apostrophemod /afii57929] + 16#318E [/araeaekorean] + 16#60 [/grave] + 16#1E04 [/Bdotbelow] + 16#43F [/pecyrillic /afii10081] + 16#FBA8 [/hehinitialaltonearabic] + 16#1E3 [/aemacron] + 16#21E3 [/arrowdashdown] + 16#30B5 [/sakatakana] + 16#FF87 [/nukatakanahalfwidth] + 16#F6F0 [/osuperior] + 16#E59 [/ninethai] + 16#5C2 [/sindothebrew /afii57803] + 16#3238 [/ideographiclaborparen] + 16#9A1 [/ddabengali] + 16#10A [/Cdotaccent /Cdot] + 16#FEAE [/rehfinalarabic] + 16#1EAE [/Abreveacute] + 16#24E9 [/zcircle] + 16#4E9 [/obarredcyrillic] + 16#33BB [/nwsquare] + 16#28D [/wturned] + 16#315F [/wikorean] + 16#31 [/one] + 16#66C [/thousandsseparatorpersian /thousandsseparatorarabic] + 16#266C [/beamedsixteenthnotes] + 16#410 [/afii10017 /Acyrillic] + 16#A4B [/oomatragurmukhi] + 16#1B4 [/yhook] + 16#3086 [/yuhiragana] + 16#FF58 [/xmonospace] + 16#E2A [/sosuathai] + 16#2593 [/shadedark /dkshade] + 16#593 [/shalshelethebrew] + 16#337 [/solidusshortoverlaycmb] + 16#3209 [/chieuchparenkorean] + 16#DB [/Ucircumflex] + 16#1E7F [/vdotbelow] + 16#4BA [/Shhacyrillic] + 16#24BA [/Ecircle] + 16#338C [/mufsquare] + 16#25E [/eopenreversedclosed] + 16#2002 [/enspace] + 16#2 [/controlSOT] + 16#F76B [/Ksmall] + 16#FB4A [/tavdageshhebrew /tavdagesh /tavdages] + 16#A1C [/jagurmukhi] + 16#185 [/tonesix] + 16#F8EE [/bracketlefttp] + 16#3057 [/sihiragana] + 16#FF29 [/Imonospace] + 16#564 [/daarmenian] + 16#2564 [/SF470000] + 16#308 [/dieresiscmb] + 16#943 [/rvocalicvowelsigndeva] + 16#20AC [/euro /Euro] + 16#AC [/logicalnot] + 16#FE50 [/commasmall] + 16#1E50 [/Omacrongrave] + 16#248B [/fourperiod] + 16#260E [/telephoneblack] + 16#3B2 [/beta] + 16#9ED [/sevenbengali] + 16#156 [/Rcommaaccent /Rcedilla] + 16#3028 [/eighthangzhou] + 16#2791 [/eightcircleinversesansserif] + 16#FEFA [/lamalefhamzabelowfinalarabic] + 16#535 [/Echarmenian] + 16#2D9 [/dotaccent] + 16#914 [/audeva] + 16#207D [/parenleftsuperior] + 16#F7E6 [/AEsmall] + 16#7D [/braceright] + 16#1E21 [/gmacron] + 16#45C [/kjecyrillic /afii10109] + 16#A97 [/gagujarati] + 16#200 [/Adblgrave] + 16#2200 [/universal /forall] + 16#30D2 [/hikatakana] + 16#5DF [/finalnunhebrew /finalnun /afii57679] + 16#9BE [/aavowelsignbengali] + 16#127 [/hbar] + 16#F890 [/maitriupperleftthai] + 16#1ECB [/idotbelow] + 16#FECB [/aininitialarabic] + 16#33D8 [/pmsquare] + 16#317C [/siostikeutkorean] + 16#4E [/N] + 16#FDF2 [/lamlamhehisolatedarabic] + 16#42D [/afii10047 /Ereversedcyrillic] + 16#A68 [/twogurmukhi] + 16#1D1 [/Ocaron] + 16#21D1 [/arrowdblup] + 16#30A3 [/ismallkatakana] + 16#FF75 [/okatakanahalfwidth] + 16#F6DE [/threequartersemdash] + 16#E47 [/maitaikhuthai] + 16#5B0 [/shevawidehebrew /shevaquarterhebrew /shevanarrowhebrew /shevahebrew /sheva2e /sheva22 /sheva15 /sheva115 /sheva /afii57799] + 16#3226 [/sevenideographicparen] + 16#98F [/ebengali] + 16#F8 [/oslash] + 16#FE9C [/thehmedialarabic] + 16#24D7 [/hcircle] + 16#4D7 [/iebrevecyrillic] + 16#33A9 [/pasquare] + 16#227B [/succeeds] + 16#27B [/rhookturned] + 16#314D [/phieuphkorean] + 16#1F [/controlUS] + 16#FB67 [/ttehfinalarabic] + 16#A39 [/hagurmukhi] + 16#1A2 [/Oi] + 16#3074 [/pihiragana] + 16#FF46 [/fmonospace] + 16#E18 [/thothongthai] + 16#581 [/coarmenian] + 16#325 [/ringbelowcmb] + 16#2325 [/option] + 16#960 [/rrvocalicdeva] + 16#C9 [/Eacute] + 16#1E6D [/tdotbelow] + 16#24A8 [/mparen] + 16#4A8 [/Haabkhasiancyrillic] + 16#224C [/allequal] + 16#311E [/aibopomofo] + 16#62B [/theharabic /afii57419] + 16#FB38 [/tetdageshhebrew /tetdagesh] + 16#A0A [/uugurmukhi] + 16#173 [/uogonek] + 16#2173 [/fourroman] + 16#3045 [/usmallhiragana] + 16#FF17 [/sevenmonospace] + 16#552 [/Yiwnarmenian] + 16#2552 [/SF510000] + 16#931 [/rradeva] + 16#6D5 [/afii57534] + 16#FE3E [/dblanglebracketrightvertical] + 16#1E3E [/Macute] + 16#479 [/ukcyrillic] + 16#2479 [/sixparen] + 16#221D [/proportional] + 16#30EF [/wakatakana] + 16#3A0 [/Pi] + 16#3272 [/mieumacirclekorean] + 16#144 [/nacute] + 16#3016 [/whitelenticularbracketleft] + 16#FEE8 [/noonmedialarabic] + 16#1EE8 [/Uhornacute] + 16#2C7 [/caron] + 16#902 [/anusvaradeva] + 16#6B [/k] + 16#1E0F [/dlinebelow] + 16#44A [/hardsigncyrillic /afii10092] + 16#A85 [/agujarati] + 16#1EE [/Ezhcaron] + 16#30C0 [/dakatakana] + 16#FF92 [/mekatakanahalfwidth] + 16#F6FB [/Ogoneksmall] + 16#3243 [/ideographicreachparen] + 16#9AC [/babengali] + 16#115 [/ebreve] + 16#1EB9 [/edotbelow] + 16#4F4 [/Chedieresiscyrillic] + 16#33C6 [/coverkgsquare] + 16#298 [/bilabialclick] + 16#316A [/rieultikeutkorean] + 16#203C [/exclamdbl] + 16#3C [/less] + 16#41B [/afii10029 /Elcyrillic] + 16#1BF [/wynn] + 16#3091 [/wehiragana] + 16#FF63 [/cornerbracketrighthalfwidth] + 16#F6CC [/DieresisAcute] + 16#E35 [/saraiithai] + 16#59E [/gershayimaccenthebrew] + 16#342 [/perispomenigreekcmb] + 16#3214 [/siosaparenkorean] + 16#E6 [/ae] + 16#FE8A [/yehhamzaabovefinalarabic] + 16#1E8A [/Xdotaccent] + 16#24C5 [/Pcircle] + 16#3397 [/dlsquare] + 16#269 [/iotalatin] + 16#313B [/rieulmieumkorean] + 16#D [/controlCR] + 16#200D [/afii301] + 16#F776 [/Vsmall] + 16#648 [/wawarabic /afii57448] + 16#3EC [/Shimacoptic] + 16#A27 [/dhagurmukhi] + 16#190 [/Eopen] + 16#F8F9 [/bracketrighttp] + 16#3062 [/dihiragana] + 16#2190 [/arrowleft] + 16#FF34 [/Tmonospace] + 16#E06 [/khorakhangthai] + 16#56F [/kenarmenian] + 16#313 [/commaabovecmb] + 16#B7 [/middot /periodcentered] + 16#6F2 [/twopersian] + 16#1E5B [/rdotbelow] + 16#FE5B [/braceleftsmall] + 16#2496 [/fifteenperiod] + 16#496 [/Zhedescendercyrillic] + 16#310C [/lbopomofo] + 16#3BD [/nu] + 16#328F [/ideographearthcircle] + 16#9F8 [/denominatorminusonenumeratorbengali] + 16#161 [/scaron] + 16#2161 [/Tworoman] + 16#FF05 [/percentmonospace] + 16#540 [/Hoarmenian] + 16#2E4 [/glottalstopreversedsuperior] + 16#91F [/ttadeva] + 16#2088 [/eightinferior] + 16#F7F1 [/Ntildesmall] + 16#1E2C [/Itildebelow] + 16#467 [/yuslittlecyrillic] + 16#2467 [/eightcircle] + 16#3339 [/herutusquare] + 16#AA2 [/ddhagujarati] + 16#20B [/iinvertedbreve] + 16#220B [/suchthat] + 16#30DD [/pokatakana] + 16#5EA [/tavhebrew /tav /afii57690] + 16#38E [/Upsilontonos] + 16#3260 [/kiyeokcirclekorean] + 16#132 [/IJ] + 16#3004 [/jis] + 16#FED6 [/qaffinalarabic] + 16#1ED6 [/Ocircumflextilde] + 16#2B5 [/rhookturnedsuperior] + 16#3187 [/yoyakorean] + 16#59 [/Y] + 16#438 [/iicyrillic /afii10074] + 16#A73 [/uragurmukhi] + 16#1DC [/udieresisgrave] + 16#30AE [/gikatakana] + 16#FF80 [/takatakanahalfwidth] + 16#F6E9 [/asuperior] + 16#E52 [/twothai] + 16#5BB [/qubutswidehebrew /qubutsquarterhebrew /qubutsnarrowhebrew /qubutshebrew /qubuts31 /qubuts25 /qubuts18 /qubuts /afii57796] + 16#3231 [/ideographicstockparen] + 16#99A [/cabengali] + 16#2103 [/centigrade] + 16#103 [/abreve] + 16#FEA7 [/khahinitialarabic] + 16#1EA7 [/acircumflexgrave] + 16#24E2 [/scircle] + 16#FC4B [/noonjeemisolatedarabic] + 16#33B4 [/pvsquare] + 16#4E2 [/Imacroncyrillic] + 16#2286 [/subsetorequal /reflexsubset] + 16#286 [/eshcurl] + 16#3158 [/wakorean] + 16#2A [/asterisk] + 16#665 [/fivehackarabic /fivearabic /afii57397] + 16#2665 [/heartsuitblack /heart] + 16#409 [/afii10058 /Ljecyrillic] + 16#1AD [/thook] + 16#307F [/mihiragana] + 16#FF51 [/qmonospace] + 16#E23 [/roruathai] + 16#258C [/lfblock] + 16#330 [/tildebelowcmb] + 16#3202 [/tikeutparenkorean] + 16#96B [/fivedeva] + 16#D4 [/Ocircumflex] + 16#1E78 [/Utildeacute] + 16#24B3 [/xparen] + 16#4B3 [/hadescendercyrillic] + 16#3385 [/KBsquare] + 16#AEE [/eightgujarati] + 16#257 [/dhook] + 16#3129 [/iubopomofo] + 16#F764 [/Dsmall] + 16#636 [/dadarabic /afii57430] + 16#3DA [/Stigmagreek] + 16#FB43 [/pefinaldageshhebrew] + 16#A15 [/kagurmukhi] + 16#17E [/zcaron] + 16#F8E7 [/arrowhorizex] + 16#3050 [/guhiragana] + 16#FF22 [/Bmonospace] + 16#55D [/commaarmenian] + 16#255D [/SF260000] + 16#301 [/acutecomb /acutecmb] + 16#93C [/nuktadeva] + 16#A5 [/yen] + 16#FE49 [/overlinedashed] + 16#1E49 [/nlinebelow] + 16#2484 [/seventeenparen] + 16#484 [/palatalizationcyrilliccmb] + 16#ABF [/ivowelsigngujarati] + 16#2228 [/logicalor] + 16#30FA [/vokatakana] + 16#F735 [/fiveoldstyle] + 16#3AB [/Upsilondieresis] + 16#9E6 [/zerobengali] + 16#14F [/obreve] + 16#3021 [/onehangzhou] + 16#278A [/onecircleinversesansserif] + 16#FEF3 [/yehinitialarabic /alefmaksurainitialarabic] + 16#1EF3 [/ygrave] + 16#2D2 [/ringhalfrightcentered] + 16#90D [/ecandradeva] + 16#2076 [/sixsuperior] + 16#76 [/v] + 16#1E1A [/Etildebelow] + 16#455 [/dzecyrillic /afii10102] + 16#3327 [/tonsquare] + 16#A90 [/aigujarati] + 16#30CB [/nikatakana] + 16#FF9D [/nkatakanahalfwidth] + 16#5D8 [/tethebrew /tet /afii57672] + 16#25D8 [/invbullet /bulletinverse] + 16#9B7 [/ssabengali] + 16#120 [/Gdotaccent /Gdot] + 16#F889 [/maitaikhuleftthai] + 16#FEC4 [/tahmedialarabic] + 16#1EC4 [/Ecircumflextilde] + 16#33D1 [/squareln] + 16#22A3 [/tackleft] + 16#2A3 [/dzaltone] + 16#3175 [/pieupsiostikeutkorean] + 16#47 [/G] + 16#426 [/afii10040 /Tsecyrillic] + 16#1CA [/NJ] + 16#309C [/semivoicedmarkkana] + 16#FF6E [/yosmallkatakanahalfwidth] + 16#F6D7 [/dieresisacute] + 16#E40 [/saraethai] + 16#25A9 [/squarediagonalcrosshatchfill] + 16#5A9 [/telishaqetanahebrew] + 16#988 [/iibengali] + 16#F1 [/ntilde] + 16#1E95 [/zlinebelow] + 16#24D0 [/acircle] + 16#4D0 [/Abrevecyrillic] + 16#33A2 [/kmsquaredsquare] + 16#3146 [/ssangsioskorean] + 16#18 [/controlCAN] + 16#2018 [/quoteleft] + 16#A32 [/lagurmukhi] + 16#19B [/lambdastroke] + 16#306D [/nehiragana] + 16#FF3F [/underscoremonospace] + 16#E11 [/thonangmonthothai] + 16#57A [/peharmenian] + 16#31E [/downtackbelowcmb] + 16#959 [/khhadeva] + 16#C2 [/Acircumflex] + 16#FE66 [/equalsmall] + 16#1E66 [/Scarondotaccent] + 16#24A1 [/fparen] + 16#4A1 [/kabashkircyrillic] + 16#2245 [/approximatelyequal /congruent] + 16#3117 [/zbopomofo] + 16#624 [/wawhamzaabovearabic /afii57412] + 16#3C8 [/psi] + 16#FB31 [/betdageshhebrew /betdagesh] + 16#16C [/Ubreve] + 16#FF10 [/zeromonospace] + 16#54B [/Jheharmenian] + 16#92A [/padeva] + 16#F7FC [/Udieresissmall] + 16#1E37 [/ldotbelow] + 16#FE37 [/braceleftvertical] + 16#2472 [/nineteencircle] + 16#472 [/afii10147 /Fitacyrillic] + 16#5344 [/twentyhangzhou] + 16#AAD [/bhagujarati] + 16#216 [/Uinvertedbreve] + 16#30E8 [/yokatakana] + 16#399 [/Iota] + 16#FB02 [/fl] + 16#326B [/thieuthcirclekorean] + 16#13D [/Lcaron] + 16#300F [/whitecornerbracketright] + 16#1EE1 [/ohorntilde] + 16#251C [/SF080000] + 16#2C0 [/glottalstopmod] + 16#64 [/d] + 16#1E08 [/Ccedillaacute] + 16#443 [/ucyrillic /afii10085] + 16#3315 [/kiroguramusquare] + 16#1E7 [/gcaron] + 16#21E7 [/arrowupwhite] + 16#30B9 [/sukatakana] + 16#FF8B [/hikatakanahalfwidth] + 16#F6F4 [/Brevesmall] + 16#25C6 [/blackdiamond] + 16#323C [/ideographicsuperviseparen] + 16#9A5 [/thabengali] + 16#10E [/Dcaron] + 16#FEB2 [/seenfinalarabic] + 16#1EB2 [/Abrevehookabove] + 16#33BF [/mwmegasquare] + 16#291 [/zcurl] + 16#3163 [/ikorean] + 16#2035 [/primereversed] + 16#35 [/five] + 16#414 [/afii10021 /Decyrillic] + 16#FB7D [/tchehmedialarabic] + 16#1B8 [/Ezhreversed] + 16#308A [/rihiragana] + 16#FF5C [/barmonospace] + 16#F6C5 [/afii10064] + 16#E2E [/honokhukthai] + 16#597 [/reviamugrashhebrew /reviahebrew] + 16#33B [/squarebelowcmb] + 16#320D [/hieuhparenkorean] + 16#DF [/germandbls] + 16#1E83 [/wacute] + 16#24BE [/Icircle] + 16#4BE [/Chedescenderabkhasiancyrillic] + 16#3390 [/Hzsquare] + 16#2262 [/notidentical] + 16#3134 [/nieunkorean] + 16#6 [/controlACK] + 16#F76F [/Osmall] + 16#641 [/feharabic /afii57441] + 16#2641 [/earth] + 16#3E5 [/feicoptic] + 16#FB4E [/perafehebrew] + 16#A20 [/tthagurmukhi] + 16#189 [/Dafrican] + 16#F8F2 [/braceleftmid] + 16#305B [/sehiragana] + 16#FF2D [/Mmonospace] + 16#568 [/etarmenian] + 16#FCD1 [/meemmeeminitialarabic] + 16#2568 [/SF460000] + 16#30C [/caroncmb] + 16#947 [/evowelsigndeva] + 16#B0 [/degree] + 16#FE54 [/semicolonsmall] + 16#1E54 [/Pacute] + 16#248F [/eightperiod] + 16#3105 [/bbopomofo] + 16#3B6 [/zeta] + 16#FB1F [/yodyodpatahhebrew /doubleyodpatahhebrew /doubleyodpatah /afii57705] + 16#9F1 [/ralowerdiagonalbengali] + 16#15A [/Sacute] + 16#539 [/Toarmenian] + 16#FCA2 [/tehhahinitialarabic] + 16#2DD [/hungarumlaut] + 16#918 [/ghadeva] + 16#2081 [/oneinferior] + 16#F7EA [/Ecircumflexsmall] + 16#1E25 [/hdotbelow] + 16#2460 [/onecircle] + 16#460 [/Omegacyrillic] + 16#A9B [/chagujarati] + 16#204 [/Edblgrave] + 16#30D6 [/bukatakana] + 16#5E3 [/finalpehebrew /finalpe /afii57683] + 16#25E3 [/blacklowerlefttriangle] + 16#387 [/anoteleia] + 16#9C2 [/uuvowelsignbengali] + 16#12B [/imacron] + 16#F894 [/maichattawalowrightthai] + 16#212B [/angstrom] + 16#1ECF [/ohookabove] + 16#FECF [/ghaininitialarabic] + 16#FC73 [/tehnoonfinalarabic] + 16#33DC [/svsquare] + 16#3180 [/ssangieungkorean] + 16#52 [/R] + 16#431 [/becyrillic /afii10066] + 16#3303 [/aarusquare] + 16#A6C [/sixgurmukhi] + 16#1D5 [/Udieresismacron] + 16#30A7 [/esmallkatakana] + 16#FF79 [/kekatakanahalfwidth] + 16#F6E2 [/commasuperior] + 16#E4B [/maichattawathai] + 16#5B4 [/hiriq2d /hiriq21 /hiriq14 /hiriq /hiriqwidehebrew /hiriqquarterhebrew /hiriqnarrowhebrew /hiriqhebrew /afii57793] + 16#25B4 [/blackuppointingsmalltriangle] + 16#322A [/ideographicmoonparen] + 16#993 [/obengali] + 16#FC [/udieresis] + 16#FEA0 [/jeemmedialarabic] + 16#1EA0 [/Adotbelow] + 16#4DB [/schwadieresiscyrillic] + 16#24DB [/lcircle] + 16#33AD [/radsquare] + 16#27F [/rfishhookreversed] + 16#3151 [/yakorean] + 16#23 [/numbersign] + 16#402 [/afii10051 /Djecyrillic] + 16#FB6B [/vehfinalarabic] + 16#1A6 [/yr] + 16#3078 [/hehiragana] + 16#FF4A [/jmonospace] + 16#E1C [/phophungthai] + 16#585 [/oharmenian] + 16#329 [/verticallinebelowcmb] + 16#2329 [/angleleft] + 16#964 [/danda] + 16#CD [/Iacute] + 16#1E71 [/tcircumflexbelow] + 16#24AC [/qparen] + 16#4AC [/Tedescendercyrillic] + 16#337E [/meizierasquare] + 16#AE7 [/onegujarati] + 16#250 [/aturned] + 16#2250 [/approaches] + 16#3122 [/anbopomofo] + 16#262F [/yinyang] + 16#62F [/dalarabic /afii57423] + 16#3D3 [/Upsilonacutehooksymbolgreek] + 16#FB3C [/lameddageshhebrew /lameddagesh] + 16#32A5 [/ideographiccentrecircle] + 16#177 [/ycircumflex] + 16#2177 [/eightroman] + 16#3049 [/osmallhiragana] + 16#FF1B [/semicolonmonospace] + 16#556 [/Feharmenian] + 16#2556 [/SF210000] + 16#935 [/vadeva] + 16#FE42 [/cornerbracketrightvertical] + 16#1E42 [/Mdotbelow] + 16#247D [/tenparen] + 16#47D [/omegatitlocyrillic] + 16#AB8 [/sagujarati] + 16#30F3 [/nkatakana] + 16#3A4 [/Tau] + 16#3276 [/cieucacirclekorean] + 16#9DF [/yyabengali] + 16#148 [/ncaron] + 16#FEEC [/hehmedialarabic] + 16#1EEC [/Uhornhookabove] + 16#2CB [/fourthtonechinese] + 16#906 [/aadeva] + 16#6F [/o] + 16#1E13 [/dcircumflexbelow] + 16#44E [/iucyrillic /afii10096] + 16#A89 [/ugujarati] + 16#1F2 [/Dz] + 16#30C4 [/tukatakana] + 16#FF96 [/yokatakanahalfwidth] + 16#F6FF [/Zcaronsmall] + 16#25D1 [/circlewithrighthalfblack] + 16#5D1 [/bethebrew /afii57665 /bet] + 16#375 [/numeralsignlowergreek] + 16#9B0 [/rabengali] + 16#119 [/eogonek] + 16#1EBD [/etilde] + 16#4F8 [/Yerudieresiscyrillic] + 16#FC61 [/shaddadammaarabic] + 16#33CA [/hasquare] + 16#316E [/mieumpieupkorean] + 16#40 [/at] + 16#41F [/afii10033 /Pecyrillic] + 16#A5A [/ghhagurmukhi] + 16#1C3 [/clickretroflex] + 16#FF67 [/asmallkatakanahalfwidth] + 16#F6D0 [/Macron] + 16#E39 [/sarauuthai] + 16#3218 [/khieukhaparenkorean] + 16#981 [/candrabindubengali] + 16#EA [/ecircumflex] + 16#1E8E [/Ydotaccent] + 16#FE8E [/aleffinalarabic] + 16#24C9 [/Tcircle] + 16#339B [/mumsquare] + 16#26D [/lhookretroflex] + 16#313F [/rieulphieuphkorean] + 16#11 [/controlDC1] + 16#F77A [/Zsmall] + 16#64C [/dammatanarabic /dammatanaltonearabic /afii57452] + 16#3F0 [/kappasymbolgreek] + 16#FB59 [/pehmedialarabic] + 16#A2B [/phagurmukhi] + 16#194 [/Gammaafrican] + 16#F8FD [/bracerightmid] + 16#3066 [/tehiragana] + 16#2194 [/arrowboth] + 16#FF38 [/Xmonospace] + 16#E0A [/chochangthai] + 16#573 [/cheharmenian] + 16#317 [/acutebelowcmb] + 16#952 [/anudattadeva] + 16#BB [/guillemotright] + 16#6F6 [/sixpersian] + 16#1E5F [/rlinebelow] + 16#FE5F [/numbersignsmall] + 16#249A [/nineteenperiod] + 16#49A [/Kadescendercyrillic] + 16#3110 [/jbopomofo] + 16#261D [/pointingindexupwhite] + 16#3C1 [/rho] + 16#FB2A [/shinshindothebrew /shinshindot /afii57694] + 16#165 [/tcaron] + 16#2165 [/Sixroman] + 16#FF09 [/parenrightmonospace] + 16#544 [/Menarmenian] + 16#2E8 [/tonebarlowmod] + 16#923 [/nnadeva] + 16#F7F5 [/Otildesmall] + 16#FE30 [/twodotleadervertical] + 16#1E30 [/Kacute] + 16#46B [/yusbigcyrillic] + 16#246B [/twelvecircle] + 16#AA6 [/dagujarati] + 16#20F [/oinvertedbreve] + 16#220F [/product] + 16#30E1 [/mekatakana] + 16#392 [/Beta] + 16#3264 [/mieumcirclekorean] + 16#9CD [/viramabengali] + 16#136 [/Kcommaaccent /Kcedilla] + 16#3008 [/anglebracketleft] + 16#FEDA [/kaffinalarabic] + 16#1EDA [/Ohornacute] + 16#2B9 [/primemod] + 16#318B [/yuyekorean] + 16#5D [/bracketright] + 16#698 [/jeharabic /afii57508] + 16#1E01 [/aringbelow] + 16#43C [/emcyrillic /afii10078] + 16#FBA5 [/hehhamzaabovefinalarabic] + 16#21E0 [/arrowdashleft] + 16#1E0 [/Adotmacron] + 16#30B2 [/gekatakana] + 16#FF84 [/tokatakanahalfwidth] + 16#F6ED [/isuperior] + 16#E56 [/sixthai] + 16#25BF [/whitedownpointingsmalltriangle] + 16#5BF [/rafehebrew /rafe /afii57841] + 16#3235 [/ideographicspecialparen] + 16#99E [/nyabengali] + 16#107 [/cacute] + 16#1EAB [/acircumflextilde] + 16#24E6 [/wcircle] + 16#4E6 [/Odieresiscyrillic] + 16#33B8 [/kvsquare] + 16#28A [/upsilonlatin] + 16#228A [/subsetnotequal] + 16#315C [/ukorean] + 16#202E [/afii61575] + 16#2E [/period] + 16#2669 [/quarternote] + 16#669 [/ninearabic /ninehackarabic /afii57401] + 16#A48 [/aimatragurmukhi] + 16#1B1 [/Upsilonafrican] + 16#3083 [/yasmallhiragana] + 16#FF55 [/umonospace] + 16#F6BE [/dotlessj] + 16#E27 [/wowaenthai] + 16#2590 [/rtblock] + 16#334 [/tildeoverlaycmb] + 16#3206 [/siosparenkorean] + 16#96F [/ninedeva] + 16#D8 [/Oslash] + 16#2713 [/checkmark] + 16#1E7C [/Vtilde] + 16#4B7 [/chedescendercyrillic] + 16#24B7 [/Bcircle] + 16#3389 [/kcalsquare] + 16#25B [/eopen] + 16#F768 [/Hsmall] + 16#263A [/whitesmilingface /smileface] + 16#63A [/ghainarabic /afii57434] + 16#3DE [/Koppagreek] + 16#FB47 [/qofdageshhebrew /qofdagesh] + 16#A19 [/ngagurmukhi] + 16#182 [/Btopbar] + 16#F8EB [/parenlefttp] + 16#3054 [/gohiragana] + 16#FF26 [/Fmonospace] + 16#561 [/aybarmenian] + 16#FCCA [/lamhahinitialarabic] + 16#2561 [/SF190000] + 16#2305 [/projective] + 16#305 [/overlinecmb] + 16#940 [/iivowelsigndeva] + 16#20A9 [/won] + 16#A9 [/copyright] + 16#FE4D [/lowlinedashed] + 16#1E4D [/otildeacute] + 16#2488 [/oneperiod] + 16#AC3 [/rvocalicvowelsigngujarati] + 16#222C [/dblintegral] + 16#30FE [/voicediterationkatakana] + 16#F739 [/nineoldstyle] + 16#3AF [/iotatonos] + 16#9EA [/fourbengali] + 16#2153 [/onethird] + 16#153 [/oe] + 16#3025 [/fivehangzhou] + 16#278E [/fivecircleinversesansserif] + 16#1EF7 [/yhookabove] + 16#FEF7 [/lamalefhamzaaboveisolatedarabic] + 16#532 [/Benarmenian] + 16#2D6 [/plusmod] + 16#911 [/ocandradeva] + 16#207A [/plussuperior] + 16#F7E3 [/Atildesmall] + 16#7A [/z] + 16#1E1E [/Fdotaccent] + 16#459 [/ljecyrillic /afii10106] + 16#332B [/paasentosquare] + 16#A94 [/augujarati] + 16#1FD [/aeacute] + 16#30CF [/hakatakana] + 16#5DC [/lamedhebrew /lamed /afii57676] + 16#124 [/Hcircumflex] + 16#F88D [/maithoupperleftthai] + 16#FEC8 [/zahmedialarabic] + 16#1EC8 [/Ihookabove] + 16#33D5 [/squaremil] + 16#2A7 [/tesh] + 16#3179 [/kapyeounssangpieupkorean] + 16#4B [/K] + 16#F7B4 [/Acutesmall] + 16#686 [/tcheharabic /afii57507] + 16#42A [/afii10044 /Hardsigncyrillic] + 16#FB93 [/gaffinalarabic] + 16#1CE [/acaron] + 16#FF72 [/ikatakanahalfwidth] + 16#F6DB [/trademarkserif] + 16#E44 [/saraaimaimalaithai] + 16#5AD [/dehihebrew] + 16#3223 [/fourideographicparen] + 16#98C [/lvocalicbengali] + 16#F5 [/otilde] + 16#1E99 [/yring] + 16#24D4 [/ecircle] + 16#4D4 [/Aiecyrillic] + 16#33A6 [/kmcubedsquare] + 16#278 [/philatin] + 16#314A [/chieuchkorean] + 16#1C [/controlFS] + 16#201C [/quotedblleft] + 16#A36 [/shagurmukhi] + 16#19F [/Ocenteredtilde] + 16#3071 [/pahiragana] + 16#FF43 [/cmonospace] + 16#E15 [/totaothai] + 16#57E [/vewarmenian] + 16#322 [/hookretroflexbelowcmb] + 16#95D [/rhadeva] + 16#C6 [/AE] + 16#FE6A [/percentsmall] + 16#1E6A [/Tdotaccent] + 16#24A5 [/jparen] + 16#FC0E [/tehmeemisolatedarabic] + 16#4A5 [/enghecyrillic] + 16#AE0 [/rrvocalicgujarati] + 16#311B [/obopomofo] + 16#628 [/afii57416 /beharabic] + 16#3CC [/omicrontonos] + 16#FB35 [/vavdageshhebrew /vavdagesh65 /vavdagesh /afii57723] + 16#329E [/ideographicprintcircle] + 16#A07 [/igurmukhi] + 16#2170 [/oneroman] + 16#170 [/Uhungarumlaut /Udblacute] + 16#3042 [/ahiragana] + 16#FF14 [/fourmonospace] + 16#54F [/Tiwnarmenian] + 16#92E [/madeva] + 16#6D2 [/yehbarreearabic /afii57519] + 16#1E3B [/llinebelow] + 16#FE3B [/blacklenticularbracketleftvertical] + 16#2476 [/threeparen] + 16#476 [/Izhitsadblgravecyrillic] + 16#221A [/radical] + 16#30EC [/rekatakana] + 16#39D [/Nu] + 16#326F [/nieunacirclekorean] + 16#141 [/Lslash] + 16#3013 [/getamark] + 16#1EE5 [/udotbelow] + 16#2C4 [/arrowheadupmod] + 16#68 [/h] + 16#1E0C [/Ddotbelow] + 16#447 [/checyrillic /afii10089] + 16#A82 [/anusvaragujarati] + 16#1EB [/oogonek] + 16#30BD [/sokatakana] + 16#FF8F [/makatakanahalfwidth] + 16#F6F8 [/Hungarumlautsmall] + 16#25CA [/lozenge] + 16#3240 [/ideographicfestivalparen] + 16#112 [/Emacron] + 16#FEB6 [/sheenfinalarabic] + 16#1EB6 [/Abrevedotbelow] + 16#4F1 [/udieresiscyrillic] + 16#33C3 [/bqsquare] + 16#2295 [/pluscircle /circleplus] + 16#295 [/glottalstopreversed] + 16#3167 [/nieunsioskorean] + 16#2039 [/guilsinglleft] + 16#F7A2 [/centoldstyle] + 16#39 [/nine] + 16#418 [/afii10026 /Iicyrillic] + 16#21BC [/harpoonleftbarbup] + 16#1BC [/Tonefive] + 16#308E [/wasmallhiragana] + 16#F6C9 [/Acute] + 16#E32 [/saraaathai] + 16#59B [/tevirlefthebrew /tevirhebrew] + 16#33F [/dbloverlinecmb] + 16#3211 [/rieulaparenkorean] + 16#E3 [/atilde] + 16#1E87 [/wdotaccent] + 16#4C2 [/zhebrevecyrillic] + 16#24C2 [/Mcircle] + 16#3394 [/thzsquare] + 16#2266 [/lessoverequal] + 16#266 [/hhook] + 16#3138 [/ssangtikeutkorean] + 16#A [/controlLF] + 16#F773 [/Ssmall] + 16#645 [/meemarabic /afii57445] + 16#3E9 [/horicoptic] + 16#A24 [/tagurmukhi] + 16#18D [/deltaturned] + 16#F8F6 [/parenrighttp] + 16#305F [/tahiragana] + 16#FF31 [/Qmonospace] + 16#E03 [/khokhuatthai] + 16#56C [/liwnarmenian] + 16#FCD5 [/noonmeeminitialarabic] + 16#256C [/SF440000] + 16#2310 [/revlogicalnot /logicalnotreversed] + 16#310 [/candrabinducmb] + 16#94B [/ovowelsigndeva] + 16#B4 [/acute] + 16#1E58 [/Rdotaccent] + 16#2493 [/twelveperiod] + 16#493 [/ghestrokecyrillic] + 16#2237 [/proportion] + 16#3109 [/dbopomofo] + 16#3BA [/kappa] + 16#328C [/ideographwatercircle] + 16#9F5 [/twonumeratorbengali] + 16#215E [/seveneighths] + 16#15E [/Scedilla] + 16#FF02 [/quotedblmonospace] + 16#53D [/Xeharmenian] + 16#91C [/jadeva] + 16#2085 [/fiveinferior] + 16#F7EE [/Icircumflexsmall] + 16#1E29 [/hcedilla] + 16#2464 [/fivecircle] + 16#464 [/Eiotifiedcyrillic] + 16#3336 [/hekutaarusquare] + 16#A9F [/ttagujarati] + 16#208 [/Idblgrave] + 16#2208 [/element] + 16#30DA [/pekatakana] + 16#5E7 [/qofhebrew /qof /afii57687] + 16#12F [/iogonek] + 16#F898 [/thanthakhatlowleftthai] + 16#3001 [/ideographiccomma] + 16#1ED3 [/ocircumflexgrave] + 16#FED3 [/fehinitialarabic] + 16#2B2 [/jsuperior] + 16#3184 [/kapyeounphieuphkorean] + 16#56 [/V] + 16#F7BF [/questiondownsmall] + 16#691 [/rreharabic /afii57513] + 16#FDFA [/sallallahoualayhewasallamarabic] + 16#435 [/iecyrillic /afii10070] + 16#A70 [/tippigurmukhi] + 16#1D9 [/Udieresiscaron] + 16#30AB [/kakatakana] + 16#FF7D [/sukatakanahalfwidth] + 16#F6E6 [/hyphensuperior] + 16#E4F [/fongmanthai] + 16#5B8 [/qamatswidehebrew /qamatsquarterhebrew /qamatsqatanwidehebrew /qamatsqatanquarterhebrew /qamatsqatannarrowhebrew /qamatsqatanhebrew /qamatsnarrowhebrew /qamatshebrew /qamatsde /qamats33 /qamats29 /qamats27 /qamats1c /qamats1a /qamats10 /qamats /afii57797] + 16#322E [/ideographicmetalparen] + 16#997 [/gabengali] + 16#100 [/Amacron] + 16#FEA4 [/hahmedialarabic] + 16#1EA4 [/Acircumflexacute] + 16#4DF [/zedieresiscyrillic] + 16#24DF [/pcircle] + 16#33B1 [/nssquare] + 16#FC48 [/meemmeemisolatedarabic] + 16#2283 [/superset /propersuperset] + 16#283 [/esh] + 16#3155 [/yeokorean] + 16#27 [/quotesingle] + 16#662 [/twoarabic /twohackarabic /afii57394] + 16#2662 [/diamondsuitwhite] + 16#406 [/afii10055 /Icyrillic] + 16#A41 [/umatragurmukhi] + 16#1AA [/eshreversedloop] + 16#307C [/bohiragana] + 16#FF4E [/nmonospace] + 16#E20 [/phosamphaothai] + 16#589 [/periodarmenian] + 16#32D [/circumflexbelowcmb] + 16#968 [/twodeva] + 16#D1 [/Ntilde] + 16#1E75 [/utildebelow] + 16#24B0 [/uparen] + 16#4B0 [/Ustraightstrokecyrillic] + 16#3382 [/muasquare] + 16#AEB [/fivegujarati] + 16#254 [/oopen] + 16#3126 [/erbopomofo] + 16#F761 [/Asmall] + 16#633 [/seenarabic /afii57427] + 16#FB40 [/nundageshhebrew /nundagesh] + 16#32A9 [/ideographicmedicinecircle] + 16#217B [/twelveroman] + 16#17B [/Zdotaccent /Zdot] + 16#304D [/kihiragana] + 16#FF1F [/questionmonospace] + 16#55A [/apostrophearmenian] + 16#255A [/SF380000] + 16#939 [/hadeva] + 16#20A2 [/cruzeiro] + 16#A2 [/cent] + 16#1E46 [/Ndotbelow] + 16#481 [/koppacyrillic] + 16#2481 [/fourteenparen] + 16#ABC [/nuktagujarati] + 16#2225 [/parallel] + 16#30F7 [/vakatakana] + 16#F732 [/twooldstyle] + 16#3A8 [/Psi] + 16#327A [/phieuphacirclekorean] + 16#9E3 [/llvocalicvowelsignbengali] + 16#14C [/Omacron] + 16#301E [/quotedblprime] + 16#FEF0 [/alefmaksurafinalarabic] + 16#1EF0 [/Uhorndotbelow] + 16#FC94 [/yehnoonfinalarabic] + 16#22CF [/curlyand] + 16#2CF [/acutelowmod] + 16#90A [/uudeva] + 16#73 [/s] + 16#1E17 [/emacronacute] + 16#452 [/djecyrillic /afii10099] + 16#A8D [/ecandragujarati] + 16#30C8 [/tokatakana] + 16#FF9A [/rekatakanahalfwidth] + 16#5D5 [/vavhebrew /vav /afii57669] + 16#FD3E [/parenleftaltonearabic] + 16#11D [/gcircumflex] + 16#F886 [/saraiileftthai] + 16#1EC1 [/ecircumflexgrave] + 16#33CE [/squarekmcapital] + 16#2A0 [/qhook] + 16#3172 [/pieupkiyeokkorean] + 16#2044 [/fraction] + 16#44 [/D] + 16#2423 [/blank] + 16#423 [/afii10037 /Ucyrillic] + 16#A5E [/fagurmukhi] + 16#1C7 [/LJ] + 16#FF6B [/osmallkatakanahalfwidth] + 16#F6D4 [/cyrbreve] + 16#25A6 [/squareorthogonalcrosshatchfill] + 16#5A6 [/merkhakefulalefthebrew /merkhakefulahebrew] + 16#321C [/cieucuparenkorean] + 16#985 [/abengali] + 16#EE [/icircumflex] + 16#1E92 [/Zdotbelow] + 16#FE92 [/behmedialarabic] + 16#24CD [/Xcircle] + 16#339F [/mmsquaredsquare] + 16#271 [/mhook] + 16#2271 [/notgreaternorequal] + 16#3143 [/ssangpieupkorean] + 16#2015 [/horizontalbar /afii00208] + 16#15 [/controlNAK] + 16#650 [/kasraarabic /afii57456] + 16#A2F [/yagurmukhi] + 16#2198 [/arrowdownright] + 16#198 [/Khook] + 16#306A [/nahiragana] + 16#FF3C [/backslashmonospace] + 16#E0E [/dochadathai] + 16#577 [/shaarmenian] + 16#31B [/horncmb] + 16#BF [/questiondown] + 16#1E63 [/sdotbelow] + 16#FE63 [/hyphensmall] + 16#249E [/cparen] + 16#49E [/Kastrokecyrillic] + 16#3114 [/chbopomofo] + 16#FFE6 [/wonmonospace] + 16#621 [/hamzalowarabic /hamzaarabic /afii57409] + 16#3C5 [/upsilon] + 16#FB2E [/alefpatahhebrew] + 16#169 [/utilde] + 16#2169 [/Tenroman] + 16#FF0D [/hyphenmonospace] + 16#548 [/Voarmenian] + 16#927 [/dhadeva] + 16#F7F9 [/Ugravesmall] + 16#FE34 [/wavyunderscorevertical] + 16#1E34 [/Klinebelow] + 16#246F [/sixteencircle] + 16#46F [/ksicyrillic] + 16#AAA [/pagujarati] + 16#213 [/rinvertedbreve] + 16#2213 [/minusplus] + 16#30E5 [/yusmallkatakana] + 16#5F2 [/yodyodhebrew /afii57718] + 16#396 [/Zeta] + 16#3268 [/cieuccirclekorean] + 16#13A [/lacute] + 16#300C [/cornerbracketleft] + 16#FEDE [/lamfinalarabic] + 16#1EDE [/Ohornhookabove] + 16#2BD [/commareversedmod /afii64937] + 16#61 [/a] + 16#1E05 [/bdotbelow] + 16#440 [/ercyrillic /afii10082] + 16#FBA9 [/hehmedialaltonearabic] + 16#21E4 [/arrowtableft] + 16#1E4 [/Gstroke] + 16#30B6 [/zakatakana] + 16#FF88 [/nekatakanahalfwidth] + 16#F6F1 [/rsuperior] + 16#E5A [/angkhankhuthai] + 16#25C3 [/whiteleftpointingsmalltriangle] + 16#5C3 [/sofpasuqhebrew /afii57658] + 16#3239 [/ideographicrepresentparen] + 16#9A2 [/ddhabengali] + 16#10B [/cdotaccent /cdot] + 16#1EAF [/abreveacute] + 16#4EA [/Obarreddieresiscyrillic] + 16#33BC [/muwsquare] + 16#28E [/yturned] + 16#3160 [/yukorean] + 16#2032 [/minute] + 16#32 [/two] + 16#266D [/musicflatsign] + 16#66D [/asteriskaltonearabic /asteriskarabic /afii63167] + 16#411 [/afii10018 /Becyrillic] + 16#A4C [/aumatragurmukhi] + 16#1B5 [/Zstroke] + 16#21B5 [/carriagereturn] + 16#3087 [/yosmallhiragana] + 16#FF59 [/ymonospace] + 16#E2B [/hohipthai] + 16#594 [/zaqefqatanhebrew] + 16#338 [/soliduslongoverlaycmb] + 16#320A [/khieukhparenkorean] + 16#DC [/Udieresis] + 16#1E80 [/Wgrave] + 16#4BB [/shhacyrillic] + 16#24BB [/Fcircle] + 16#338D [/mugsquare] + 16#25F [/jdotlessstroke] + 16#3131 [/kiyeokkorean] + 16#3 [/controlETX] + 16#F76C [/Lsmall] + 16#3E2 [/Sheicoptic] + 16#FB4B [/vavholamhebrew /vavholam /afii57700] + 16#A1D [/jhagurmukhi] + 16#186 [/Oopen] + 16#F8EF [/bracketleftex] + 16#3058 [/zihiragana] + 16#FF2A [/Jmonospace] + 16#565 [/echarmenian] + 16#2565 [/SF480000] + 16#309 [/hookcmb /hookabovecomb] + 16#944 [/rrvocalicvowelsigndeva] + 16#AD [/softhyphen /sfthyphen] + 16#1E51 [/omacrongrave] + 16#248C [/fiveperiod] + 16#AC7 [/evowelsigngujarati] + 16#260F [/whitetelephone] + 16#3B3 [/gamma] + 16#9EE [/eightbengali] + 16#157 [/rcommaaccent /rcedilla] + 16#3029 [/ninehangzhou] + 16#2792 [/ninecircleinversesansserif] + 16#FEFB [/lamalefisolatedarabic] + 16#536 [/Zaarmenian] + 16#FC9F [/behmeeminitialarabic] + 16#22DA [/lessequalorgreater] + 16#2DA [/ring] + 16#915 [/kadeva] + 16#207E [/parenrightsuperior] + 16#F7E7 [/Ccedillasmall] + 16#7E [/asciitilde] + 16#1E22 [/Hdotaccent] + 16#A98 [/ghagujarati] + 16#201 [/adblgrave] + 16#30D3 [/bikatakana] + 16#5E0 [/nunhebrew /nun /afii57680] + 16#384 [/tonos] + 16#9BF [/ivowelsignbengali] + 16#128 [/Itilde] + 16#F891 [/maitrilowrightthai] + 16#FECC [/ainmedialarabic] + 16#1ECC [/Odotbelow] + 16#317D [/siospieupkorean] + 16#4F [/O] + 16#F7B8 [/Cedillasmall] + 16#42E [/afii10048 /IUcyrillic] + 16#3300 [/apaatosquare] + 16#A69 [/threegurmukhi] + 16#1D2 [/ocaron] + 16#21D2 [/dblarrowright /arrowdblright] + 16#30A4 [/ikatakana] + 16#FF76 [/kakatakanahalfwidth] + 16#F6DF [/centinferior] + 16#E48 [/maiekthai] + 16#5B1 [/hatafsegolwidehebrew /hatafsegolquarterhebrew /hatafsegolnarrowhebrew /hatafsegolhebrew /hatafsegol30 /hatafsegol24 /hatafsegol17 /hatafsegol /afii57801] + 16#3227 [/eightideographicparen] + 16#990 [/aibengali] + 16#F9 [/ugrave] + 16#24D8 [/icircle] + 16#4D8 [/Schwacyrillic] + 16#33AA [/kpasquare] + 16#27C [/rlongleg] + 16#314E [/hieuhkorean] + 16#20 [/spacehackarabic /space] + 16#2020 [/dagger] + 16#FB68 [/ttehinitialarabic] + 16#1A3 [/oi] + 16#3075 [/huhiragana] + 16#FF47 [/gmonospace] + 16#E19 [/nonuthai] + 16#582 [/yiwnarmenian] + 16#2326 [/deleteright] + 16#961 [/llvocalicdeva] + 16#CA [/Ecircumflex] + 16#1E6E [/Tlinebelow] + 16#24A9 [/nparen] + 16#4A9 [/haabkhasiancyrillic] + 16#337B [/heiseierasquare] + 16#311F [/eibopomofo] + 16#62C [/jeemarabic /afii57420] + 16#3D0 [/betasymbolgreek] + 16#FB39 [/yoddageshhebrew /yoddagesh] + 16#2174 [/fiveroman] + 16#174 [/Wcircumflex] + 16#3046 [/uhiragana] + 16#FF18 [/eightmonospace] + 16#553 [/Piwrarmenian] + 16#2553 [/SF520000] + 16#932 [/ladeva] + 16#1E3F [/macute] + 16#FE3F [/anglebracketleftvertical] + 16#247A [/sevenparen] + 16#47A [/Omegaroundcyrillic] + 16#AB5 [/vagujarati] + 16#221E [/infinity] + 16#30F0 [/wikatakana] + 16#3A1 [/Rho] + 16#3273 [/pieupacirclekorean] + 16#9DC [/rrabengali] + 16#145 [/Ncommaaccent /Ncedilla] + 16#3017 [/whitelenticularbracketright] + 16#1EE9 [/uhornacute] + 16#2524 [/SF090000] + 16#FC8D [/noonnoonfinalarabic] + 16#2C8 [/verticallinemod] + 16#903 [/visargadeva] + 16#6C [/l] + 16#1E10 [/Dcedilla] + 16#44B [/yericyrillic /afii10093] + 16#A86 [/aagujarati] + 16#1EF [/ezhcaron] + 16#30C1 [/tikatakana] + 16#FF93 [/mokatakanahalfwidth] + 16#F6FC [/Ringsmall] + 16#25CE [/bullseye] + 16#9AD [/bhabengali] + 16#2116 [/numero /afii61352] + 16#116 [/Edotaccent /Edot] + 16#FEBA [/sadfinalarabic] + 16#1EBA [/Ehookabove] + 16#4F5 [/chedieresiscyrillic] + 16#FC5E [/shaddadammatanarabic] + 16#33C7 [/cosquare] + 16#2299 [/circleot] + 16#316B [/rieulpieupsioskorean] + 16#3D [/equal] + 16#41C [/afii10030 /Emcyrillic] + 16#21C0 [/harpoonrightbarbup] + 16#1C0 [/clickdental] + 16#3092 [/wohiragana] + 16#FF64 [/ideographiccommaleft] + 16#F6CD [/DieresisGrave] + 16#E36 [/sarauethai] + 16#59F [/qarneyparahebrew] + 16#343 [/koroniscmb] + 16#3215 [/ieungaparenkorean] + 16#E7 [/ccedilla] + 16#FE8B [/yehhamzaaboveinitialarabic] + 16#1E8B [/xdotaccent] + 16#24C6 [/Qcircle] + 16#3398 [/klsquare] + 16#226A [/muchless] + 16#313C [/rieulpieupkorean] + 16#E [/controlSO] + 16#200E [/afii299] + 16#F777 [/Wsmall] + 16#649 [/alefmaksuraarabic /afii57449] + 16#3ED [/shimacoptic] + 16#A28 [/nagurmukhi] + 16#191 [/Fhook] + 16#F8FA [/bracketrightex] + 16#3063 [/tusmallhiragana] + 16#2191 [/arrowup] + 16#FF35 [/Umonospace] + 16#E07 [/ngonguthai] + 16#570 [/hoarmenian] + 16#314 [/commareversedabovecmb] + 16#B8 [/cedilla] + 16#6F3 [/threepersian] + 16#FE5C [/bracerightsmall] + 16#1E5C [/Rdotbelowmacron] + 16#2497 [/sixteenperiod] + 16#497 [/zhedescendercyrillic] + 16#310D [/gbopomofo] + 16#3BE [/xi] + 16#3290 [/ideographsuncircle] + 16#9F9 [/sixteencurrencydenominatorbengali] + 16#162 [/Tcommaaccent /Tcedilla] + 16#2162 [/Threeroman] + 16#FF06 [/ampersandmonospace] + 16#541 [/Jaarmenian] + 16#2E5 [/tonebarextrahighmod] + 16#920 [/tthadeva] + 16#2089 [/nineinferior] + 16#F7F2 [/Ogravesmall] + 16#1E2D [/itildebelow] + 16#2468 [/ninecircle] + 16#468 [/Yuslittleiotifiedcyrillic] + 16#AA3 [/nnagujarati] + 16#220C [/notcontains] + 16#20C [/Odblgrave] + 16#30DE [/makatakana] + 16#38F [/Omegatonos] + 16#3261 [/nieuncirclekorean] + 16#133 [/ij] + 16#3005 [/ideographiciterationmark] + 16#FED7 [/qafinitialarabic] + 16#1ED7 [/ocircumflextilde] + 16#2B6 [/Rsmallinvertedsuperior] + 16#3188 [/yoyaekorean] + 16#5A [/Z] + 16#439 [/iishortcyrillic /afii10075] + 16#A74 [/ekonkargurmukhi] + 16#1DD [/eturned] + 16#30AF [/kukatakana] + 16#FF81 [/tikatakanahalfwidth] + 16#F6EA [/bsuperior] + 16#E53 [/threethai] + 16#25BC [/triagdn /blackdownpointingtriangle] + 16#5BC [/dageshhebrew /dagesh /afii57807] + 16#360 [/tildedoublecmb] + 16#3232 [/ideographichaveparen] + 16#99B [/chabengali] + 16#104 [/Aogonek] + 16#FEA8 [/khahmedialarabic] + 16#1EA8 [/Acircumflexhookabove] + 16#24E3 [/tcircle] + 16#4E3 [/imacroncyrillic] + 16#33B5 [/nvsquare] + 16#287 [/tturned] + 16#2287 [/supersetorequal /reflexsuperset] + 16#3159 [/waekorean] + 16#2B [/plus] + 16#666 [/sixhackarabic /sixarabic /afii57398] + 16#2666 [/diamond] + 16#40A [/afii10059 /Njecyrillic] + 16#1AE [/Tretroflexhook] + 16#3080 [/muhiragana] + 16#FF52 [/rmonospace] + 16#E24 [/ruthai] + 16#331 [/macronbelowcmb] + 16#3203 [/rieulparenkorean] + 16#96C [/sixdeva] + 16#D5 [/Otilde] + 16#1E79 [/utildeacute] + 16#24B4 [/yparen] + 16#4B4 [/Tetsecyrillic] + 16#3386 [/MBsquare] + 16#AEF [/ninegujarati] + 16#258 [/ereversed] + 16#F765 [/Esmall] + 16#637 [/taharabic /afii57431] + 16#FB44 [/pedageshhebrew /pedagesh] + 16#A16 [/khagurmukhi] + 16#17F [/slong /longs] + 16#F8E8 [/registersans] + 16#3051 [/kehiragana] + 16#FF23 [/Cmonospace] + 16#55E [/questionarmenian] + 16#255E [/SF360000] + 16#2302 [/house] + 16#302 [/circumflexcmb] + 16#93D [/avagrahadeva] + 16#A6 [/brokenbar] + 16#FE4A [/overlinecenterline] + 16#1E4A [/Ncircumflexbelow] + 16#485 [/dasiapneumatacyrilliccmb] + 16#2485 [/eighteenparen] + 16#3357 [/wattosquare] + 16#AC0 [/iivowelsigngujarati] + 16#2229 [/intersection] + 16#30FB [/dotkatakana] + 16#F736 [/sixoldstyle] + 16#3AC [/alphatonos] + 16#9E7 [/onebengali] + 16#150 [/Ohungarumlaut /Odblacute] + 16#3022 [/twohangzhou] + 16#278B [/twocircleinversesansserif] + 16#FEF4 [/yehmedialarabic /alefmaksuramedialarabic] + 16#1EF4 [/Ydotbelow] + 16#2D3 [/ringhalfleftcentered] + 16#90E [/eshortdeva] + 16#2077 [/sevensuperior] + 16#F7E0 [/Agravesmall] + 16#77 [/w] + 16#1E1B [/etildebelow] + 16#456 [/icyrillic /afii10103] + 16#A91 [/ocandragujarati] + 16#1FA [/Aringacute] + 16#30CC [/nukatakana] + 16#FF9E [/voicedmarkkanahalfwidth] + 16#5D9 [/yodhebrew /yod /afii57673] + 16#25D9 [/whitecircleinverse /invcircle] + 16#9B8 [/sabengali] + 16#2121 [/telephone] + 16#F88A [/maiekupperleftthai] + 16#121 [/gdotaccent /gdot] + 16#1EC5 [/ecircumflextilde] + 16#2500 [/SF100000] + 16#33D2 [/squarelog] + 16#22A4 [/tackdown] + 16#2A4 [/dezh] + 16#3176 [/pieupcieuckorean] + 16#48 [/H] + 16#427 [/afii10041 /Checyrillic] + 16#1CB [/Nj] + 16#309D [/iterationhiragana] + 16#FF6F [/tusmallkatakanahalfwidth] + 16#F6D8 [/dieresisgrave] + 16#E41 [/saraaethai] + 16#5AA [/yerahbenyomolefthebrew /yerahbenyomohebrew] + 16#25AA [/blacksmallsquare /H18543] + 16#3220 [/oneideographicparen] + 16#989 [/ubengali] + 16#F2 [/ograve] + 16#FE96 [/tehfinalarabic] + 16#1E96 [/hlinebelow] + 16#4D1 [/abrevecyrillic] + 16#24D1 [/bcircle] + 16#33A3 [/mmcubedsquare] + 16#275 [/obarred] + 16#3147 [/ieungkorean] + 16#19 [/controlEM] + 16#2019 [/quoteright] + 16#19C [/Mturned] + 16#306E [/nohiragana] + 16#FF40 [/gravemonospace] + 16#E12 [/thophuthaothai] + 16#57B [/jheharmenian] + 16#31F [/plusbelowcmb] + 16#95A [/ghhadeva] + 16#C3 [/Atilde] + 16#1E67 [/scarondotaccent] + 16#24A2 [/gparen] + 16#FC0B [/tehjeemisolatedarabic] + 16#4A2 [/Endescendercyrillic] + 16#3118 [/cbopomofo] + 16#625 [/afii57413 /alefhamzabelowarabic] + 16#3C9 [/omega] + 16#FB32 [/gimeldagesh /gimeldageshhebrew] + 16#16D [/ubreve] + 16#FF11 [/onemonospace] + 16#54C [/Raarmenian] + 16#92B [/phadeva] + 16#F7FD [/Yacutesmall] + 16#FE38 [/bracerightvertical] + 16#1E38 [/Ldotbelowmacron] + 16#2473 [/twentycircle] + 16#473 [/fitacyrillic /afii10195] + 16#AAE [/magujarati] + 16#217 [/uinvertedbreve] + 16#2217 [/asteriskmath] + 16#30E9 [/rakatakana] + 16#F724 [/dollaroldstyle] + 16#39A [/Kappa] + 16#FB03 [/ffi] + 16#326C [/phieuphcirclekorean] + 16#13E [/lcaron] + 16#3010 [/blacklenticularbracketleft] + 16#FEE2 [/meemfinalarabic] + 16#1EE2 [/Ohorndotbelow] + 16#2C1 [/glottalstopreversedmod] + 16#65 [/e] + 16#1E09 [/ccedillaacute] + 16#444 [/efcyrillic /afii10086] + 16#3316 [/kiromeetorusquare] + 16#21E8 [/arrowrightwhite] + 16#1E8 [/Kcaron] + 16#30BA [/zukatakana] + 16#FF8C [/hukatakanahalfwidth] + 16#F6F5 [/Caronsmall] + 16#25C7 [/whitediamond] + 16#323D [/ideographicenterpriseparen] + 16#9A6 [/dabengali] + 16#10F [/dcaron] + 16#FEB3 [/seeninitialarabic] + 16#1EB3 [/abrevehookabove] + 16#4EE [/Umacroncyrillic] + 16#33C0 [/kohmsquare] + 16#292 [/ezh] + 16#3164 [/hangulfiller] + 16#36 [/six] + 16#415 [/afii10022 /Iecyrillic] + 16#1B9 [/ezhreversed] + 16#308B [/ruhiragana] + 16#FF5D [/bracerightmonospace] + 16#F6C6 [/afii10192] + 16#E2F [/paiyannoithai] + 16#598 [/zarqahebrew] + 16#33C [/seagullbelowcmb] + 16#320E [/kiyeokaparenkorean] + 16#E0 [/agrave] + 16#FE84 [/alefhamzaabovefinalarabic] + 16#1E84 [/Wdieresis] + 16#4BF [/chedescenderabkhasiancyrillic] + 16#24BF [/Jcircle] + 16#3391 [/khzsquare] + 16#263 [/gammalatinsmall] + 16#3135 [/nieuncieuckorean] + 16#7 [/controlBEL] + 16#F770 [/Psmall] + 16#642 [/qafarabic /afii57442] + 16#2642 [/mars /male] + 16#3E6 [/Kheicoptic] + 16#FB4F [/aleflamedhebrew] + 16#A21 [/ddagurmukhi] + 16#18A [/Dhook] + 16#F8F3 [/braceleftbt] + 16#305C [/zehiragana] + 16#FF2E [/Nmonospace] + 16#569 [/toarmenian] + 16#FCD2 [/noonjeeminitialarabic] + 16#2569 [/SF400000] + 16#30D [/verticallineabovecmb] + 16#948 [/aivowelsigndeva] + 16#B1 [/plusminus] + 16#1E55 [/pacute] + 16#FE55 [/colonsmall] + 16#2490 [/nineperiod] + 16#490 [/afii10050 /Gheupturncyrillic] + 16#ACB [/ovowelsigngujarati] + 16#2234 [/therefore] + 16#3106 [/pbopomofo] + 16#3B7 [/eta] + 16#FB20 [/ayinaltonehebrew] + 16#9F2 [/rupeemarkbengali] + 16#15B [/sacute] + 16#215B [/oneeighth] + 16#FEFF [/zerowidthjoiner] + 16#53A [/Zhearmenian] + 16#2DE [/rhotichookmod] + 16#919 [/ngadeva] + 16#2082 [/twoinferior] + 16#F7EB [/Edieresissmall] + 16#1E26 [/Hdieresis] + 16#2461 [/twocircle] + 16#461 [/omegacyrillic] + 16#3333 [/huiitosquare] + 16#A9C [/jagujarati] + 16#205 [/edblgrave] + 16#2205 [/emptyset] + 16#30D7 [/pukatakana] + 16#5E4 [/pe /pehebrew /afii57684] + 16#25E4 [/blackupperlefttriangle] + 16#388 [/Epsilontonos] + 16#9C3 [/rvocalicvowelsignbengali] + 16#12C [/Ibreve] + 16#F895 [/maichattawalowleftthai] + 16#FED0 [/ghainmedialarabic] + 16#1ED0 [/Ocircumflexacute] + 16#33DD [/wbsquare] + 16#3181 [/yesieungkorean] + 16#53 [/S] + 16#432 [/vecyrillic /afii10067] + 16#A6D [/sevengurmukhi] + 16#1D6 [/udieresismacron] + 16#30A8 [/ekatakana] + 16#FF7A [/kokatakanahalfwidth] + 16#F6E3 [/dollarinferior] + 16#E4C [/thanthakhatthai] + 16#5B5 [/tsere /tserewidehebrew /tserequarterhebrew /tserenarrowhebrew /tserehebrew /tsere2b /tsere1e /tsere12 /afii57794] + 16#25B5 [/whiteuppointingsmalltriangle] + 16#322B [/ideographicfireparen] + 16#994 [/aubengali] + 16#FD [/yacute] + 16#1EA1 [/adotbelow] + 16#24DC [/mcircle] + 16#4DC [/Zhedieresiscyrillic] + 16#33AE [/radoverssquare] + 16#2280 [/notprecedes] + 16#3152 [/yaekorean] + 16#2024 [/onedotenleader] + 16#24 [/dollar] + 16#403 [/afii10052 /Gjecyrillic] + 16#FB6C [/vehinitialarabic] + 16#A3E [/aamatragurmukhi] + 16#1A7 [/Tonetwo] + 16#3079 [/behiragana] + 16#FF4B [/kmonospace] + 16#E1D [/fofathai] + 16#586 [/feharmenian] + 16#32A [/bridgebelowcmb] + 16#232A [/angleright] + 16#965 [/dbldanda] + 16#CE [/Icircumflex] + 16#1E72 [/Udieresisbelow] + 16#4AD [/tedescendercyrillic] + 16#24AD [/rparen] + 16#337F [/corporationsquare] + 16#AE8 [/twogujarati] + 16#2251 [/geometricallyequal] + 16#251 [/ascript] + 16#3123 [/enbopomofo] + 16#630 [/thalarabic /afii57424] + 16#3D4 [/Upsilondieresishooksymbolgreek] + 16#32A6 [/ideographiclowcircle] + 16#A0F [/eegurmukhi] + 16#2178 [/nineroman] + 16#178 [/Ydieresis] + 16#304A [/ohiragana] + 16#FF1C [/lessmonospace] + 16#2557 [/SF250000] + 16#936 [/shadeva] + 16#FE43 [/whitecornerbracketleftvertical] + 16#1E43 [/mdotbelow] + 16#247E [/elevenparen] + 16#47E [/Otcyrillic] + 16#AB9 [/hagujarati] + 16#30F4 [/vukatakana] + 16#3A5 [/Upsilon] + 16#3277 [/chieuchacirclekorean] + 16#9E0 [/rrvocalicbengali] + 16#149 [/quoterightn /napostrophe] + 16#1EED [/uhornhookabove] + 16#2CC [/verticallinelowmod] + 16#907 [/ideva] + 16#2070 [/zerosuperior] + 16#70 [/p] + 16#1E14 [/Emacrongrave] + 16#44F [/iacyrillic /afii10097] + 16#A8A [/uugujarati] + 16#1F3 [/dz] + 16#30C5 [/dukatakana] + 16#FF97 [/rakatakanahalfwidth] + 16#5D2 [/gimel /gimelhebrew /afii57666] + 16#11A [/Ecaron] + 16#FEBE [/dadfinalarabic] + 16#1EBE [/Ecircumflexacute] + 16#4F9 [/yerudieresiscyrillic] + 16#FC62 [/shaddakasraarabic] + 16#33CB [/HPsquare] + 16#29D [/jcrossedtail] + 16#316F [/mieumsioskorean] + 16#41 [/A] + 16#420 [/afii10034 /Ercyrillic] + 16#FB89 [/ddalfinalarabic] + 16#A5B [/zagurmukhi] + 16#21C4 [/arrowrightoverleft] + 16#1C4 [/DZcaron] + 16#FF68 [/ismallkatakanahalfwidth] + 16#F6D1 [/cyrBreve] + 16#E3A [/phinthuthai] + 16#25A3 [/squarewhitewithsmallblack] + 16#5A3 [/munahlefthebrew /munahhebrew] + 16#3219 [/thieuthaparenkorean] + 16#982 [/anusvarabengali] + 16#EB [/edieresis] + 16#1E8F [/ydotaccent] + 16#24CA [/Ucircle] + 16#339C [/squaremm] + 16#226E [/notless] + 16#26E [/lezh] + 16#3140 [/rieulhieuhkorean] + 16#2012 [/figuredash] + 16#12 [/controlDC2] + 16#64D [/kasratanarabic /afii57453] + 16#3F1 [/rhosymbolgreek] + 16#A2C [/bagurmukhi] + 16#195 [/hv] + 16#2195 [/arrowupdn] + 16#3067 [/dehiragana] + 16#F8FE [/bracerightbt] + 16#FF39 [/Ymonospace] + 16#E0B [/sosothai] + 16#574 [/menarmenian] + 16#FCDD [/yehmeeminitialarabic] + 16#2318 [/propellor] + 16#318 [/lefttackbelowcmb] + 16#953 [/gravedeva] + 16#BC [/onequarter] + 16#6F7 [/sevenpersian] + 16#1E60 [/Sdotaccent] + 16#249B [/twentyperiod] + 16#49B [/kadescendercyrillic] + 16#3111 [/qbopomofo] + 16#FFE3 [/macronmonospace] + 16#261E [/pointingindexrightwhite] + 16#3C2 [/sigmafinal /sigma1] + 16#FB2B [/shinsindothebrew /shinsindot /afii57695] + 16#3294 [/ideographnamecircle] + 16#166 [/Tbar] + 16#2166 [/Sevenroman] + 16#FF0A [/asteriskmonospace] + 16#545 [/Yiarmenian] + 16#2E9 [/tonebarextralowmod] + 16#924 [/tadeva] + 16#208D [/parenleftinferior] + 16#F7F6 [/Odieresissmall] + 16#1E31 [/kacute] + 16#FE31 [/emdashvertical] + 16#246C [/thirteencircle] + 16#46C [/Yusbigiotifiedcyrillic] + 16#AA7 [/dhagujarati] + 16#210 [/Rdblgrave] + 16#30E2 [/mokatakana] + 16#25EF [/largecircle] + 16#393 [/Gamma] + 16#3265 [/pieupcirclekorean] + 16#137 [/kcommaaccent /kcedilla] + 16#3009 [/anglebracketright] + 16#1EDB [/ohornacute] + 16#FEDB [/kafinitialarabic] + 16#2BA [/dblprimemod] + 16#318C [/yuikorean] + 16#5E [/asciicircum] + 16#1E02 [/Bdotaccent] + 16#43D [/encyrillic /afii10079] + 16#1E1 [/adotmacron] + 16#21E1 [/arrowdashup] + 16#30B3 [/kokatakana] + 16#FF85 [/nakatakanahalfwidth] + 16#F6EE [/lsuperior] + 16#E57 [/seventhai] + 16#5C0 [/paseqhebrew /afii57842] + 16#25C0 [/blackleftpointingtriangle] + 16#3236 [/ideographicfinancialparen] + 16#99F [/ttabengali] + 16#108 [/Ccircumflex] + 16#FEAC [/thalfinalarabic] + 16#1EAC [/Acircumflexdotbelow] + 16#24E7 [/xcircle] + 16#4E7 [/odieresiscyrillic] + 16#33B9 [/mvmegasquare] + 16#228B [/supersetnotequal] + 16#28B [/vhook] + 16#315D [/weokorean] + 16#2F [/slash] + 16#66A [/percentarabic /afii57381] + 16#266A [/musicalnote] + 16#40E [/afii10062 /Ushortcyrillic] + 16#1B2 [/Vhook] + 16#3084 [/yahiragana] + 16#FF56 [/vmonospace] + 16#F6BF [/LL] + 16#E28 [/sosalathai] + 16#2591 [/shadelight /ltshade] + 16#591 [/etnahtalefthebrew /etnahtahebrew /etnahtafoukhlefthebrew /etnahtafoukhhebrew] + 16#335 [/strokeshortoverlaycmb] + 16#3207 [/ieungparenkorean] + 16#970 [/abbreviationsigndeva] + 16#D9 [/Ugrave] + 16#1E7D [/vtilde] + 16#24B8 [/Ccircle] + 16#4B8 [/Cheverticalstrokecyrillic] + 16#338A [/pfsquare] + 16#25C [/eopenreversed] +.dicttomark readonly def diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_btokn.ps b/Master/tlpkg/tlgs/Resource/Init/gs_btokn.ps new file mode 100644 index 00000000000..a2f08b748b2 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_btokn.ps @@ -0,0 +1,330 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Initialization file for binary tokens. +% When this is run, systemdict is still writable, +% but everything defined here goes into level2dict. + +% Define whether or not to allow writing dictionaries. +% This is a non-standard feature! +/WRITEDICTS //false def + +languagelevel 1 .setlanguagelevel +level2dict begin + +% Initialization for the system name table. + +mark +% 0 + /abs /add /aload /anchorsearch /and + /arc /arcn /arct /arcto /array + /ashow /astore /awidthshow /begin /bind + /bitshift /ceiling /charpath /clear /cleartomark +% 20 + /clip /clippath /closepath /concat /concatmatrix + /copy /count /counttomark /currentcmykcolor /currentdash + /currentdict /currentfile /currentfont /currentgray /currentgstate + /currenthsbcolor /currentlinecap /currentlinejoin /currentlinewidth /currentmatrix +% 40 + /currentpoint /currentrgbcolor /currentshared /curveto /cvi + /cvlit /cvn /cvr /cvrs /cvs + /cvx /def /defineusername /dict /div + /dtransform /dup /end /eoclip /eofill +% 60 + /eoviewclip /eq /exch /exec /exit + /file /fill /findfont /flattenpath /floor + /flush /flushfile /for /forall /ge + /get /getinterval /grestore /gsave /gstate +% 80 + /gt /identmatrix /idiv /idtransform /if + /ifelse /image /imagemask /index /ineofill + /infill /initviewclip /inueofill /inufill /invertmatrix + /itransform /known /le /length /lineto +% 100 + /load /loop /lt /makefont /matrix + /maxlength /mod /moveto /mul /ne + /neg /newpath /not /null /or + /pathbbox /pathforall /pop /print /printobject +% 120 + /put /putinterval /rcurveto /read /readhexstring + /readline /readstring /rectclip /rectfill /rectstroke + /rectviewclip /repeat /restore /rlineto /rmoveto + /roll /rotate /round /save /scale +% 140 + /scalefont /search /selectfont /setbbox /setcachedevice + /setcachedevice2 /setcharwidth /setcmykcolor /setdash /setfont + /setgray /setgstate /sethsbcolor /setlinecap /setlinejoin + /setlinewidth /setmatrix /setrgbcolor /setshared /shareddict +% 160 + /show /showpage /stop /stopped /store + /string /stringwidth /stroke /strokepath /sub + /systemdict /token /transform /translate /truncate + /type /uappend /ucache /ueofill /ufill +% 180 + /undef /upath /userdict /ustroke /viewclip + /viewclippath /where /widthshow /write /writehexstring + /writeobject /writestring /wtranslation /xor /xshow + /xyshow /yshow /FontDirectory /SharedFontDirectory /Courier +% 200 + /Courier-Bold /Courier-BoldOblique /Courier-Oblique /Helvetica /Helvetica-Bold + /Helvetica-BoldOblique /Helvetica-Oblique /Symbol /Times-Bold /Times-BoldItalic + /Times-Italic /Times-Roman /execuserobject /currentcolor /currentcolorspace + /currentglobal /execform /filter /findresource /globaldict +% 220 + /makepattern /setcolor /setcolorspace /setglobal /setpagedevice + /setpattern +% pad to 256 + counttomark 256 exch sub { 0 } repeat +% 256 + /= /== /ISOLatin1Encoding /StandardEncoding +% 260 + ([) cvn (]) cvn /atan /banddevice /bytesavailable + /cachestatus /closefile /colorimage /condition /copypage + /cos /countdictstack /countexecstack /cshow /currentblackgeneration + /currentcacheparams /currentcolorscreen /currentcolortransfer /currentcontext /currentflat +% 280 + /currenthalftone /currenthalftonephase /currentmiterlimit /currentobjectformat /currentpacking + /currentscreen /currentstrokeadjust /currenttransfer /currentundercolorremoval /defaultmatrix + /definefont /deletefile /detach /deviceinfo /dictstack + /echo /erasepage /errordict /execstack /executeonly +% 300 + /exp /false /filenameforall /fileposition /fork + /framedevice /grestoreall /handleerror /initclip /initgraphics + /initmatrix /instroke /inustroke /join /kshow + /ln /lock /log /mark /monitor +% 320 + /noaccess /notify /nulldevice /packedarray /quit + /rand /rcheck /readonly /realtime /renamefile + /renderbands /resetfile /reversepath /rootfont /rrand + /run /scheck /setblackgeneration /setcachelimit /setcacheparams +% 340 + /setcolorscreen /setcolortransfer /setfileposition /setflat /sethalftone + /sethalftonephase /setmiterlimit /setobjectformat /setpacking /setscreen + /setstrokeadjust /settransfer /setucacheparams /setundercolorremoval /sin + /sqrt /srand /stack /status /statusdict +% 360 + /true /ucachestatus /undefinefont /usertime /ustrokepath + /version /vmreclaim /vmstatus /wait /wcheck + /xcheck /yield /defineuserobject /undefineuserobject /UserObjects + /cleardictstack +% 376 + /A /B /C /D /E /F /G /H /I /J /K /L /M + /N /O /P /Q /R /S /T /U /V /W /X /Y /Z + /a /b /c /d /e /f /g /h /i /j /k /l /m + /n /o /p /q /r /s /t /u /v /w /x /y /z +% 428 + /setvmthreshold (<<) cvn + (>>) cvn /currentcolorrendering /currentdevparams /currentoverprint /currentpagedevice + /currentsystemparams /currentuserparams /defineresource /findencoding /gcheck +% 440 + /glyphshow /languagelevel /product /pstack /resourceforall + /resourcestatus /revision /serialnumber /setcolorrendering /setdevparams + /setoverprint /setsystemparams /setuserparams /startjob /undefineresource + /GlobalFontDirectory /ASCII85Decode /ASCII85Encode /ASCIIHexDecode /ASCIIHexEncode +% 460 + /CCITTFaxDecode /CCITTFaxEncode /DCTDecode /DCTEncode /LZWDecode + /LZWEncode /NullEncode /RunLengthDecode /RunLengthEncode /SubFileDecode + /CIEBasedA /CIEBasedABC /DeviceCMYK /DeviceGray /DeviceRGB + /Indexed /Pattern /Separation /CIEBasedDEF /CIEBasedDEFG +% 480 + /DeviceN +% 481 -- end +.packtomark .installsystemnames + +% Define printobject and writeobject. +% These are mostly implemented in PostScript, so that we don't have to +% worry about interrupts or callbacks when writing to the output file. + +% Define procedures for accumulating the space required to represent +% an object in binary form. The procedures for composite objects (arrays +% and dictionaries) leave different results on the stack: +% <#refs> <#chars> <simple_obj> -proc- <#refs> <#chars> +% <#refs> <#chars> <array|dict> -proc- <array|dict> <#refs> <#chars> +% This is required so that .writeobjects can also accumulate the actual +% list of composite objects to write in the binary object sequence. +/cntdict mark + /integertype /pop load + /realtype 1 index + /marktype 1 index + /nulltype 1 index + /booleantype 1 index + /nametype { length add } bind + /stringtype 1 index + /arraytype //null + /dicttype //null +.dicttomark def +/.cntobj { % <<arguments and results as for procedures in cntdict>> + dup type //cntdict exch get exec +} .bind def +cntdict /arraytype { + dup dup length 5 -1 roll add 4 2 roll { .cntobj } forall +} bind put +cntdict /dicttype { + WRITEDICTS { + dup dup length 2 mul 5 -1 roll add 4 2 roll { + % We have to use .execn here, rather than simply rolling the + % value under the top elements, because key might involve arrays + % or dictionaries. + cvlit {.cntobj} exch 2 .execn .cntobj + } forall + } { + /writeobject .systemvar /typecheck signalerror + } ifelse +} bind put + +/w2dict mark + /nametype { 2 copy .writecvs pop } bind + /stringtype 1 index +.dicttomark def + +/.bosheader { % <top_length> <total_length> <string8> .bosheader + % <string4|8> + dup 0 currentobjectformat 127 add put % object format => BOS tag + 2 index 255 le 2 index 65531 le and { + % Use the short header format: tag toplen(1) totlen(2) + exch 4 add exch + 0 4 getinterval + dup 1 5 -1 roll put + } { + % Use the long header format: tag 0(1) toplen(2) totlen(4) + exch 8 add exch + 0 0 4 2 roll .bosobject exch pop exch pop % store with byte swapping + } ifelse % Stack: shortlen str + exch dup -8 bitshift exch 255 and % str hibyte lobyte + currentobjectformat 1 and 0 eq { % lsb first + exch + } if + 2 index 3 3 -1 roll put + 1 index 2 3 -1 roll put +} .bind def + +/.writeobjects { % <file> <tag> <array> .writeobjects - + mark exch + + % Count the space required for refs and strings. + + dup length 0 3 -1 roll + % Stack: file tag -mark- #refs #chars array + dup 4 1 roll { .cntobj } forall + + % Write the header. + + % Stack: file tag -mark- array1 ... (array|dict)N #refs #chars + counttomark 3 add -2 roll 4 1 roll + % Stack: -mark- array1 ... (array|dict)N tag #refs #chars file + dup counttomark 1 sub index length + 4 index 3 bitshift 4 index add + (xxxxxxxx) .bosheader writestring + + % Write the objects per se. + + 3 1 roll pop + counttomark 1 sub index length 3 bitshift exch + 3 bitshift + % Stack: -mark- array1 ... (array|dict)N tag file ref# char# + counttomark 4 sub { + counttomark -1 roll dup 6 1 roll + % Stack: ... objN tag file ref# char# objN + dup type /dicttype eq { % can't be first object + { 5 1 roll (x\000xxxxxx) .bosobject + 3 index exch writestring + 4 -1 roll (x\000xxxxxx) .bosobject + 3 index exch writestring + } forall + } { + { (x\000xxxxxx) .bosobject + dup 1 6 index put + 3 index exch writestring + 4 -1 roll pop 0 4 1 roll % clear tag + } forall + } ifelse + } repeat + + % Write the strings and names. + + pop pop exch pop + % Stack: -mark- array1 ... array|dictN file + counttomark 1 sub { + counttomark -1 roll { + % The counting pass ensured that the keys and values + % of any dictionary must be writable objects. + % Hence, we are processing a dictionary iff + % the next-to-top stack element is not a file. + 1 index type /filetype ne { + exch 2 index exch dup type //w2dict exch .knownget + { exec } { pop } ifelse pop + } if + dup type //w2dict exch .knownget { exec } { pop } ifelse + } forall + } repeat + + % Clean up. + + % Stack: -mark- file + pop pop + +} .bind def + +/printobject { % <obj> <tag> printobject - + currentobjectformat 0 eq { + /printobject .systemvar /undefined signalerror + } if + (%stdout) (w) file 2 index 2 index .writeobject pop pop +} odef +/writeobject { % <file> <obj> <tag> writeobject - + currentobjectformat 0 eq { + /writeobject .systemvar /undefined signalerror + } if + 2 .argindex pop % check # of args + .writeobject +} odef +/.writeobject { + 3 copy exch + % We must allocate the array in local VM + % to avoid a possible invalidaccess. + .currentglobal //false .setglobal exch 1 array astore exch .setglobal + .writeobjects pop pop pop +} .bind def + +% Implement binary error message output. +/.objectprinttest { % <obj> .objectprinttest - + % This is a pseudo-operator so it will restore the stack + % if it gets an error. + mark 0 0 3 .argindex .cntobj cleartomark pop +} bind odef +/.printerror { + $error /binary get .languagelevel 2 ge and { + currentobjectformat 0 ne { + [ /Error $error /errorname get $error /command get + % Convert the object with cvs if it isn't printable. + dup { .objectprinttest } .internalstopped { + pop 100 string cvs + } if + //false ] 250 printobject + } + //.printerror % known to be a procedure + ifelse + } + //.printerror % known to be a procedure + ifelse +} bind def + +currentdict /cntdict .undef +currentdict /w2dict .undef + +% End of level2dict + +end +.setlanguagelevel diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_cet.ps b/Master/tlpkg/tlgs/Resource/Init/gs_cet.ps new file mode 100644 index 00000000000..8eb79bb06e0 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_cet.ps @@ -0,0 +1,111 @@ +%!PS +% Set defaults for Ghostscript to match Adobe CPSI behaviour for CET + +% do this in the server level so it is persistent across jobs +//true 0 startjob not { + (*** Warning: CET startup is not in server default) = flush +} if + +300 .sethiresscreen % needed for language switch build since it + % processes gs_init.ps BEFORE setting the resolution + +0 array 0 setdash % CET 09-08 wants local setdash + +currentglobal //true setglobal + +{ + systemdict dup dup dup + /version (3017.102) readonly put % match CPSI 3017.102 + /product (PhotoPRINT SE 5.0v2) readonly put % match CPSI 3017.102 + /revision 0 put % match CPSI 3017.103 Tek shows revision 5 + /serialnumber dup {233640} readonly .makeoperator put % match CPSI 3017.102 Tek shows serialnumber 1401788461 + systemdict /deviceinfo undef % for CET 20-23-1 +% /UNROLLFORMS true put % CET files do unreasonable things inside forms +} superexec + +/UNROLLFORMS true def + +{ } bind dup +setblackgeneration +setundercolorremoval +0 array cvx readonly dup dup dup setcolortransfer + +% CPSI doesn't define "Localization" resource. +/Localization /Category undefineresource + +% Quality Logic test 09-59.ps tries to set each listed /OutputDevice. +% This can cause problems with some devices (eg mswinpr2 on Windows) +% so for the CET files we define the OutputDevice resource as +% being empty. We need to redefine /.definecategory as that definition +% gets destroyed at the end of gs_res.ps +/OutputDevice /Category undefineresource + +/.definecategory % <name> -mark- <key1> ... <valuen> .definecategory - + { counttomark 2 idiv 2 add % .Instances, Category + /Generic /Category findresource dup maxlength 3 -1 roll add + dict .copydict begin + counttomark 2 idiv { def } repeat pop % pop the mark + currentdict end /Category defineresource pop + } bind def + +/OutputDevice mark /InstanceType /dicttype .definecategory + +% Redefine Font category to return -1 (unknown) VM usage +% in all cases to avoid differences between hosts. +/Font /Category findresource +dup length dict copy +dup +dup /.loadfontresource get +dup length array copy cvx +dup 1 0 put +dup 7 -1 put +/.loadfontresource exch put +/Font exch /Category defineresource pop + +% Some previously compile time options such as USE_ADOBE_CMYK_RGB +% and GS_CHAR_FILL are now dynamic. Force CPSI compatibility. +//true .setCPSImode + +setglobal + +% Remove all but 'letter' page size +<< +currentpagedevice /InputAttributes get +1 1 2 index length 1 sub { + 1 index exch undef +} for +/InputAttributes exch +>> +setpagedevice + +% Patch setsmoothness, currentsmoothness for a better view of shadings : +userdict /.smoothness currentsmoothness put +/setsmoothness { + dup type dup /integertype eq exch /realtype eq or { + userdict /.smoothness 3 2 roll cvr put + } { + /setsmoothness .systemvar /typecheck signalerror + } ifelse +} bind odef +/currentsmoothness { userdict /.smoothness get } bind odef % for 09-55.PS, 09-57.PS . + +% slightly nasty hack to give consistent cluster results +/ofnfa systemdict /filenameforall get def + +/filenameforall +{ + 2 index dup length 1 eq + { + (*) eq + { + 3 -1 roll pop ( ) 3 1 roll + } if + } + { + pop + } ifelse + ofnfa +} bind def +% end of slightly nasty hack to give consistent cluster results + +//false 0 startjob pop % re-enter encapsulated mode diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_cff.ps b/Master/tlpkg/tlgs/Resource/Init/gs_cff.ps new file mode 100644 index 00000000000..c5e72602a45 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_cff.ps @@ -0,0 +1,250 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Loader for CFF (compressed) fonts, including OpenType CFFs. +% The following are not implemented yet: +% Deleted entries in the Name Index +% Embedded PostScript +% Multiple Master fonts +% Chameleon fonts +% Synthetic fonts + +% ---------------- Font loading machinery ---------------- % + +% Augment the FONTPATH machinery so it recognizes OpenType CFF font sets. + +/.scanfontheaders where { + pop /.scanfontheaders [ + .scanfontheaders aload pop (OTTO*) + ] def +} if + +% Load a font file that might be an OpenType CFF font set. + +% <file> .loadfontfile - +/.loadnonottofontfile /.loadfontfile load def +/.loadfontfile { + dup (12345678) .peekstring pop (wOFFOTTO) eq + { + .init_wOFF_otto_font_file + //true //false + }{//true} ifelse + + { + dup 4 string .peekstring pop (OTTO) eq + { + % If this is a font at all, it's an OpenType CFF font set. + .init_otto_font_file //true + } + { //false } ifelse + } if + + { % Use a random FontSet resource name. ****** WRONG ****** + realtime rand xor =string cvs exch //false //false + ReadData pop + } { + % Not a TrueType font. + .loadnonottofontfile + } ifelse +} bind def + +% <file> .init_otto_font_file <file> +/.init_otto_font_file { + /FontSetInit /ProcSet findresource begin + 2 dict begin + /f exch def /cff //null def + card32 pop card16 6 { next pop } repeat dup { + % Stack: numtables tablesleft + dup 0 eq { + pop pop /.loadottofontfile cvx /invalidfont signalerror + } if + f 4 string readstring pop (CFF ) eq { sub exit } if + f 12 string readstring pop pop 1 sub % skip to next table + } loop + % Stack: tablesread + card32 pop card32 card32 + % Stack: tablesread start length + exch 3 -1 roll 1 add 16 mul 12 add sub + f exch subfilefilter flushfile % skip to start + f exch subfilefilter end +} bind def + +% <file> .init_otto_font_file <file> +/.init_wOFF_otto_font_file { + /FontSetInit /ProcSet findresource begin + 2 dict begin + /f exch def /cff //null def + 3 {card32 pop} repeat % (wOFF), (OTTO) and file length + + card16 + 30 { next pop } repeat + dup + { + % Stack: numtables tablesleft + dup 0 eq { + pop pop /.loadottofontfile cvx /invalidfont signalerror + } if + f 4 string readstring pop (CFF ) eq { sub exit } if + f 12 string readstring pop pop 1 sub % skip to next table + } loop + % Stack: tablesread + 4 { card32 } repeat + % Stack: tablesread start complen len checksum + pop + % Stack: tablesread start complen len + 4 -2 roll exch + % Stack: complen len start tablesread + 1 add 20 mul 44 add sub + % Stack: complen len offset + f exch subfilefilter flushfile % skip to start + % Stack: complen len + % the table can legally be uncompressed: complen == len + 1 index 1 index eq + { exch pop f exch subfilefilter} + { pop f exch subfilefilter /FlateDecode filter} ifelse + end +} bind def +20 dict begin + +% ------ Utilities ------ % + +/subfilefilter { % <file> <length> subfilefilter <filter> + % SubFileDecode interprets a length of 0 as infinite. + dup 0 le { pop pop () 0 } if () /SubFileDecode filter +} bind def + + +/advance { % <n> advance - + f cff eq { pos add /pos exch store } { pop } ifelse +} bind def +/next { % - next <byte> + f read { + 1 advance + CFFDEBUG { ( ) print dup = } if + } { + 0 + CFFDEBUG { ( Out of range access, assuming 0) = } if + /pdfformaterror where { + pop + ( **** Warning: Out of range access to a CFF table, assuming 0.\n) + pdfformaterror + } if + } ifelse +} bind def +/next2 { % - next2 <byte1> <byte2> + f read { + f read { + 2 advance + CFFDEBUG { ( ) print 1 index =only (,) print dup = } if + } { + 1 advance + CFFDEBUG { ( ) print dup = } if + } ifelse + } if +} bind def +/nextstring { % <length> nextstring <string> + dup 0 eq { + pop () + } { + string f exch readstring pop dup length advance + CFFDEBUG { ( ) print dup //== exec } if + } ifelse +} bind def + +/card8 % - card8 <card8> + /next load +def +/card16 { % - card16 <card16> + next2 exch 8 bitshift add +} bind def +/card32 { % - card32 <card32> + card16 16 bitshift card16 add +} bind def +/offsetprocs [ + /card8 load + /card16 load + { card8 16 bitshift card16 add } bind + /card32 load +] readonly def +/offsetproc { % <offsize> offsetproc <proc> + 1 sub //offsetprocs exch get +} bind def +/offset { % <offsize> offset <offset> + offsetproc exec +} bind def +/sid % - <sid> sid + /card16 load +def + +% ------ Main program ------ % + +% We need to pass the file as a parameter for the sake of the PDF +% interpreter. Also for the sake of PDF, a flag forces the font +% to be defined as <resname> instead of the name embedded in the data. +% This is needed for subsetted fonts; it is valid if the CFF +% contains only a single font. +% Finally, PDF interpreter may request creation of CIDFont out of an +% ordinary CFF font. +/StartData { % <resname> <nbytes> StartData - + currentfile exch subfilefilter //false //false ReadData pop +} bind def +/ReadData { % <resname> <file> <forceresname> <forcecid> ReadData <fontset> + % Initialize. + + 30 dict begin + /forcecidfont exch def + /forceresname exch def + /cff exch def + /pos 0 def + /resname exch cvlit def + /DEBUG CFFDEBUG def % bring the binding closer + /StringCache 1 dict def % Private DICT may be reused. + + forcecidfont + [ { cff 1024 string readstring not { exit } if } loop ] + .parsecff /fonts exch def + + resname + mark fonts { + forceresname { exch pop resname exch } if + dup /CIDFontType known { % This is a CIDFont. + dup /CIDFontName 3 index put + 1 index exch /CIDFont defineresource + } { % This is a font. + dup /FontName 3 index put + dup /FontType 2 put + 1 index exch + definefont + } ifelse + } forall .dicttomark + + end % temporary dict + end % FontSetInit ProcSet + /FontSet defineresource + +} bind def + +% ---------------- Resource category definition ---------------- % + +currentdict end readonly + +languagelevel exch 2 .setlanguagelevel + +/FontSet /Generic /Category findresource dup length dict .copydict +/Category defineresource pop + +/FontSetInit exch /ProcSet defineresource pop + +.setlanguagelevel diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_cidcm.ps b/Master/tlpkg/tlgs/Resource/Init/gs_cidcm.ps new file mode 100644 index 00000000000..d2a767f7625 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_cidcm.ps @@ -0,0 +1,447 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Extending Font resource category with CIDFont-CMap fonts. + +languagelevel 2 .setlanguagelevel currentglobal //true setglobal + +% In the comments below, 'CSI' is an abbreviation/acronym for CIDSystemInfo. +% We pre-scan resource files to retrieve the CSI from them. +% First we define a hidden procset .prs_dict containing +% necessary variables and procedures. +% Then we redefine the old /Font category using this procset. + +% We maintain internal caches for the CSI values retrieved from +% resource files. This supposes that document doesn't uninstall +% resource files. To disable caching, set enable_cache to false. + +% We assume that names starting with '.prs' do not appear in resource files. +% If this causes any problem, this prefix should be systematically changed +% in this file. ('prs' is an abbreviation for 'prescan'.) + +25 dict begin + +% Define local variables : + +/.prs_dict currentdict def % self-reference (constant) +/.prs_empty 0 dict readonly def +/path_buffer 8192 string def +/name_buffer 1024 string def +/minus (-) 0 get def % character code constant for '-' +/period (.) 0 get def % character code constant for '.' +/CMap 10 dict def % CSI cache for CMaps +/CIDFont 10 dict def % CSI cache for CIDFonts +/enable_cache //true def % set false to disable cache + +% The folloving variables are just placeholders for ones to be set +% dynamically : +/.prsFile 0 def % file to prescan +/.prsResult 0 def % result of prescan +/.prsDictCount 0 def % save the dictionary stack depth + +% Define a dummy CIDInit procset to use while pre-scanning : + +/DummyCIDInit 15 dict +begin + + /begincmap {} def + /usecmap {pop} bind def + + {stop} bind + [ /begincodespacerange /endcodespacerange /beginnotdefchar /endnotdefchar + /beginnotdefrange /endnotdefrange /begincidchar /endcidchar /begincidrange + /endcidrange /endcmap /usefont /StartData + ] { + 1 index def + } bind forall + pop + +currentdict end def + +% Define a local 'findresource' for pre-scanning : +% (it returns the dummy CIDInit instead of the regular CIDInit ProcSet) + +/findresource { % <InstName> <CatName> findresource <inst> + 2 copy /ProcSet eq exch % /InstName /CatName bool /InstName + /CIDInit eq and { + pop pop //DummyCIDInit + } { + //findresource exec + } ifelse +} bind def + +% Define procedures for pre-scanning : + +/StopIfCSIDefined { % - StopIfCSIDefined - + + % Check if the dictionary stack contains a dictionary containing /CIDSystemInfo. + % The search is limited to the top .prsDictCount dictionaries in the stack. + % If so, retrieve the CSI, and execute stop to terminate the pre-scanning of the file. + % Otherwise, do nothing, so the pre-scanning continues. + + countdictstack //.prs_dict /.prsDictCount get sub dup { + currentdict /CIDSystemInfo .knownget { + //.prs_dict exch /.prsResult exch put + stop + } if + currentdict exch end + } repeat { + begin + } repeat +} bind def + +/PrescanFile { % - PrescanFile - + { //.prs_dict /.prsFile get token { + dup type % token type + dup /nametype eq exch /operatortype eq or { + dup xcheck { + exec + //StopIfCSIDefined exec + } if + } if + } { + stop + } ifelse + } loop +} bind odef + +/GetCIDSystemInfoFromFile { % <file> GetCIDSystemInfoFromFile <CSI> + + % This procedure reads resource files with 'token', + % executing the tokens untill /CIDSystemInfo appears to be defined. + % Normally the resource file creates a new dictionary on + % dictionary stack and defines /CIDSystemInfo in it. + % + % Returns an empty dictionary if no CIDSystemInfo is found. + + RESMPDEBUG { (cidcm GetCIDSystemInfoFromFile beg) = } if + //.prs_dict begin + /.prsFile exch def + /.prsResult //.prs_empty def + /.prsDictCount countdictstack def + RESMPDEBUG { (cidcm GetCIDSystemInfoFromFile will PrescanFile.) = } if + { //PrescanFile } stopped pop + //.prs_dict /.prsResult get + end + RESMPDEBUG { (cidcm GetCIDSystemInfoFromFile end) = } if +} bind def + +/GetCIDSystemInfo { % <InstName> <CatName> GetCIDSystemInfo <CSI> + + % Retrieve CSI, using caches. + + RESMPDEBUG { (cidcm GetCIDSystemInfo beg) = } if + /Category findresource begin % /InstName + dup ResourceStatus + { + pop 2 lt { + FindResource /CIDSystemInfo .knownget not { + //.prs_empty + } if % CSI + } { % /InstName + currentdict /GetCIDSystemInfoFromMap .knownget { + exec + } if + dup type /nametype eq + { + RESMPDEBUG { (cidcm GetCIDSystemInfo got a name.) = } if + //.prs_dict Category get % /InstName CSIs + dup 2 index known + //enable_cache and { + RESMPDEBUG { (cidcm GetCIDSystemInfo from cache.) = } if + exch get % CSI + } { + RESMPDEBUG { (cidcm GetCIDSystemInfo from file.) = } if + exch % CSIs /InstName + dup //path_buffer ResourceFileName % CSIs /InstName (path) + RESMPDEBUG { (cidcm GetCIDSystemInfo from file ) print dup = } if + currentglobal exch //true setglobal % CSIs /InstName g (path) + mark exch % CSIs /InstName g [ (path) + { (r) file } stopped { + cleartomark //.prs_empty + } { + exch 1 index % CSIs /InstName g file [ file + //GetCIDSystemInfoFromFile stopped { + cleartomark closefile //.prs_empty + } { + exch pop exch closefile + } ifelse + } ifelse % CSIs /InstName g CSI + exch setglobal % CSIs /InstName CSI + dup 4 1 roll % CSI CSIs /InstName CSI + put % CSI + RESMPDEBUG { + (cidcm GetCIDSystemInfo got from file : <<) print + dup { exch //=string cvs print ( ) print + //=string cvs print ( ) print + } forall + (>>) = + } if + } ifelse + } if + } ifelse + } { + pop //.prs_empty + } ifelse + end + RESMPDEBUG { (cidcm GetCIDSystemInfo end) = } if +} bind def + +/IsCompatibleCSI { % <CSI-M> <CSI-F> IsCompatibleCSI <bool> + + % The CSI in a CIDFont may be an array, a dict, or null. + % If it is an array, it must be of 1 element, which is a dict. + % In this case the dict is used for testing the compatibility. + % Two dicts are compatible iff they contain same /Ordering and /Registry. + % Identity CMap is compatible with any CIDFont. + + exch % CSI-F CSI-M + { dup type /arraytype eq { + dup length 1 ne { + pop pop //false exit + } if + 0 get + } if % CSI-F CSI-M + dup type /dicttype ne { + pop pop //false exit + } if % CSI-F <<CSI-M>> + exch % <<CSI-M>> CSI-F + dup type /dicttype ne { + pop pop //false exit + } if % <<CSI-M>> <<CSI-F>> + dup /Ordering .knownget { + /Identity eq { + pop pop //true exit + } if + } if + //true % <<CSI-M>> <<CSI-F>> bEQ + [/Registry /Ordering] { + 2 index 1 index .knownget not { + 1234567 + } if % <<CSI-M>> <<CSI-F>> bEQ /key vF + exch % <<CSI-M>> <<CSI-F>> bEQ vF /key + 4 index exch .knownget not { + 7654321 + } if % <<CSI-M>> <<CSI-F>> bEQ vF vM + eq and % <<CSI-M>> <<CSI-F>> bEQ + } forall + exch pop exch pop % bEQ + exit + } loop +} bind def + +/IsWellComposed { % <CIDFontName> <CMapName> IsWellComposed <bool> + + % Check if the given CIDFont and CMap have compatible CSIs. + exch % /CMapName /CIDFontName + /CIDFont //GetCIDSystemInfo exec % /CMapName CSI-F + dup type /dicttype eq { + dup length 0 ne { + exch % CSI-F /CMapName + /CMap //GetCIDSystemInfo exec % CSI-F CSI-M + //IsCompatibleCSI exec % bool + } { + pop pop //false + } ifelse + } { + pop pop //false + } ifelse +} bind def + +/IsComposedFont { % <FontName> IsComposedFont <CIDFontName> <CMapName> true + % <FontName> IsComposedFont false + + % Check if the given font name may be decomposed into CIDFont.CMap, CIDFont-CMap + % or into CIDFont--CMap, such that CIDFont and CMap have compatible CSIs. + % FontName + dup type /stringtype ne { + //name_buffer cvs + } if % (FontName) + { dup length 2 sub -1 1 { + % (FontName) i + 2 copy get dup //minus eq exch //period eq or { + 2 copy 2 copy % (FontName) i (FontName) i (FontName) i + 2 copy get //minus eq { + 2 copy 1 sub get //minus eq { + 1 sub + } if + } if % (FontName) i (FontName) i (FontName) i0 + 0 exch getinterval cvn % (FontName) i (FontName) i /CIDFontName + 3 1 roll % (FontName) i /CIDFontName (FontName) i + 1 add dup % (FontName) i /CIDFontName (FontName) i1 i1 + 5 index length % (FontName) i /CIDFontName (FontName) i1 i1 l + exch sub getinterval cvn % (FontName) i /CIDFontName /CMapName + 2 copy //IsWellComposed exec { % (FontName) i /CIDFontName /CMapName + 4 2 roll pop pop % /CIDFontName /CMapName + stop + } if + pop pop pop + } { + pop + } ifelse % (FontName) + } for + pop + } stopped +} bind def + +/ComposeName { % <CIDFont> <CMap> <scr> ComposeName <CIDFont-CMap> + dup dup 5 2 roll % (scr) (scr) /CIDFont /CMap (scr) + 3 2 roll exch cvs length dup % (scr) (scr) /CMap l0 l0 + 4 -1 roll exch //minus put % (scr) /CMap l0 + 1 add dup % (scr) /CMap l1 l1 + 3 index dup length % (scr) /CMap l1 l1 (scr) L + 2 index sub % (scr) /CMap l1 l1 (scr) LT + 3 2 roll % (scr) /CMap l1 (scr) LT l1 + exch getinterval % (scr) /CMap l1 (scrT) + 3 2 roll exch cvs length % (scr) l1 l2 + add 0 exch getinterval % (CIDFont-CMap) +} bind def + +% Redefine the /Font category with CIDFont-CMap construction : + +% The following code supposes that the following names are not +% defined in the old /Font category dictionary : +% /IsComposedFont, /IsWellComposed . + +/Font /Category findresource dup length dict copy begin + +/FindResource { % <InstName> FindResource <inst> + dup //ResourceStatus exec { + pop pop //FindResource exec + } { + dup //IsComposedFont exec { % /FontName /CIDFontName /CMapName + exch [ exch ] composefont % inst + } { + //FindResource exec + } ifelse + } ifelse +} bind def + +/ResourceStatus { % <InstName> ResourceStatus <nStatus> <nSize> true + % <InstName> ResourceStatus false + dup //ResourceStatus exec { + 3 2 roll pop //true % nStatus nSize true + } { + //IsComposedFont exec { % /CIDFontName /CMapName + /CMap resourcestatus { % /CIDFontName nStatusM nSizeM + exch pop exch % nSizeM /CIDFontName + /CIDFont resourcestatus { % nSizeM nStatusF nSizeF + exch pop % nSizeF nSizeM + dup 0 ge { + exch dup 0 ge { + add + } { + exch pop + } ifelse + } { + pop + } ifelse % nSize + 2 exch //true % nStatus nSize true + } { + pop pop pop //false % work around buggy resource file + } ifelse + } { + pop pop pop //false % work around buggy resource file + } ifelse + } { + //false + } ifelse + } ifelse +} bind def + +/ResourceForAll { % <template> <proc> <scratch> ResourceForAll - + + % We suppose that the resourceforall procedure does not + % define or install new fonts, CMaps, and/or CIDFonts. + + % First we create 3 temporary dictionaries to store temporary data + % about fonts, CMaps and CIDFonts. + % These dictionaries must be created dynamically, to allow for a possible + % recursive call to resourceforall from the resourceforall procedure. + currentglobal //false setglobal + 20 dict 20 dict 20 dict % (templ) proc (scr) g <<CIDFont>> <<CMap>> <<Fonts>> + + % Store resource identifiers into local dictionaries + % A resource instance can have a key that is not a name or a string. In this + % case, resourceforall passes the key directly to proc instead of copying it + % into the scratch string. This case can arise only for a resource instance + % defined in virtual memory by a previous defineresource + + % Discard non-string keys of CIDFont and CMap because <CIDFontName>-<CMapName> + % is only defined for names. + + { /.DisableResourceOrdering pop % gs_resmp accesses this through execstack - don't remove ! + + 6 index [ 2 index {exch //null put} aload pop ] cvx bind 6 index //ResourceForAll exec + + (*) [ 3 index {exch dup type /stringtype eq { cvn dup put } { pop pop } ifelse } aload pop + ] cvx bind 6 index /CMap resourceforall + + (*) [ 4 index {exch dup type /stringtype eq { cvn dup put } { pop pop } ifelse } aload pop + ] cvx bind 6 index /CIDFont resourceforall + + exit + } loop % This loop is a pattern for execstack_lookup - don't remove ! + 4 -1 roll setglobal % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>> + + %% Make the list of fonts in the form (/Name status) : + + % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>> + dup { + pop dup + //ResourceStatus exec { + pop 2 index % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>> /Name nStatus <<Font>> + 3 1 roll put % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>> + } { + pop + } ifelse + } forall % (templ) proc (scr) <<CIDFont>> <<CMap>> <<Fonts>> + + %% Add CIDFont-CMap to it (filtering duplicates) : + + 3 2 roll { + 3 index { + 3 1 roll % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap /CIDFont /CMap + 6 index //ComposeName exec % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap (Font) + dup 8 index .stringmatch { + cvn % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap /Font + dup 4 index exch known { + pop pop + } { + 2 index % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CMap /Font /CIDFont + 4 2 roll % (templ) proc (scr) <<CMap>> <<Font>> /Font /CIDFont /CIDFont /CMap + //IsWellComposed exec { + exch 2 index exch 2 put % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont + } { + exch pop + } ifelse + } ifelse + } { + pop pop + } ifelse + dup % (templ) proc (scr) <<CMap>> <<Font>> /CIDFont /CIDFont + } forall + pop pop % (templ) proc (scr) <<CMap>> <<Font>> + } forall % (templ) proc (scr) <<CMap>> <<Font>> + exch pop % (templ) proc (scr) <<Font>> + 4 3 roll pop % proc (scr) <<Font>> + + % Make the enumerator and apply it : + /MappedCategoryRedefiner /ProcSet findresource /MakeResourceEnumerator get exec exec +} bind def + +currentdict end /Font exch /Category defineresource pop +end +setglobal .setlanguagelevel diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_ciddc.ps b/Master/tlpkg/tlgs/Resource/Init/gs_ciddc.ps new file mode 100644 index 00000000000..612d44a5b09 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_ciddc.ps @@ -0,0 +1,230 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Define SubstCID, Decoding and CIDDecoding resource categories and related procsets. + +languagelevel 2 .setlanguagelevel +currentglobal //true setglobal + +%----------------ParseDecoding procset---------------------------- + +/ParseDecoding << + +/Parse % <resource_name> <num_tokens> Parse - +{ dict begin % /ResName + 0 % /ResName nCode + { currentfile token not { + exit + } if % /ResName nCode token + dup type /integertype eq { % /ResName nCode + exch pop + } { + 1 index def % /ResName nCode + } ifelse + } loop % /ResName nCode + pop % /ResName + currentdict end /Decoding % /ResName <<inst>> /Decoding + defineresource pop +} bind + +>> /ProcSet defineresource pop + +%----------------Decoding category---------------------------- + +/Generic /Category findresource dup length dict copy +dup /InstanceType /dicttype put +/Decoding exch /Category defineresource pop + +%----------------ParseCMap_Inverse procset---------------------------- + +/ParseCMap_Inverse << + /findresource { pop } bind + /defineresource { pop pop } bind + /dict {} + /def { pop pop } bind + /dup //null + /begin { pop } bind + /end {} + /currentdict //null + /CMapName //null + /usecmap { pop } bind + /begincmap {} + /endcmap {} + /begincodespacerange { pop mark } bind + /endcodespacerange { cleartomark } bind + /beginnotdefrange { pop mark } bind + /endnotdefrange { cleartomark } bind + /beginbfchar { pop mark } bind + /endbfchar { pop mark } bind + /beginbfrange { begincidrange } + /endbfrange { endcidrange } + /begincidchar { beginbfchar } + /endcidchar { endbfchar } + /begincidrange { pop mark } bind + /endcidrange { cleartomark } bind +>> % Just keep it on stack for a while. + +% Now we define another dict for local binding, than merge it with the previous one : +dup length 5 add dict begin + + /.Ranges 40 dict def % Key = CID/256, value = array of 256 integer codes. + //.Ranges /CIDCount 0 put + + /.StringToInt % <string> .StringToInt <integer> + { 0 exch { exch 8 bitshift add } forall + } bind def + + /.SetCouple % <I> <b> .SetCouple - + { exch % b I + dup 256 idiv % b I I0 + dup //.Ranges exch known not { + dup //.Ranges exch 256 array put + } if % b I I0 + //.Ranges exch get % b I [Range] + exch 256 mod % b [Range] I1 + 2 copy get % b [Range] I1 e + dup //null ne { + % We've got char code duplicates for same CID. + dup type /integertype eq { + 4 3 roll % [Range] I1 e b + 2 array astore put % + } { + dup length 1 add dup dup array dup % b [Range] I1 D l l D' D' + 3 2 roll 0 exch getinterval % b [Range] I1 D l D' D'' + 4 3 roll exch copy pop % b [Range] I1 l D' + dup 3 2 roll 1 sub % b [Range] I1 D' D' l-1 + 6 5 roll % [Range] I1 D' D' l-1 b + put put % + } ifelse + } { + pop 3 2 roll put % + } ifelse + } bind def + + /endcidrange + { % Writes the inversed CMap to .Ranges + counttomark 3 idiv { % (b) (e) I + exch .StringToInt % (b) I e + 3 2 roll .StringToInt % I e b + % Note : this code does't handle multidimentional CID ranges. + % fixme : optimize below. + dup 3 2 roll exch sub 1 add % I b d + { 2 copy //.SetCouple exec % I b + 1 add exch 1 add exch + } repeat % I b + pop % I + dup //.Ranges /CIDCount get gt { % I + dup //.Ranges exch /CIDCount exch put + } if % I + pop + } repeat + pop % mark + } bind def + + /.GetCIDDecoding % - .GetCIDDEcoding <dict> + { //.Ranges dup length dict copy + //.Ranges //.PurgeDict exec + //.Ranges /CIDCount 0 put + } bind def + +currentdict end +exch copy % Merge the dicts - see above. +/ProcSet defineresource pop + +%----------------CIDDecoding category---------------------------- +% Note that we put all instances in global memory - see FindResource. + +/Generic /Category findresource dup length dict copy +begin + /Category /CIDDecoding def + /InstanceType /dicttype def + + /.CMapChooser << + % This lists CMaps to inverse and unite for creating a CIDDecoding. + % Choose by FAPIcidfmap.Registry concatenated with TrueType encoding ID. + % Font renderer must provide the glyph substitution internally. + + /CNS1.Big5 [ /ETen-B5-H /ETen-B5-V ] + /CNS1.Unicode [ /UniCNS-UCS2-H /UniCNS-UCS2-V] + /CNS1.UCS-4 [ /UniCNS-UCS2-H /UniCNS-UCS2-V] + /GB1.GB2312 [ /GBK-EUC-H /GBK-EUC-V ] + /GB1.Unicode [ /UniGB-UCS2-H /UniGB-UCS2-V ] + /GB1.UCS-4 [ /UniGB-UCS2-H /UniGB-UCS2-V ] + /Japan1.ShiftJIS [ /90ms-RKSJ-H /90ms-RKSJ-V ] + /Japan1.Unicode [ /UniJIS-UCS2-H /UniJIS-UCS2-V] + /Japan1.UCS-4 [ /UniJIS-UCS2-H /UniJIS-UCS2-V] + /Japan2.ShiftJIS [ /90ms-RKSJ-H /90ms-RKSJ-V ] + /Japan2.Unicode [ /UniHojo-UCS2-H ] + /Japan2.UCS-4 [ /UniHojo-UCS2-H ] + /Korea1.Johab [ /KSC-Johab-V /KSC-Johab-H ] + /Korea1.Wansung [ /KSCms-UHC-V /KSCms-UHC-H ] + /Korea1.Unicode [ /UniKS-UCS2-H /UniKS-UCS2-V ] + /Identity.Symbol [ /Identity-H /Identity-V ] + /Unicode.Unicode [ /Identity-UTF16-H ] + /Identity.Unicode [ /Identity-UTF16-H ] + /Identity.UCS-4 [ /Identity-H /Identity-V ] + >> def + + /.MakeInstance % <name> .MakeInstance <inst> + { dup % /Name /Name + //.CMapChooser exch .knownget not { + (Can't build /) print =string cvs print + ( /CIDDecoding resource. See gs_ciddc.ps . ) = flush + /findresource cvx /undefinedresource signalerror + } if % /Name [CMaps] + exch pop % [CMaps] + /CMap /Category findresource % [CMaps] <CMapCategory> + /ParseCMap_Inverse /ProcSet findresource % [CMaps] <CMapCategory> <PCI> + 3 2 roll { % <CMapCategory> <PCI> /CMapName + 3 2 roll begin % <PCI> /CMapName + dup .ResourceFile not { + (Can't find CMap ) print =string cvs print + ( building a CIDDecoding resource. ) = flush + /findresource cvx /undefinedresource signalerror + } if + currentdict end exch % <PCI> /CMapName <CMapCategory> file + + 3 index begin + cvx exec % <PCI> /CMapName <CMapCategory> + end + exch pop exch % <CMapCategory> <PCI> + } forall + exch pop begin % + .GetCIDDecoding + end + } bind def + + /FindResource % <name> FindResource <dict> + { currentglobal exch % bGlobal /InstName + //true setglobal + dup //.MakeInstance exec % bGlobal /InstName <Inst> + DefineResource % bGlobal <Inst> + exch setglobal % <Inst> + } bind def + +currentdict end +/CIDDecoding exch /Category defineresource pop + +%----------------SubstCID category---------------------------- + +/Generic /Category findresource dup length dict copy +begin + /Category /SubstCID def + /InstanceType /dicttype def +currentdict end +/SubstCID exch /Category defineresource pop + +setglobal +.setlanguagelevel diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_cidfm.ps b/Master/tlpkg/tlgs/Resource/Init/gs_cidfm.ps new file mode 100644 index 00000000000..9011634ef95 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_cidfm.ps @@ -0,0 +1,254 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Redefine CIDFont category with cidfmap . + +languagelevel 2 .setlanguagelevel + +4 dict begin +/CategoryName /CIDFont def + +/MapFileName (cidfmap) def + +/IsMyRecord % <raw_record> -> <raw_record> bool +{ % Only for client's needs. + dup type /stringtype eq exch + dup type /nametype eq 3 -1 roll or +} bind def + +/RecordVirtualMethods 3 dict begin + + /MakeInstance % <Name> <record> MakeInstance <Name> <Instance> <size> + { % We know that currentdict is the category. + /Substitute get dup type /stringtype eq + { + (r) file dup cvx exec closefile + dup + } if + + FindResource % /Name <<CIDFont>> + + dup length dict copy % /Name <<CIDFont>> + 1 index ResourceStatus pop exch pop % /Name <<CIDFont>> size + } bind def + + /GetFilePath % <scratch> <Name> <record> GetFilePath <filepath> + { % We know that currentdict is the category. + exch pop + /Substitute get dup type /stringtype eq not + { + exch ResourceFileName + } if + } bind def + + /GetSize % <Name> <record> GetSize <size> + { % We know that currentdict is the category. + dup /Substitute get dup type /stringtype eq + { + % The simplest solution is to instantiate the resource + pop //MakeInstance exec + 3 1 roll pop pop + } + { + exch pop + ResourceStatus { + exch pop exch pop + } { + /undefinedresource signalerror + } ifelse + }ifelse + } bind def + + /GetCSI % <record> GetCSI null + % <record> GetCSI dict + { % We know that currentdict is the category. + RESMPDEBUG { (cidfm GetCSI beg ) = } if + dup /Substitute get dup type /stringtype eq + { + pop + dup /Name get exch //MakeInstance exec + pop exch pop + /CIDSystemInfo get + } + { + exch pop % /Name + GetCIDSystemInfoFromMap + } ifelse + RESMPDEBUG { (cidfm GetCSI end ) print dup = } if + } bind def + + /IsActive % <record> IsActive <bool> + { pop //true + } bind def + +currentdict end def + +% This is the default definition of our fallback CIDFont +/DefaultCIDFallBack +<< + /Path + systemdict /CIDFSubstPath .knownget + { + (/) concatstrings + } + { + (CIDFSUBSTPATH) getenv + { + (/) concatstrings + } + { + currentsystemparams /GenericResourceDir get (CIDFSubst/) concatstrings + } ifelse + } ifelse + + systemdict /CIDFSubstFont .knownget not + { + (CIDFSUBSTFONT) getenv not + { + (DroidSansFallback.ttf) + } if + } if + concatstrings + % The CSI data just has to be valid, the substition machinery will + % generally overwrite it with appropriate values for the missing font. + /CSI [(Identity) 0] + /RecordVirtualMethods //RecordVirtualMethods + /FileType /TrueType + + (CIDFSUBSTFONTID) getenv + { + /SubfontID exch cvi + } if +>> def + +/VerifyMap % <raw_map> VerifyMap - +{ + % Remove any mappings for which we cannot find the font file + dup + { + % if we have a name1->name2 mapping, follow the "trail", + % so if the name2 mapping is known in the .map dict, retrieve + % that map value and loop round until we either reach a map + % which references a TTF (i.e. a dictionary record) or we have + % a name not known in the .map, in which case we have to resort + % to the normal Postscript "resourcestatus". + { + dup type /nametype eq + { + dup 3 index exch .knownget + { exch pop } + { + /CIDFont resourcestatus + { pop pop pop } + { 2 index exch .undef } + ifelse + exit + } ifelse + } + { + dup type /dicttype eq + { + /Path .knownget + { + .libfile + {closefile pop} + { + {(r) file} .internalstopped + {pop pop 2 index exch .undef} + {closefile pop} ifelse + } ifelse + } + {2 index exch .undef} + ifelse + exit + } if + } ifelse + } loop + } forall + + % This is where we insert the default fallback into the map + % checking first to see if there is a user specified alternative + dup /CIDFallBack known not{ + //DefaultCIDFallBack dup /Path get status + { + pop pop pop pop + /CIDFallBack exch 2 index 3 1 roll put + } + { + pop + }ifelse + } if + + % Checks for vicious substitution cycles. + dup length dict copy % <<map>> + dup length dict % <<map>> <<temp>> + { % Choose a random record : + //true 2 index { % <<map>> <<temp>> true /Name /Subs + 3 2 roll pop //false exit % <<map>> <<temp>> /Name /Subs false + } forall + { exit % <<map>> <<temp>> + } if % <<map>> <<temp>> /Name /Subs + % Move the substitution chain to <<temp>>, checking for a cycle : + 3 index 2 index undef % <<map>> <<temp>> /Name /Subs + exch 2 index exch 0 put % <<map>> <<temp>> /Subs + { //IsMyRecord exec not { + % Not a substitution, the chain terminates. + pop exit % <<map>> <<temp>> + } if % <<map>> <<temp>> /Subs + 1 index 1 index known { + (Vicious substitution cycle in map file with the entry ) print =string cvs print ( .) = + /VerifyMap cvx /undefinedresource signalerror + } if % <<map>> <<temp>> /Subs + 1 index 1 index 0 put + dup 3 index exch .knownget not { % <<map>> <<temp>> /Subs + % No more substitutions, the chain terminates. + pop exit % <<map>> <<temp>> + } if % <<map>> <<temp>> /Subs /Subs1 + exch % <<map>> <<temp>> /Subs1 /Subs + 3 index exch undef % <<map>> <<temp>> /Subs1 + } loop + % Not cycled, now purge the <<temp>> : + { % Choose a random record : + //true 1 index { % <<map>> <<temp>> true /Name /Subs + 3 2 roll pop //false exit % <<map>> <<temp>> /Name /Subs false + } forall + { exit % <<map>> <<temp>> + } if % <<map>> <<temp>> /Name /Subs + % Remove it : + pop 1 index exch undef % <<map>> <<temp>> + } loop + } loop + pop pop +} bind def + +/PreprocessRecord % <map> <Name> <raw_record> PreprocessRecord <map> <Name> <record> <bool> +{ + //IsMyRecord exec { + 1 dict begin + /Substitute exch def + dup /Name exch def + /RecordVirtualMethods //RecordVirtualMethods def + currentdict end + //true + } { + //false + } ifelse +} bind def + +currentdict end + +/MappedCategoryRedefiner /ProcSet findresource /Redefine get exec + +.setlanguagelevel diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_cidfn.ps b/Master/tlpkg/tlgs/Resource/Init/gs_cidfn.ps new file mode 100644 index 00000000000..d70d1895c8d --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_cidfn.ps @@ -0,0 +1,413 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% ProcSet for implementing CIDFont and CIDMap resources. +% When this is run, systemdict is still writable. + +% ---------------- Defining CIDFont resources ---------------- % + +% Define a CIDFont resource. This is the defineresource implementation for +% the CIDFont resource category. + +/.checkfonttype { % <cidfont> <fonttype> .checkfonttype <cidfont> <new?> + 1 index /FID known { + 1 index /FontType get ne { + /definefont cvx /invalidfont signalerror + } if //false + } { + 1 index /FontType 3 -1 roll put //true + } ifelse +} bind def + +/.cidfonttypes where { pop } { /.cidfonttypes 6 dict def } ifelse +.cidfonttypes + +30 dict begin + +% The key in .cidfonttypes is the CIDFontType value; +% the value is a procedure that takes a font name and the CIDFont dictionary +% and replaces the latter with a real font. + +% ------ CIDFontType 0 (FontType 9) ------ % + +% We add the following entries to the CIDFont dictionary, in addition to +% the ones documented by Adobe: +% SubrCache - dictionary for caching Subr arrays +% For CIDFonts where we read the data from disk incrementally: +% GlyphData is 0 (arbitrary) +% DataSource - a ReusableStreamDecode filter for the data +% We also add a FID entry, and possibly a Subrs entry, to each element of +% FDArray. + +dup 0 { + 9 .checkfonttype { + /CIDInit /ProcSet findresource begin + .completefont9 + end + } if + 1 index exch .buildfont9 exch pop +} put % Don't bind it here, because gs_fapi.ps redefines .buildfont9 + +% Add entries to a new CIDFontType 0 font per documentation (FontMatrix) +% or for .buildfont9 (FDArray.Private.Subrs). +/.completefont9 { % <cidfont0> .completefont9 <cidfont0> + currentglobal 3 1 roll dup gcheck setglobal + dup /FontMatrix known { + dup /FDArray get { + dup /FontMatrix get 0 get 1000000 ge { + /FontMatrix matrix put % Bug 688517 + } { + pop + } ifelse + } forall + } { + dup /FontMatrix [0.001 0 0 0.001 0 0] put + dup /FDArray get { + currentglobal exch dup gcheck setglobal + dup /FontMatrix get {1000 0 0 1000 0 0} matrix concatmatrix + /FontMatrix exch put + setglobal + } forall + } ifelse + dup /FDArray get { + % Read the Subrs if necessary. + dup /Private get dup /Subrs known not { + dup /SubrCount .knownget { + % Stack: font Private SubrCount + currentglobal 3 1 roll 1 index gcheck setglobal + array 1 index /Subrs 3 -1 roll put + % Stack: font global Private + 2 index begin begin .loadsubrs end end + setglobal + } { + pop + } ifelse readonly pop + } { + pop pop + } ifelse + } forall + 3 -1 roll setglobal +} bind def + +% Read some Subrs for the current Type 1 subfont. +% The subfont's Private dict is currentdict; the CIDFont itself is the +% next dictionary on the stack. +/.readsubrs { % <Subrs> <start> .readsubrs <Subrs> + 1 SubrCount 1 sub { + dup SDBytes mul SubrMapOffset add + dup SDBytes .readint exch SDBytes add SDBytes .readint + 1 index sub string ReadString 2 index 3 1 roll put + } for +} bind def + +% Ensure that all the Subrs for the current Type 1 subfont are loaded. +% The subfont's Private dict is currentdict; the CIDFont itself is the +% next dictionary on the stack. +/.loadsubrs { + Subrs length 0 ne { + SubrCache SubrMapOffset .knownget { + % We've already loaded some Subrs at this offset. + % Make sure we've got as many as we need. + dup length SubrCount lt { + % We need to load more. + SubrCount array exch 1 index copy length .readsubrs + SubrCache SubrMapOffset 2 index put + } if + } { + % We haven't loaded any Subrs at this offset yet. + SubrCount array 0 .readsubrs + SubrCache SubrMapOffset 2 index put + } ifelse + Subrs copy pop + } if +} bind def + +% ------ CIDFontType 1 (FontType 10) ------ % + +dup 1 { + 10 .checkfonttype pop + 1 index exch .buildfont10 exch pop +} put % Don't bind it here because gs_fapi.ps redefines .buildfont10 + +% ------ CIDFontType 2 (FontType 11) ------ % + +dup 2 { + 11 .checkfonttype pop + 1 index exch .buildfont11 exch pop +} put % Don't bind it here because gs_fapi.ps redefines .buildfont11 + +pop % .cidfonttypes + +% ---------------- Reading CIDFontType 0 files ---------------- % + +/StartData { % <(Binary)|(Hex)> <datalength> StartData - + % (currentdict is CID font dict) + % If we're loading a resource file and the data format is + % binary, we can just save a pointer to the data and load it + % incrementally. + mark { + % Previous versions of this code made provisions for + % reading hex-encoded data incrementally. Since hex data + % doesn't seem to be used in practice, we no longer bother. + 2 index (Binary) ne { stop } if + currentfile .currentresourcefile ne { stop } if + % Hack: the pdfwrite driver relies on finalization to write + % out fonts. However, the font may be finalized after the + % resource file, in which case the resource file will be + % closed. So if the current output device is pdfwrite, + % don't use incremental loading. + /AllowIncrementalCFF /GetDeviceParam .special_op { + exch pop {stop}if + }if + currentfile fileposition + } .internalstopped { + % File is not positionable, or uses hex data. + % Load the data now. + cleartomark exch + currentfile exch + (Hex) eq { /ASCIIHexDecode filter } if + exch + % Stack: file length + dup 65400 le { + % readstring with a 0-length string causes a rangecheck, + % but a data length of 0 is allowed. + string dup () ne { 1 index exch readstring pop } if + } { + mark 3 1 roll { + % Stack: mark str ... file length + dup 0 eq { pop exit } if + dup 65400 .min dup string 3 index exch readstring pop + % Stack: mark str ... file length newstrlen newstr + 4 1 roll sub + } loop + counttomark 1 add 1 roll ] + } ifelse + /GlyphData exch def + dup currentfile eq { pop } { closefile } ifelse + } { + % File is positionable and binary, just save a pointer. + % Stack: (Binary) length -mark- pos + /GlyphData 0 def + exch pop 3 -1 roll pop exch + % Stack: pos length + /DataSource currentfile 2 index () .subfiledecode //true .reusablestream def + currentfile 3 1 roll add setfileposition + } ifelse + /SubrCache 10 dict def + CIDFontName currentdict /CIDFont defineresource pop + end % CID font dict + end % resource category dict +} bind def + +% Some Adobe fonts include the line +% /Setup /cid_Setup load def +% This is apparently included only to prevent proper, conforming PostScript +% interpreters (as opposed to ATM or a special Adobe font loader) from +% loading the font, since Setup is not referenced anywhere else in the file. +/cid_Setup { } def + +% ------ Generic ------ % + +% Read a string at a given offset in a "file" (binary file or +% GlyphData in RAM). +/ReadString { % <pos> <string> ReadString <string> + GlyphData 0 eq { + % Read from the file. + DataSource 3 -1 roll setfileposition + DataSource exch readstring pop + } { + % Read from a string or an array of strings. + GlyphData .stringsreadstring + } ifelse +} bind def +/.stringsreadstring % <pos> <string> <strings> .stringsreadstring + % <vmstring> +{ dup type /stringtype eq + { 3 1 roll length getinterval + } + { { % Stack: pos string glyphdata + dup 0 get length dup 4 index gt { exit } if + 4 -1 roll exch sub 3 1 roll + dup length 1 sub 1 exch getinterval + } + loop + % Stack: pos string glyphdata glyphdata[0]length + % We know no request can span more than 2 strings. + 3 index 3 index length add 1 index le + { % Request fits in a single string: just return a substring. + pop 0 get 3 1 roll length getinterval + } + { % Request spans 2 strings. Copy the first part. + 1 index 0 get 4 index 3 -1 roll 1 index sub getinterval + 2 index copy + % Copy the second part. + % Stack: pos str glyphdata str1 + length exch 1 get 0 3 index length + 3 index sub getinterval 2 index 3 1 roll putinterval + exch pop + } + ifelse + } + ifelse +} bind def + +% Interpret a byte string as a (big-endian) integer. +/.cvbsi % <bytes> .cvbsi <int> +{ 0 exch { exch 8 bitshift add } forall +} bind def + +% Read an integer from binary data. +/.readint % <pos> <nbytes> .readint <int> +{ string ReadString .cvbsi +} bind def + +currentdict end + +% ---------------- Rendering ---------------- % + +% ------ CIDFontType 0 ------ % + +/.readglyphdata { + currentfont exch .type9mapcid + FDArray exch get exch +} bind def + +% BuildGlyph procedure for CIDFontType 0. +% The name %Type9BuildGlyph is known to the interpreter. +/.cid0buildstring 10 string def +(%Type9BuildGlyph) cvn { % <cidfont> <cid> %Type9BuildGlyph - + .currentglobal 3 1 roll 1 index gcheck .setglobal + 1 index begin + dup .readglyphdata dup //null eq { + % Substitute CID 0. **** WRONG **** + pop pop 0 .readglyphdata + } if + % Stack: cidfont cid subfont charstring + dup //null eq { pop pop pop pop } { %**** WRONG **** + 4 -1 roll pop + 3 1 roll exch dup 4 -1 roll 0 0 moveto + 3 index /FontType get 2 eq { .type2execchar } { .type1execchar } ifelse + } ifelse %**** WRONG **** + end + .setglobal +} bind def + +% ------ CIDFontType 2 ------ % + +% BuildGlyph procedure for CIDFontType 2. +% The name %Type11BuildGlyph is known to the interpreter. +(%Type11BuildGlyph) cvn { % <cidfont> <cid> %Type11BuildGlyph - + % We must be prepared for out-of-range CIDs. + 2 copy { .type11mapcid } .internalstopped { + pop /CharStrings get /.notdef get + } if + % Stack: cidfont cid glyphindex + 1 index exch .type42execchar +} bind def + +% ---------------- Define resources ---------------- % + +languagelevel exch 2 .setlanguagelevel + +% Define the CIDInit ProcSet resource. +% The ProcSet dictionary is still on the stack. + +% We might have loaded CMap support already. However, Adobe's +% protected font downloader defines a CIDInit ProcSet that will be +% loaded from the filesystem later, so we must check specifically +% for the ProcSet being defined in VM. +/CIDInit /ProcSet 2 copy resourcestatus { pop 0 eq } { //false } ifelse { + pop pop findresource dup length 4 index length add dict .copydict + 4 -1 roll exch .copydict +} { + 3 -1 roll +} ifelse exch defineresource pop + +% Define the CIDFont resource category. +% We break out .buildcidfont because it appears that at least for +% Type 32 (CIDFontType 4) fonts, the font can be registered in the Font +% category with only a CIDFontType and no FontType. +/.buildcidfont { % <name> <fontdict> .buildcidfont + % <name> <cidfont> + systemdict /ProvideUnicode .knownget not { //false } if { + /FontEmulationProcs /ProcSet findresource + /ProvideUnicodeDecoding get exec + } if + dup /CIDFontType get //.cidfonttypes exch get exec +} odef + +/CIDFont /Generic /Category findresource dup length dict .copydict +dup /InstanceType /dicttype put +dup /DefineResource { + dup /OrigFont known not { + dup dup /OrigFont exch .growput % CPSI does it. Adding just for CET 33_all.PS conformity. + } if + dup /PaintType known not { + dup /PaintType 0 .growput % CPSI does it. Adding just for CET 33_all.PS conformity. + } if + .buildcidfont + /Generic /Category findresource /DefineResource get exec +} put +% CIDFonts may be defined in CFF OpenType files. +% Check for this here. +/.loadcidfontresource { + dup .ResourceFile { + {.loadfont} .execasresource + } { + dup /undefinedresource signalerror + } ifelse +} bind def +dup /.LoadResource { + currentglobal { + .loadcidfontresource + } { + //true setglobal {.loadcidfontresource} stopped //false setglobal {stop} if + } ifelse +} bind put + +/Category defineresource pop + +% Add the new FontType resources. + +9 1 11 { dup /FontType defineresource pop } for + +% Add the new FMapType resource. + +9 dup /FMapType defineresource pop + +% Define the CIDMap resource category. +% These aren't documented, but it's clear what they are for: +% to give names to CIDMaps for CIDFontType 2 fonts. + +/CIDMap /Generic /Category findresource dup length dict .copydict +dup /.CheckResource { + % Allow a string, an array of strings, or (as of Adobe release 3011) + % a dictionary. + dup type dup dup /stringtype eq exch /dicttype eq or { + pop //true + } { + dup /arraytype eq exch /packedarraytype eq or { + //true exch { type /stringtype eq and } forall + } { + //false + } ifelse + } ifelse +} bind put +/Category defineresource pop + +.setlanguagelevel + +%% Replace 1 (gs_ciddc.ps) +(gs_ciddc.ps) runlibfile diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_cidtt.ps b/Master/tlpkg/tlgs/Resource/Init/gs_cidtt.ps new file mode 100644 index 00000000000..7e83cfdc6d3 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_cidtt.ps @@ -0,0 +1,186 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Redefine CIDFont category with an emulation with True Type fonts. + +languagelevel 2 .setlanguagelevel + +15 dict begin % a temporary dictionary for local binding. + +%------------------Copy the FontEmulationProcs here : ------------------- + +/FontEmulationProcs /ProcSet findresource { + def +} forall + +currentdict /super.complete_instance currentdict /complete_instance get put + +%-------Auxiliary procedures for building CIDFontType 2 from TT file ----------- + +/GenerateCIDMap % <font> GenerateCIDMap <font> +{ begin + % Obtain the maximal CID : + % This implementation doesn't check whether glyphs really present. + Decoding /CIDCount get /CIDCount exch def + % Prepare the CIDMap structure : + /CIDMap [ + CIDCount 22000 le { + CIDCount 2 mul string + } { + 44000 string + CIDCount 44000 gt { + % need three strings + 44000 string % 22000 2 mul string + CIDCount 44000 sub 2 mul string + } { + CIDCount 22000 sub 2 mul string + } ifelse + } ifelse + ] def + % Now fill it : + Decoding TT_cmap SubstNWP GDBytes CIDMap .fillCIDMap + currentdict end +} bind def + +/GenerateIdentityCIDMap % <font> GenerateCIDMap <font> +{ begin + /CIDMap [ 44000 string 44000 string 44000 string] def + CIDMap .fillIdentityCIDMap + currentdict end +} bind def + +/load_sfnts % <FontDict> load_sfnts <FontDict> +{ % Read the True Type file from the path /Path, and buld /sfnts, + % skipping glyf and loca. + dup /Path get % <font> (path) + QUIET not { + (Loading a TT font from ) print dup print + ( to emulate a CID font ) print 1 index /CIDFontName get =only ( ... ) print + } if + (r) file dup % <font> file file + 3 1 roll % file <font> file + 1 index /SubfontID .knownget not { 0 } if % file <font> file SubfontID + 2 index /FileType .knownget + {/WOFF eq} + {//false} ifelse + % It's not (currently) viable to load WOFF fonts "stripped", so we don't try + {.load_woff_for_cid exch copy exch pop} + { + .load_tt_font_stripped exch + copy % file <font> + QUIET not { + (Done.) = + } if + dup 3 1 roll % <font> file <font> + exch /File exch put % <font> + } ifelse + dup dup /CIDSystemInfo get /Ordering get (.) % <font> () () + 2 index /Decoding get =string cvs % <font> () () () + concatstrings concatstrings cvn /Decoding exch put % <font> + dup dup /CIDSystemInfo get /Ordering get (-WMode) % <font> <font> () () + concatstrings cvn /SubstCID + 2 copy resourcestatus { + pop pop + findresource /subst_CID_on_WMode exch put % <font> + } { + pop pop pop + } ifelse + dup /Decoding get /Identity.Unicode eq { + //ChooseDecoding exec % <font> + //GenerateIdentityCIDMap exec % <font> + } { + //ChooseDecoding exec % <font> + //GenerateCIDMap exec % <font> + } ifelse +} bind def + +%-----------TrueType-specific methods for category redefinition : ----------- + +/RefinePath % <FontDict> RefinePath <FontDict> +{ dup begin + Path .libfile { + dup .filename { + currentdict exch /Path exch put + } if + closefile + } { + (r) { file } .internalstopped + { + (Can't find the font file ) print = + /findfont cvx /undefinedfilename signalerror + } + { + dup .filename { + currentdict exch /Path exch put + } if + closefile + } ifelse + } ifelse + end +} bind def + +/complete_instance % <font_name> <FontDict> <Options> complete_FAPI_Font <font_name> <FontDict> +{ 1 index /CIDFontType 2 put % Other types are not emulated yet. + //super.complete_instance exec + //RefinePath exec + //load_sfnts exec +} bind def + +/ValidFileTypes +<< + /TrueType 0 + /WOFF 0 +>> def + +/IsMyRecord % <raw_record> -> <raw_record> bool +{ + dup type /dicttype eq { dup /FileType .knownget { //ValidFileTypes exch known } { //false } ifelse } { //false } ifelse +} bind def + +currentdict /ValidFileTypes undef + +/IsActive % <record> IsActive <bool> +{ pop //true +} bind 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 + } bind def +currentdict end def + +% Redefine the /CIDFont category : +4 dict begin + /CategoryName /CIDFont def + /IsMapFileOptional //true 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 + +/MappedCategoryRedefiner /ProcSet findresource /Redefine get exec + +end % the temporary dictionary for local binding. + +.setlanguagelevel diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_cmap.ps b/Master/tlpkg/tlgs/Resource/Init/gs_cmap.ps new file mode 100644 index 00000000000..a9143efcb85 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_cmap.ps @@ -0,0 +1,549 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% ProcSet for implementing CMap resources. +% When this is run, systemdict is still writable. + +% NOTE: Rearranged fonts are not implemented yet. + +[ + /CMERGE_DEBUG + /USE_CIDCHAR_AS_RANGE +] {dup where {pop pop} { currentdict exch //false def pop } ifelse} forall + +% ---------------- Public operators ---------------- % + +/.rewriteTempMapsNotDef { + % + % Before building .CodeMapData from .TempMaps, + % we need to replace dst type codes in the notdef map with the value 3, + % which corresponds to CODE_VALUE_NOTDEF, see gxfcmap.h . + % + CMAPDEBUG { (rewriting TempMapsNotDef\n) print flush } if + .TempMaps 2 get + dup length 0 gt { + 0 get + CMAPDEBUG { (...original...\n) print flush } if + 1 5 2 index length 1 sub { + { 1 index exch get 2 3 put } stopped + { CMAPDEBUG { (cannot rewrite\n) print flush } if } + { CMAPDEBUG { (rewrite\n) print flush } if } ifelse + } for + } if + pop + CMAPDEBUG { (...FINISHED...\n) print } if +} bind def + +/.composefontdict { % <name> <cmap|cmapname> <fonts> composefont <name> <font_dict> + 10 dict begin + /CMap 2 index dup type /dicttype ne { /CMap findresource } if def + /FDepVector 1 index cvlit def % temporarily + /Encoding [ 0 1 FDepVector length 1 sub { } for ] def + /FontInfo 1 dict def % for .processToUnicode in pdf_font.ps . + /FDepVector [ 0 1 FDepVector length 1 sub { + % Stack: name cmap[name] fonts /FDepVector [ fonts... i + FDepVector 1 index get + dup type /dicttype ne { + dup /CIDFont resourcestatus { + pop pop /CIDFont + } { + /Font + } ifelse findresource + } if + exch CMap /FontMatrices get dup length 2 index gt { + exch get dup //null eq { pop } { makefont } ifelse + } { + pop pop + } ifelse + } for ] readonly def + /FMapType 9 def + /FontMatrix matrix def + /FontName 3 index def + CMap /WMode .knownget { /WMode exch def } if + /FontType 0 def + pop pop currentdict end +} bind odef + +% composefont doesn't appear in CMap files -- it's documented in +% the "PostScript Language Reference Manual Supplement". +/composefont { % <name> <cmap|cmapname> <fonts> composefont <font> + .composefontdict /Font defineresource +} bind def + +% ---------------- CMap operators ---------------- % + +40 dict begin + +% Our internal .CodeMapData structure closely mirrors the structures +% defined in gxfcmap.h (q.v.). () indicate a string, [] indicate an array, +% ? indicates a Boolean, # indicates an integer, {} for grouping. +% [[[(first) (last) ...]+] % code space ranges +% [[(prefix) (key_size,?is_range,value_type,value_size) (keys...) +% {(values...) | [value ...]} #font_index ]+] % code mappings +% ...] +% <<same>> % notdef mappings +% ] +% FontMatrices is the array of matrices defined by begin/endusematrix. +% All of the arrays and strings are read-only after they have been built. +% +% Note that the code in zfcmap.c that constructs the C structures from +% the PostScript structures has intimate knowledge of the above format. + +% ****** NOTE: The code currently only handles "well-behaved" CMaps: +% - CID values only (no bfchars), 16-bit +% - Entries (both code space and map) must be sorted +% - Only the last byte must vary in each map range, except for +% the identity mapping + +% ------ Font-level operators ------ % + +/begincmap { % - begincmap - + /.CodeMapData [[[]] [[]] [[]]] def + /FontMatrices [] def + /.FontIndex 0 def + /.TempMaps [20 dict 50 dict 50 dict] def + /CodeMap //null def % for .buildcmap +} bind def + +/endcmap { % - endcmap - + .rewriteTempMapsNotDef + + CMAPDEBUG { + 2 (*** undefined charmap ***) + 1 (*** defined charmap ***) + 0 (*** code space ranges ***) + 3 { = + .TempMaps exch get + 0 1 2 index length 1 sub { + dup //== exec (\t) print + 1 index exch get //== exec + } for + pop + } repeat + } if + + /.CodeMapData dup load [ exch + .TempMaps aload pop begin begin begin + { + [ exch aload pop + 0 1 currentdict length 1 sub { + currentdict exch get + } for + ] + end + } forall + ] .endmap def + + CMAPDEBUG { + (*** Content of .CodeMapData ***) = + 0 .CodeMapData { exch dup //== exec 1 add exch (\t) print //== exec } forall + pop + } if + + currentdict /.TempMaps undef + /FontMatrices FontMatrices .endmap def +} bind def + +/.endmap { % <map> .endmap <map> + dup type /arraytype eq { + % This might be a shared read-only array inherited via usecmap. + % Don't try to update its elements if this is the case. + dup wcheck { + 0 1 2 index length 1 sub { + 2 copy 2 copy get .endmap put pop + } for readonly + } if + } { + dup type /stringtype eq { readonly } if + } ifelse +} bind def + +/.appendmap { % -mark- <elt> ... <array#> .appendmap - + .TempMaps exch get counttomark 1 add 1 roll + ] 1 index length exch put +} bind def + +/begincodespacerange { % <count> begincodespacerange - + pop mark +} bind def + +/endcodespacerange { % <code_lo> <code_hi> ... endcodespacerange - + 0 .appendmap +} bind def + +/usecmap { % <CMap_name> usecmap - + /CMap findresource dup + % Copy the top level of .CodeMapData + /.CodeMapData exch /.CodeMapData get copyarray def + /FontMatrices exch /FontMatrices get copyarray def +} bind def + +/usefont { % <fontID> usefont - + /.FontIndex exch def +} bind def + +/beginusematrix { % <fontID> beginusematrix - + FontMatrices wcheck not FontMatrices length 2 index le or { + FontMatrices length 1 index 1 add .max array + dup 0 FontMatrices putinterval + /FontMatrices exch def + } if +} bind def + +/endusematrix { % <matrix> endusematrix - + FontMatrices 3 1 roll put +} bind def + +% ------ Rearranged font operators ------ % + +/beginrearrangedfont { % <font_name> <font*> beginrearrangedfont - + 10 dict begin + /.FontNames exch def + /.FontName exch def + begincmap +} bind def +/endrearrangedfont { % - endrearrangedfont - + (REARRANGED FONTS NOT IMPLEMENTED YET.) = flush + .FontName .FontNames 0 get findfont end definefont pop +} bind def + +% ------ Character name/code selector operators ------ % + +/beginbfchar { % <count> beginbfchar - + pop mark +} bind def +/endbfchar { % <code> <to_code|charname> ... endbfchar + counttomark 2 idiv { + counttomark -2 roll % process in correct order + .addbfchar + } repeat 1 .appendmap +} bind def + +/beginbfrange { % <count> beginbfrange - + pop mark +} bind def +/endbfrange { % <code_lo> <code_hi> <to_code|(charname*)> ... + % endbfrange - + counttomark 3 idiv { + counttomark -3 roll % process in correct order + dup type dup /arraytype eq exch /packedarraytype eq or { + % Array value, split up. + exch pop { + % Stack: code to_code|charname + 1 index exch .addbfchar + % Increment the code. As noted above, we require + % that only the last byte vary, but we still must + % mask it after incrementing, in case the last + % value was 0xff. + % Stack: code prefix params key value fontindex + 6 -1 roll dup length string copy + dup dup length 1 sub 2 copy get 1 add 255 and put + } forall pop + } { + % Single value, handle directly. + .addbfrange + } ifelse + } repeat 1 .appendmap +} bind def + +/.addbfchar { % <code> <to_code|charname> .addbfchar + % <prefix> <params> <key> <value> <font_index> + 1 index exch .addbfrange +} bind def +/.addbfrange { % <code_lo> <code_hi> <to_code|charname> + % .addbfrange <<same as .addbfchar>> + 4 string dup 3 + 3 index type /nametype eq { + 2 index 2 1 put % dst = CODE_VALUE_GLYPH, see gxfcmap.h . + 4 -1 roll 1 array astore 4 1 roll 4 + } { + 2 index 2 2 put % dst = CODE_VALUE_CHARS, see gxfcmap.h . + 3 index length + } ifelse put + % Stack: code_lo code_hi value params + 3 index 3 index eq { + % Single value. + 3 -1 roll pop exch () exch + } { + % Range. + dup 0 4 index length put + dup 1 1 put + 4 2 roll + 1 index dup length 1 sub 0 exch getinterval 5 1 roll % prefix + % Stack: prefix value params code_lo code_hi + concatstrings + 3 -1 roll + } ifelse + .FontIndex +} bind def + +% ------ CID selector operators ------ % + +/begincidchar { % <count> begincidchar - + pop mark +} bind def +/endcidchar { % <code> <cid> ... endcidchar - + 1 .endmapchars +} bind def + +/begincidrange { % <count> begincidrange - + pop mark +} bind def +/endcidrange { % <code_lo> <code_hi> <cid_base> ... endcidrange - + 1 .endmapranges +} bind def + +/.endmapchars { % -mark- <code> <cid> ... <map#> .endmapchars - + counttomark 1 add 1 roll + counttomark 2 idiv { + counttomark -2 roll % process in correct order + exch % <cid> <code> + % Construct prefix, params, key, value, font_index + dup length 1 eq { % 1-byte + <00 00 00 02> () % <prefix> <param> <null_key> + } { % N-byte + dup 0 1 getinterval exch % make 1-byte prefix + 4 string dup 0 + USE_CIDCHAR_AS_RANGE { + <00 01 00 02> % skelton for param + } { + <00 00 00 02> % skelton for param + } ifelse + putinterval + exch % <prefix> <param> <code> + dup length % <prefix> <param> <code> N + 1 sub % <prefix> <param> <code> N-1 + dup % <prefix> <param> <code> N-1 N-1 + 3 index % <prefix> <param> <code> N-1 N-1 <param> + exch % <prefix> <param> <code> N-1 <param> N-1 + 0 exch % <prefix> <param> <code> N-1 <param> 0 N-1 + put % <prefix> <param'> <code> N-1 + 1 exch % <prefix> <param'> <code> 1 N-1 + getinterval % <prefix> <param'> <key> + + USE_CIDCHAR_AS_RANGE { + dup length 2 mul string % <key> <dkey> + dup % <key> <dkey> <dkey> + 2 index % <key> <dkey> <dkey> <key> + 0 exch putinterval % <key> <dkey'> + dup % <key> <dkey'> <dkey'> + 3 -1 roll % <dkey'> <dkey'> <key> + dup length % <dkey'> <dkey'> <key> N-1 + exch putinterval % <dkey''> + } if + + } ifelse + + 4 -1 roll % <prefix> <param'> <key> <cid> + .endmapvalue % <prefix> <param'> <key> <hex_cid> <font_idx> + % prefix params keys value fontindex + counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) + 4 index 10 index eq % compare prefix + 4 index 10 index eq and % compare params + 1 index 7 index eq and % compare fontindex + { + CMAPDEBUG { (merge! char\n) print } if + pop 4 2 roll pop pop + % prefix params keys value fontindex keys2 value2 + 5 -1 roll 3 -1 roll concatstrings + % prefix params value fontindex value2 keys' + 4 -1 roll 3 -1 roll concatstrings + % prefix params fontindex keys' values' + 3 -1 roll + } if + } if % end of 2 (or more) ranges + CMERGE_DEBUG { + ( prefix:) print 4 index =only + ( param:) print 3 index =only + ( key:) print 2 index =only + ( hex_cid:) print 1 index =only + ( font_idx:) print 0 index //== exec flush + } if + } repeat + counttomark 2 add -1 roll .appendmap +} bind def + +/.endmapranges { % -mark- <code_lo> <code_hi> <cid_base> ... <map#> + % .endmapranges - + counttomark 1 add 1 roll + counttomark 3 idiv { + counttomark -3 roll % process in correct order + % Construct prefix, params, key_lo, key_hi, value, font_index + 3 1 roll % <cid_base> <code_lo> <code_hi> + % prefix key + % 1-byte code: () . + % 1-byte range: () . + % N-byte code: . (*) + % N-byte range: (*) (*) + dup 2 index eq { % <code_lo> == <code_hi> + % 0: prefix_len for 1-byte code + % 1: prefix_len for N-byte code + dup length 1 eq { 0 } { 1 } ifelse + } { % <code_lo> != <code_hi> + % calculate prefix_len for *-byte range + dup length 1 sub % <cid_base> <code_lo> <code_hi> <code_len-1> + 0 % initial value for N + { % <cid_base> <code_lo> <code_hi> (code_len-1) N + dup 2 index ge { exit } if % if (N >= len - 1) exit + 3 index 1 index get % N-th byte of code_lo + 3 index 2 index get % N-th byte of code_hi + eq { 1 add } { exit } ifelse + } loop + exch pop % discard <code_len-1> + } ifelse + % cid_base code_lo code_hi prefix_len + + % Althogh Adobe CPSI with native CID/CMap support accept + % multi-dimensional range specification in notdef & cidrange + % (and CID is calculated as relative position in multi-dimensional + % range), but older CPSI & ATM cannot handle it. + % + % GS accepts such specification, but it's recommended to keep + % from using this feature for notdef & cidrange. + % Following is a disabler of this feature. + % ------------------------------------------------------------- + % counttomark 1 add index % get map# + % 0 ne { % if not codespacerange + % 1 index length % get code length + % 1 index % get prefix length + % sub % calculate key length + % 1 gt { % if (key_len > 1), + % (.endmapranges error) = flush + % (multi-dimensional range specification is used out of codespacerange) + % = flush + % (/) =only + % CMapName CMapName length string cvs =only + % (: <) =only + % 2 index (%stdout) (w) file exch writehexstring + % (> <) =only + % 1 index (%stdout) (w) file exch writehexstring + % (>\n) =only flush + % quit + % } if + % } if + % ------------------------------------------------------------- + + 1 index exch 0 exch getinterval + % cid_base code_lo code_hi prefix + dup length 3 index length exch sub + % cid_base code_lo code_hi prefix range_len + dup 255 gt { + (too long coderange specification for current GS\n) print + /.endmapranges cvx /rangecheck signalerror + } if + <00 01 00 02> 4 string copy % create initialized param + dup 0 4 -1 roll put % put range_len into param + + % get key_hi + 3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval + + % get key_lo + 4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval + + % make "keys" (concatenated key_lo + key_hi) + exch concatstrings + + % + 4 -1 roll + .endmapvalue + + % See if we can merge with the previous value. + % The prefix, params, and font index must match. + % prefix params keys value fontindex + counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) + 4 index 10 index eq % compare prefix + 4 index 10 index eq and % compare params + 1 index 7 index eq and % compare fontindex + { + CMAPDEBUG { (merge!\n) print } if + pop 4 2 roll pop pop + % prefix params keys value fontindex keys2 value2 + 5 -1 roll 3 -1 roll concatstrings + % prefix params value fontindex value2 keys' + 4 -1 roll 3 -1 roll concatstrings + % prefix params fontindex keys' values' + 3 -1 roll + } if + } if % end of 2 (or more) ranges + } repeat + counttomark 2 add -1 roll .appendmap +} bind def + +/.endmapvalue { % <cid> .endmapvalue (hi,lo) .FontIndex + 2 string dup 0 3 index -8 bitshift put % value + dup 1 4 -1 roll 255 and put + .FontIndex % font_index +} bind def + +% ------ notdef operators ------ % + +/beginnotdefchar { % <count> beginnotdefchar - + pop mark +} bind def +/endnotdefchar { % <code> <cid> ... endnotdefchar - + 2 .endmapchars +} bind def + +/beginnotdefrange { % <count> beginnotdefrange - + pop mark +} bind def +/endnotdefrange { % <code_lo> <code_hi> <cid> ... endnotdefrange - + 2 .endmapranges +} bind def + +% ---------------- Resource category definition ---------------- % + +currentdict end + +languagelevel exch 2 .setlanguagelevel + +/CMap /Generic /Category findresource dup length dict .copydict +dup /InstanceType /dicttype put +dup /DefineResource { + % The AdobePS5 Windows driver emits code that attempts to + % create CMaps without the required CMapName entry. + % Work around this here. + dup /CMapName known not { + dup wcheck not { + .currentglobal exch dup wcheck .setglobal + dup length dict .copydict exch .setglobal + } if + dup gcheck 2 index gcheck not and { + exch .currentglobal exch //true .setglobal + dup length string copy exch .setglobal exch + } if dup /CMapName 3 index put + } if + % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. + % With the above, we can actually tolerate: /name << >> defineresource + dup /CIDSystemInfo known not { + dup wcheck not { + .currentglobal exch dup wcheck .setglobal + dup length dict .copydict exch .setglobal + } if + dup /CIDSystemInfo [ //null ] put + } if + dup /CodeMap .knownget { //null eq { .buildcmap } if } if + /Generic /Category findresource /DefineResource get exec +} bind put +/Category defineresource pop + % We might have loaded CID font support already. +/CIDInit /ProcSet 2 copy { findresource } .internalstopped + % An interior `stopped' might have reset VM allocation to local. +//true .setglobal + { pop pop 3 -1 roll } + { dup length 4 index length add dict .copydict 4 -1 roll exch .copydict } +ifelse exch defineresource pop + +.setlanguagelevel diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_cspace.ps b/Master/tlpkg/tlgs/Resource/Init/gs_cspace.ps new file mode 100644 index 00000000000..deb282df7ba --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_cspace.ps @@ -0,0 +1,187 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% basic colorspace mechanism + +% +% There have been some major changes to the PostScript colour handling. +% In particular, the vast majority of the colour space code has been +% converted from PostScript to C. This file has been extensively +% modified, as has gs_icc.ps. The remaining PostScript files which +% previously implemented colour space handling; gs_ciecs2.ps, gs_ciecs3.ps +% gs_devcs.ps, gs_devn.ps, gs_devpxl.ps, gs_indxd.ps, gs_patrn.ps and +% gs_sepr.ps have been superceded by the C code and removed. +% +% gs_lev2.ps and gs_ll3.ps have also been modified so that they no longer +% attempt to execute these PostScript files. +% +.currentglobal //true .setglobal +systemdict begin + +% +% gs_res.ps, and possibly other files, use this dictionary. Formerly +% in cspace_util, moved to systemdict. +% +20 dict dup /colorspacedict exch def + +begin % colorspacedict + +% +% gs_res.ps uses these entries in colorspacedict +% to populate the ColorSpaceFamily resource, so we need +% to add the supported spaces. +% +/DeviceGray [] def +/DeviceRGB [] def +/DeviceCMYK [] def +end % colorspacedict + +% +% Global, read-only, unpacked, array-form device color spaces +% We need to return an array argument in response to currentcolorspace +% even if the argument presented to setcolorspace was a simple device +% space name. Not only that, but in order to satisfy some Adobe +% applications, it must be the *same* array every time. The only way +% to do that is to define an appropriate set initial arrays and always return +% one of those. These arrays are defined here. +% +/DeviceGray_array /DeviceGray 1 array astore readonly def +/DeviceRGB_array /DeviceRGB 1 array astore readonly def +/DeviceCMYK_array /DeviceCMYK 1 array astore readonly def + +% +% - initgraphics - +% +% The internal routine gs_initgraphics doesn't (re)set the color space, +% so we must redefine the operation to do it here. +% +% +/initgraphics + { initgraphics systemdict /DeviceGray_array get setcolorspace } +.bind odef + +% +% These routines used for the NOSUBSTDEVICECOLORS switch. This prevents +% substitution of DeviceGray, DeviceRGB and DeviceCMYK with a Default* +% colour space when /UseCIEColors is true. If the job includes a +% definition of /DefaltGray, DefaultRGB or DefaultCMYK then it also executes +% .includecolorspace to allow the device to record the substitute space. +% +/..page_default_spaces 3 dict def + +% +% Used internally to retrieve any relevant default colour space. +% +% <Default space name> ..nosubstdevicetest false +% <Default space name> [space] true +% +% If the boolean is true then the C code must set the additional colour space +% and execute .includecolorspace before finally setting a DeviceGray space. +% +/..nosubstdevicetest +{ + //false mark 3 -1 roll + % If we have already recorded this space, don't repeat it. + systemdict /..page_default_spaces get 1 index known { + cleartomark + } { + { + % Check to see if this space was defined by defineresource, if so then + % the job defined it, otherwise its the usual default, so ignore it. + dup /ColorSpace resourcestatus { + pop 0 eq { + % Default* defined by defineresource + systemdict /..page_default_spaces get 1 index //true put + dup /ColorSpace findresource 4 2 roll pop pop //true + }{ + cleartomark + } ifelse + }{ + cleartomark + } ifelse + } stopped + {cleartomark}if + } ifelse +}bind def + +% +% <color_space_name> ..includecolorspace - +% +/..includecolorspace +{ + % If we have already recorded this space, don't repeat it. + systemdict /..page_default_spaces get 1 index known { + pop + } { + mark exch + { + % Check to see if this space was defined by defineresource, if so then + % the job defined it, otherwise its the usual default, so ignore it. + dup /ColorSpace resourcestatus { + pop 0 eq { + % Job defined /Default*, so record it and allow the device access to it + systemdict /..page_default_spaces get 1 index //true put + gsave + { dup /ColorSpace findresource //setcolorspace exec .includecolorspace + } stopped pop + grestore + } if + } if + } stopped pop + cleartomark + } ifelse +} bind def + +% +% <color_space> <color_space_name> cs_substitute_generic <color_space1> <color_space2> +% +/cs_substitute_generic +{ .getuseciecolor + {NOSUBSTDEVICECOLORS + { //..includecolorspace exec dup } + { /ColorSpace findresource } + ifelse + } + { pop dup } + ifelse +} +bind def + +% +% <color_space> <color_space_name> cs_substitute_DeviceRGB_for_PDFX_or_PDFA <color_space1> <color_space2> +% +/cs_substitute_DeviceRGB_for_PDFX_or_PDFA +{ systemdict /PDFX .knownget not { //false } if + systemdict /PDFA .knownget not { //false } {0 eq {//false}{//true} ifelse} ifelse + or { + dup /ColorSpace resourcestatus { + pop pop + } { + (Error: Need a /DefaultRGB /ColorSpace resource for generating a PDF/X or PDF/A document.) = + /cs_substitute_DeviceRGB_for_PDFX_or_PDFA cvx /undefined signalerror + } ifelse + /ColorSpace findresource + } { + //cs_substitute_generic exec + } ifelse +} bind def +end + +% +% Set the initial device space +% +systemdict /DeviceGray_array get setcolorspace + +.setglobal diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_dbt_e.ps b/Master/tlpkg/tlgs/Resource/Init/gs_dbt_e.ps new file mode 100644 index 00000000000..abd5e13a4b2 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_dbt_e.ps @@ -0,0 +1,58 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Define the Dingbats encoding vector. +/currentglobal where + { pop currentglobal { setglobal } //true setglobal } + { { } } +ifelse +/DingbatsEncoding +% \000 + StandardEncoding 0 32 getinterval aload pop % /.notdef +% \040 + /space /a1 /a2 /a202 /a3 /a4 /a5 /a119 + /a118 /a117 /a11 /a12 /a13 /a14 /a15 /a16 + /a105 /a17 /a18 /a19 /a20 /a21 /a22 /a23 + /a24 /a25 /a26 /a27 /a28 /a6 /a7 /a8 +% \100 + /a9 /a10 /a29 /a30 /a31 /a32 /a33 /a34 + /a35 /a36 /a37 /a38 /a39 /a40 /a41 /a42 + /a43 /a44 /a45 /a46 /a47 /a48 /a49 /a50 + /a51 /a52 /a53 /a54 /a55 /a56 /a57 /a58 +% \140 + /a59 /a60 /a61 /a62 /a63 /a64 /a65 /a66 + /a67 /a68 /a69 /a70 /a71 /a72 /a73 /a74 + /a203 /a75 /a204 /a76 /a77 /a78 /a79 /a81 + /a82 /a83 /a84 /a97 /a98 /a99 /a100 /.notdef +% \200 + StandardEncoding 0 32 getinterval aload pop % /.notdef +% \240 + /.notdef /a101 /a102 /a103 /a104 /a106 /a107 /a108 + /a112 /a111 /a110 /a109 /a120 /a121 /a122 /a123 + /a124 /a125 /a126 /a127 /a128 /a129 /a130 /a131 + /a132 /a133 /a134 /a135 /a136 /a137 /a138 /a139 +% \300 + /a140 /a141 /a142 /a143 /a144 /a145 /a146 /a147 + /a148 /a149 /a150 /a151 /a152 /a153 /a154 /a155 + /a156 /a157 /a158 /a159 /a160 /a161 /a163 /a164 + /a196 /a165 /a192 /a166 /a167 /a168 /a169 /a170 +% \340 + /a171 /a172 /a173 /a162 /a174 /a175 /a176 /a177 + /a178 /a179 /a193 /a180 /a199 /a181 /a200 /a182 + /.notdef /a201 /a183 /a184 /a197 /a185 /a194 /a198 + /a186 /a195 /a187 /a188 /a189 /a190 /a191 /.notdef +256 packedarray .defineencoding +3 DingbatsEncoding .registerencoding +exec diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_diskf.ps b/Master/tlpkg/tlgs/Resource/Init/gs_diskf.ps new file mode 100644 index 00000000000..3cd10f65076 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_diskf.ps @@ -0,0 +1,223 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Support for converting Type 1 fonts without eexec encryption to +% Type 4 fonts that load individual character outlines on demand. + +% If DISKFONTS is true, we load individual CharStrings as they are needed. +% (This is intended primarily for machines with very small memories.) +% Initially, the character definition is the file position of the definition; +% this gets replaced with the actual CharString. +% Note that if we are loading characters lazily, CharStrings is writable. + +% _Cstring must be long enough to hold the longest CharString for +% a character defined using seac. This is lenIV + 4 * 5 (for the operands +% of sbw, assuming div is not used) + 2 (for sbw) + 3 * 5 (for the operands +% of seac other than the character codes) + 2 * 2 (for the character codes) +% + 2 (for seac), i.e., lenIV + 43. + +/_Cstring 60 string def + +% When we initially load the font, we call +% <index|charname> <length> <readproc> cskip_C +% to skip over each character definition and return the file position instead. +% This substitutes for the procedure +% <index|charname> <length> string currentfile exch read[hex]string pop +% [encrypt] +% What we actually store in the CharString is fileposition * 1000 + length, +% negated if the string is stored in binary form. + +/cskip_C + { exch dup 1000 ge 3 index type /nametype ne or + { % This is a Subrs string, or the string is so long we can't represent + % its length. Load it now. + exch exec + } + { % Record the position and length, and skip the string. + dup currentfile fileposition 1000 mul add + 2 index 3 get /readstring cvx eq { neg } if + 3 1 roll + dup _Cstring length idiv + { currentfile _Cstring 3 index 3 get exec pop pop + } repeat + _Cstring length mod _Cstring exch 0 exch getinterval + currentfile exch 3 -1 roll 3 get exec pop pop + } + ifelse + } bind def + +% Load a CharString from the file. The font is the top entry +% on the dictionary stack. +/load_C % <charname> <fileposandlength> load_C - + { dup abs 1000 idiv FontFile exch setfileposition + CharStrings 3 1 roll + .currentglobal CharStrings .gcheck .setglobal exch + dup 0 lt + { neg 1000 mod string FontFile exch readstring } + { 1000 mod string FontFile exch readhexstring } + ifelse pop + exch .setglobal +% If the CharStrings aren't encrypted on the file, encrypt now. + Private /-| get 0 get + dup type /nametype ne + { dup length 5 sub 5 exch getinterval exec } + { pop } + ifelse dup 4 1 roll put +% If the character is defined with seac, load its components now. + mark exch seac_C + counttomark + { StandardEncoding exch get dup CharStrings exch get + dup type /integertype eq { load_C } { pop pop } ifelse + } repeat + pop % the mark + } bind def + +/seac_C % <charstring> seac_C <achar> <bchar> ..or nothing.. + { dup length _Cstring length le + { 4330 exch _Cstring .type1decrypt exch pop + dup dup length 2 sub 2 getinterval <0c06> eq % seac + { dup length + Private /lenIV known { Private /lenIV get } { 4 } ifelse + exch 1 index sub getinterval +% Parse the string just enough to extract the seac information. +% We assume that the only possible operators are hsbw, sbw, and seac, +% and that there are no 5-byte numbers. + mark 0 3 -1 roll + { exch + { { dup 32 lt + { pop 0 } + { dup 247 lt + { 139 sub 0 } + { dup 251 lt + { 247 sub 256 mul 108 add 1 1 } + { 251 sub -256 mul -108 add -1 1 } + ifelse + } + ifelse + } + ifelse + } % 0 + { mul add 0 } % 1 + } + exch get exec + } + forall pop + counttomark 1 add 2 roll cleartomark % pop all but achar bchar + } + { pop % not seac + } + ifelse + } + { pop % punt + } + ifelse + } bind def + +% Define replacement procedures for loading fonts. +% If DISKFONTS is true and the body of the font is not encrypted with eexec: +% - Prevent the CharStrings from being made read-only. +% - Substitute a different CharString-reading procedure. +% (eexec disables this because the implicit 'systemdict begin' hides +% the redefinitions that make the scheme work.) +% We assume that: +% - The magic procedures (-|, -!, |-, and |) are defined with +% executeonly or readonly; +% - The contents of the reading procedures are as defined in bdftops.ps; +% - The font includes the code +% <font> /CharStrings <CharStrings> readonly put +/.loadfontdict 6 dict def mark + /begin % push this dict after systemdict + { dup begin + //systemdict eq { //.loadfontdict begin } if + } bind + /end % match begin + { currentdict end + //.loadfontdict eq currentdict //systemdict eq and { end } if + } bind + /dict % leave room for FontFile, BuildChar, BuildGlyph + { 3 add dict + } bind + /executeonly % for reading procedures + { readonly + } + /noaccess % for Subrs strings and Private dictionary + { readonly + } + /readonly % for procedures and CharStrings dictionary + { % We want to take the following non-standard actions here: + % - If the operand is the CharStrings dictionary, do nothing; + % - If the operand is a number (a file position replacing the + % actual CharString), do nothing; + % - If the operand is either of the reading procedures (-| or -!), + % substitute a different one. + dup type /dicttype eq % CharStrings or Private + count 2 gt and + { 1 index /CharStrings ne { readonly } if } + { dup type /arraytype eq % procedure or data array + { dup length 5 ge 1 index xcheck and + { dup 0 get /string eq + 1 index 1 get /currentfile eq and + 1 index 2 get /exch eq and + 1 index 3 get dup /readstring eq exch /readhexstring eq or and + 1 index 4 get /pop eq and + { /cskip_C cvx 2 packedarray cvx + } + { readonly + } + ifelse + } + { readonly + } + ifelse + } + { dup type /stringtype eq % must be a Subr string + { readonly } + if + } + ifelse + } + ifelse + } bind + /definefont % to insert BuildChar/Glyph and change FontType + { dup /FontType get 1 eq + { dup /FontType 4 put + dup /BuildChar /build_C load put + dup /BuildGlyph /build_C load put + } + if definefont + } bind +counttomark 2 idiv { .loadfontdict 3 1 roll put } repeat pop +.loadfontdict readonly pop + +% Define the BuildChar and BuildGlyph procedures for modified fonts. +% A single procedure serves for both. +/build_C % <font> <code|name> build_C - + { 1 index begin + dup dup type /integertype eq { Encoding exch get } if + % Stack: font code|name name + dup CharStrings exch .knownget not + { 2 copy eq { exch pop /.notdef exch } if + QUIET not + { (Substituting .notdef for ) print = flush } + { pop } + ifelse + /.notdef CharStrings /.notdef get + } if + % Stack: font code|name name charstring + dup type /integertype eq + { load_C end build_C } + { end .type1execchar } + ifelse + } bind def diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_diskn.ps b/Master/tlpkg/tlgs/Resource/Init/gs_diskn.ps new file mode 100644 index 00000000000..bb47655b2fd --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_diskn.ps @@ -0,0 +1,213 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Initialization file for %disk device modifications +% When this is run, systemdict is still writable, + +systemdict begin + +% Collect the list of searchable IODevices in SearchOrder +% Efficiency here doesn't matter since we run this at the end +% of gs_init and convert it to a static array. +/.getsearchabledevs { % - .getsearchabledevs [ list_of_strings ] + //systemdict /.searchabledevs .knownget not { + .currentglobal //true .setglobal + mark (*) { + dup length string copy dup currentdevparams /Searchable + .knownget { not { pop } if } { pop } ifelse + } 8192 string /IODevice resourceforall + ] + % now process the array into correct SearchOrder + 0 1 2 { + mark exch 2 index { + dup currentdevparams /SearchOrder get 2 index eq + { exch } { pop } ifelse + } forall % devices on the old list + pop + % make the array and sort it by name + ] { lt } bind .sort + exch + } for + % collect all devices with SearchOrder > 2 + mark 2 index { + dup currentdevparams /SearchOrder get 2 gt + { exch } { pop } ifelse + } forall + ] exch pop + % We now have 4 arrays on the stack, SO=0 SO=1 SO=2 SO>2 + % make them into a single array + mark 5 1 roll ] mark exch { { } forall } forall ] + //systemdict /.searchabledevs 2 index .forceput + exch .setglobal + } + if +} .bind executeonly def % must be bound and hidden for .forceput + +% Modify .putdevparams to force regeneration of .searchabledevs list +/.putdevparams { + % We could be smarter and check for %disk* device, but this + % doesn't get run enough to justify the complication + //.putdevparams + //systemdict /.searchabledevs .forceundef +} .bind odef % must be bound and hidden for .forceundef + +% ------ extend filenameforall to handle wildcards in %dev% part of pattern -------% +/filenameforall { + count 3 ge { + 2 index (%) search { + pop pop + } { + % no device specified, so search them all + pop (*%) 3 index concatstrings + % we need to suppress the device when we return the string + % in order to match Adobe's behaviour with %disk devices. + 4 -2 roll % the callers procedure + [ { (%) search { pop pop (%) search { pop pop } if } if } /exec load + 4 -1 roll % the callers procedure + /exec load + ] cvx + 4 2 roll % put the modified procedure where it belongs + } ifelse + % extract device portion (up to end of string or next %) + (%) search { exch pop } if % stack: opat proc scratch npat device + dup (*) search { pop pop pop //true } { pop //false } ifelse + 1 index (?) search { pop pop pop //true } { pop //false } ifelse + or not { + pop pop //filenameforall % device with no wildcard + } { + (%) concatstrings (%) exch concatstrings + .getsearchabledevs + % find all matching devices and add the rest of the search string + mark exch { + dup counttomark 1 add index .stringmatch { + counttomark 2 add index concatstrings + } { + pop + } ifelse + } forall + ] + 3 1 roll pop pop + 4 -1 roll pop + % now we need to invoke filenameforall for each of the strings + % in the array. We do this by building a procedure that is like + % an unrolled 'forall' loop. We do this to get the parameters + % for each filenameforall, since each execution will pop its + % parameters, but we can't use the operand stack for storage + % since each invocation must have the same operand stack. + mark exch { + counttomark dup 3 add index exch + 2 add index + /filenameforall load + } forall + ] cvx + 3 1 roll pop pop + exec % run our unrolled loop + } + ifelse + } { + //filenameforall % not enough parameters -- just let it fail + } + ifelse +} odef + +% redefine file to search all devices in order +/file { + dup 0 get (r) 0 get eq dup { + pop //false % success code + 2 index 0 get 37 eq { [ () ] } { .getsearchabledevs } ifelse + { 3 index concatstrings % prepend the device + { + 2 index //file } .internalstopped not { + 4 1 roll pop pop pop //true + exit % exit with success + } { + pop pop + } + ifelse + } + forall + } + if + not { % just let standard file operator handle things + //file + } + if +} bind odef + +% redefine deletefile to search all devices in order +/deletefile { + //false % success code + 1 index 0 get 37 eq { [ () ] } { .getsearchabledevs } ifelse + { 2 index concatstrings % prepend the device + { //deletefile } .internalstopped exch pop not { + pop //true exit % exit with success + } + if + } + forall + not { $error /errorname get /deletefile .systemvar exch signalerror } if +} bind odef + +% redefine status to search all devices in order +/status { + dup type /stringtype eq { + //false % success code + 1 index 0 get 37 eq { [ () ] } { .getsearchabledevs } ifelse + { 2 index concatstrings % prepend the device + { //status } .internalstopped not { + { //true 7 -2 roll pop pop //true exit } % exit with success + if + } + if + } + forall + % If we made it this far, no devices were found to status the file + % clean up to return 'false' + exch pop + } { + //status + } + ifelse +} bind odef + +% Also redefine renamefile to search all devices in order +/renamefile { + //false % success code + 2 index 0 get 37 eq { [ () ] } { .getsearchabledevs } ifelse + { dup 4 index concatstrings % prepend the device + { (r) //file } .internalstopped + not { + closefile exch pop //true exit % exit with success + } { + pop pop + } ifelse + } + forall + not { $error /errorname get /renamefile .systemvar exch signalerror } if + 3 -1 roll concatstrings exch + //renamefile +} bind odef + +% redefine devforall to process devices in numeric order +% Spec's for 'devforall' are unclear, but font downloaders may expect this +/devforall { % <proc> <scratch> devforall - + [ { dup length string copy } 2 index //devforall ] + % stack: proc scratch array_of_device_names + { lt } .sort + % We don't really invoke the procedure with the scratch string + % but rather with the strings from our array + exch pop exch forall +} odef +end % systemdict diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_dpnxt.ps b/Master/tlpkg/tlgs/Resource/Init/gs_dpnxt.ps new file mode 100644 index 00000000000..76fbd288b4c --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_dpnxt.ps @@ -0,0 +1,133 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% gs_dpnxt.ps +% NeXT Display PostScript extensions + +% Define the operation values for compositing. These must match the values +% in gsdpnext.h, which also are the ones from the NeXT documentation. +% We put them in systemdict, which seems like as good a place as any. +mark + /Clear /Copy /Sover /Sin /Sout /Satop /Dover /Din /Dout /Datop /Xor + /PlusD /PlusL /Highlight % not sure about Highlight +counttomark { counttomark 1 sub def } repeat pop + +% We implement readimage and sizeimage using the following 3 otherwise +% undocumented lower-level operators: +% +% <x> <y> <width> <height> <matrix> .sizeimagebox +% <dev_x> <dev_y> <dev_width> <dev_height> <matrix> +% +% - .sizeimageparams <bits/sample> <multiproc> <ncolors> +% +% <device> <x> <y> <width> <max_height> <alpha?> <std_depth|null> +% <string> .getbitsrect <height> <substring> +% +% NOTE: These operators are subject to change without notice! + +% Implement readimage using .getbitsrect. Experimentation on a NeXT system +% shows that the data is always returned in order of increasing device Y, +% regardless of the CTM. +% +% Note that we can't make stack protection work for this operator, +% because it must remove its operands from the stack before calling +% the supplied procedure(s). + +/readimage { % <x> <y> <width> <height> <proc> [... <procN-1>] + % <string> <alpha?> readimage - + .sizeimageparams exch { + % multiproc = true. If N > 1, store the procedures in an array. + exch pop 1 index { 1 add } if + % Stack: ... string alpha? nprocs + dup 1 eq { + pop //false % only 1 procedure, multiproc is irrelevant + } { + dup array 4 1 roll 3 add 2 roll astore 3 1 roll //true + } ifelse + } { + % multiproc = false. + pop pop //false + } ifelse + % Map the rectangle to device coordinates. + % Stack: x y w h proc(s) str alpha? multi? + 8 -4 roll matrix .sizeimagebox pop 8 4 roll + % Make sure we allocate the operand array in local VM + % to avoid a possible invalidaccess. + .currentglobal //false .setglobal 9 1 roll + exch { 1 } { 0 } ifelse exch % alpha is last, if present + exch 4 1 roll 8 array astore exch .setglobal + { % Read out a block of scan lines and pass them to the procedure. + % Stack: [x y w h alpha? proc(s) str multi?] -- we must consume this. + dup 3 get 0 eq { pop exit } if + aload 9 1 roll pop exch pop currentdevice 7 1 roll + % Always read out the data as standard (not native) pixels. + .sizeimageparams pop pop exch .getbitsrect + % Stack: [x y w h alpha? proc(s) str multi?] hread substr + 3 -1 roll + % Stack: hread substr [x y w h alpha? proc(s) str multi?] + dup 1 2 copy get 5 index add put + % Stack: hread substr [x y' w h alpha? proc(s) str multi?] + dup 3 2 copy get 6 -1 roll sub put + % Stack: substr [x y' w h' alpha? proc(s) str multi?] + dup 5 get exch 7 get { + % multiproc = true, pass each plane to a different procedure. + % Stack: substr procs + 0 1 2 index length 1 sub { + % Push 1 plane and its procedure under the top 2 elements. + % Stack: ... substr procs plane# + 2 index length 2 index length idiv % bytes per plane + dup 2 index mul exch + % Stack: ... substr procs plane# start length + 4 index 3 1 roll getinterval 4 1 roll + 2 copy get 4 1 roll pop + } for + exch pop length 2 mul .execn + } { + % multiproc = false, just call the procedure. + exec + } ifelse + } //systemdict /exec get 3 packedarray cvx loop +} bind odef + +% +% <w> <h> <bpc> <mtx> <dsrc0> ... <multi> <ncomp> alphaimage - +% +img_utils_dict begin +/.alphaimage where + { + pop + .currentglobal //true .setglobal + /alphaimage + { + //true + //.colorimage + stopped + { /alphaimage .systemvar $error /errorname get signalerror } + if + } + .bind systemdict begin odef end + .setglobal + } +if +end + +% Implement sizeimage using lower-level operators. + +/sizeimage { % <x> <y> <width> <height> <matrix> sizeimage + % <devwidth> <devheight> <bits/sample> <matrix> + % <multiproc> <ncolors> + .sizeimagebox 5 -2 roll pop pop + .sizeimageparams 3 -1 roll 4 1 roll +} bind odef diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_dps.ps b/Master/tlpkg/tlgs/Resource/Init/gs_dps.ps new file mode 100644 index 00000000000..7eb0a14401d --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_dps.ps @@ -0,0 +1,222 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Initialization file for Display PostScript functions. + +% ------ Errors ------ % + +% These errors are only defined in DPS. +{ /invalidcontext /invalidid } { .registererror } forall + +% ------ Contexts ------ % + +% To create a context with private local VM, we use the .localfork +% operator to actually create the context, the new VM, and an empty +% userdict, and then we call the .initlocaldicts procedure to make +% local copies of the initial contents of the dictionaries in local VM. +% savedlocaldicts in systemdict is a global read-only dictionary whose +% elements are global read-only copies of these initial contents; +% we just copy its elements into local VM and install them in systemdict. +% userdict and internaldict require special handling. + +% Switching between contexts with different local VMs requires +% changing the bindings in systemdict that reference local objects. +% For this purpose, each userdict has an entry called localdicts +% which holds the local copies of the elements of savedlocaldicts, +% plus internaldict. The context switching code in the interpreter +% effectively copies this dictionary into systemdict. +% NOTE: the name localdicts is known to the interpreter. + +% Switching between contexts also requires resetting the user parameters. +% The interpreter records the value of userparams (a local dictionary +% referenced from systemdict) for each context, and uses it for this. +% See gs_lev2.ps for more details. +% NOTE: the name userparams is known to the interpreter. + +% Save copies of local dictionaries at the end of system initialization. +% Also save the initial gstate. +/.savelocalstate { + .currentglobal //true .setglobal + //systemdict /savedlocaldicts mark //systemdict { + dup gcheck { + pop pop + } { + dup type /dicttype eq { + % Save a copy of this dictionary in global VM. + dup maxlength dict .copydict readonly + } { + pop pop + } ifelse + } ifelse + } forall .dicttomark readonly put + % Create localdicts for the current context. + //false .setglobal + userdict /localdicts mark savedlocaldicts { + pop dup load + } forall /internaldict dup load + .dicttomark readonly put + % Save a copy of the initial gstate. + //systemdict /savedinitialgstate gstate readonly .forceput + .setglobal +} .bind def + +% Initialize local dictionaries and gstate when creating a new context. +% Note that until this completes, we are in the anomalous situation of +% having systemdict point to dictionaries that are in a non-current +% local VM. Because of this, we turn off garbage collection temporarily. +/.copylocal { % <name> <dict> .copylocal <name> <dict'> + % Copy a dictionary to the current (local) VM, + % and make it read-only if its current definition is. + dup maxlength dict .copydict + 1 index load wcheck not { readonly } if +} .bind def +% When this is called, the dictionary stack is in its initial state, +% and there is (anomalously) only one gstate on the gstate stack. +/.initlocaldicts { % - .initlocaldicts - + -2 vmreclaim + .currentglobal //systemdict begin + //false .setglobal + % Since localdicts doesn't exist yet, references from + % systemdict to local objects won't get restored if + % a context switch happens in this code. Therefore, + % until localdicts is defined, we have to keep all our + % state on the operand stack. + + % Acquire userdict. + %****** WRONG IF NON-STANDARD INITIAL DSTACK ****** + countdictstack array dictstack + { dup gcheck not { exit } if pop } forall + % Create localdicts with a local copy of each dictionary, + % except for userdict and userparams, which just need + % to be filled in. + mark savedlocaldicts { + 1 index /userdict eq { + % Stack: userdict mark ... /userdict inituserdict + counttomark 1 add index .copydict + } { + 1 index /userparams eq { + % Stack: userdict mark ... /userparams inituserparams + userparams .copydict + } { + .copylocal + } ifelse + } ifelse + } forall /internaldict dup .makeinternaldict .makeoperator + .dicttomark readonly /localdicts exch put + % localdicts is now defined in userdict. + % Copy the definitions into systemdict. + localdicts { .forcedef } forall + % Set the user parameters. + userparams readonly .setuserparams + % Establish the initial gstate(s). + /savedinitialgstate .systemvar setgstate gsave + % Wrap up. + end .setglobal +} odef + +% Check whether an object is a procedure. +/.proccheck { % <obj> .proccheck <bool> + dup xcheck + exch type dup /arraytype eq exch /packedarraytype eq or and +} bind def + +% Create a context with private local VM. +% The .localfork operator does all the work, but we must ensure that +% .initlocaldicts gets called when the new context starts up. +/localfork { % <mark> <obj1> ... <objN> <proc> + % <stdin|null> <stdout|null> + % localfork <context> + .currentglobal //true .setglobal 3 index + dup .proccheck not { + pop .setglobal /localfork .systemvar /typecheck signalerror + } if + {exec .initlocaldicts} aload pop + 3 1 roll 3 packedarray cvx + 4 1 roll 5 -1 roll pop .setglobal .localfork +} odef + +% Fork a context that shares VM. The .fork operator creates an empty +% userparams dictionary for the context, but we still need to initialize +% this dictionary when the new context starts up. +/.postfork { % - .postfork - + % Initialize the user parameters. + savedlocaldicts /userparams get userparams .copydict readonly pop +} odef +/fork { % <mark> <obj1> ... <objN> <proc> fork <context> + .currentglobal //false .setglobal 1 index + dup .proccheck not { + pop .setglobal /fork .systemvar /typecheck signalerror + } if + {exec .postfork} aload pop + 3 1 roll 3 packedarray cvx + 3 1 roll exch pop .setglobal .fork +} odef + +% ------ Halftone phase ------ % + +/sethalftonephase { % <x> <y> sethalftonephase - + -1 2 index 2 index .setscreenphase pop pop +} odef +/currenthalftonephase { % - currenthalftonephase <x> <y> + 0 .currentscreenphase +} odef + +% ------ Device-source images ------ */ + +.imagetypes 2 /.image2 load put + +% ------ Device information ------ % + +/.deviceinfodict mark + /Colors //null /GrayValues //null /RedValues //null /GreenValues //null + /BlueValues //null /ColorValues //null +.dicttomark readonly def +/deviceinfo { % - deviceinfo <dict> + currentdevice //.deviceinfodict .getdeviceparams .dicttomark + dup begin + /ColorValues .knownget { + 0 le + { currentdict /ColorValues undef } + { + % hack around devices that incorrect set GrayValues + Colors 3 eq { 1 } { GrayValues } ifelse + RedValues mul GreenValues mul BlueValues mul ColorValues ne + { currentdict /GrayValues undef + currentdict /RedValues undef + currentdict /GreenValues undef + currentdict /BlueValues undef + } if + } + ifelse + } if + currentdict end readonly +} odef + +% The current implementation allocates a 2-element array each time. +% Perhaps we should change this to 2 separate parameters for X and Y? +/.wtdict mark + /wtranslation //null +.dicttomark readonly def +/wtranslation { % - wtranslation <x> <y> + currentdevice //.wtdict .getdeviceparams exch pop exch pop aload pop +} odef +currentdict /.wtdict .undef + +% ------ View clipping ------ % + +/rectviewclip { % <x> <y> <width> <height> rectviewclip - + % <numarray|numstring> rectviewclip - + newpath .rectappend viewclip +} odef diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_dps1.ps b/Master/tlpkg/tlgs/Resource/Init/gs_dps1.ps new file mode 100644 index 00000000000..a57bb94ed3b --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_dps1.ps @@ -0,0 +1,138 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Initialization file for most of the Display PostScript functions +% that are also included in Level 2. + +level2dict begin + +% ------ Virtual memory ------ % + +/currentshared /.currentglobal load def +/scheck /.gcheck load def +%****** FOLLOWING IS WRONG ****** +/shareddict currentdict /globaldict .knownget not { 20 dict } if def + +% Global and LocalFontDirectory must remain in systemdict +% even if we temporarily exit Level 2 mode. + +end % level2dict +systemdict begin + +/SharedFontDirectory .FontDirectory .gcheck + { .currentglobal //false .setglobal + /LocalFontDirectory .FontDirectory dup maxlength dict copy + .forcedef % LocalFontDirectory is local, systemdict is global + .setglobal .FontDirectory + } + { /LocalFontDirectory .FontDirectory + .forcedef % LocalFontDirectory is local, systemdict is global + 50 dict + } +ifelse def + +end % systemdict +level2dict begin + +% setshared must rebind FontDirectory to the appropriate one of +% Local or SharedFontDirectory. + +/.setglobal % <bool> .setglobal - + { dup .setglobal + //systemdict /FontDirectory .currentglobal + { //SharedFontDirectory } + { /LocalFontDirectory .systemvar } % can't embed ref to local VM + ifelse .forceput pop % LocalFontDirectory is local, systemdict is global + } .bind odef % must bind .forceput and .setglobal + % even if NOBIND in effect +% Don't just copy (load) the definition of .setglobal: +% it gets redefined for LL3. +/setshared { /.setglobal .systemvar exec } odef +.currentglobal setshared + +% See below for changes in save and restore. + +% ------ Fonts ------ % + +/selectfont % <fontname> <size> selectfont - + { + { 1 .argindex findfont + 1 index dup type /arraytype eq { makefont } { scalefont } ifelse + setfont pop pop + } stopped { /selectfont .systemvar $error /errorname get signalerror } if + } odef +% undefinefont has to take local/global VM into account. +/undefinefont % <fontname> undefinefont - + { .FontDirectory 1 .argindex .forceundef % FontDirectory is readonly + .currentglobal + { % Current mode is global; delete from local directory too. + //systemdict /LocalFontDirectory .knownget + { 1 index .forceundef } % LocalFontDirectory is readonly + if + } + { % Current mode is local; if there was a shadowed global + % definition, copy it into the local directory. + //systemdict /SharedFontDirectory .knownget + { 1 index .knownget + { .FontDirectory 2 index 3 -1 roll { put } //superexec } % readonly + if + } + if + } + ifelse pop + } odef + +% If we load a font into global VM within an inner save, the restore +% will delete it from FontDirectory but not from SharedFontDirectory. +% We have to handle this by making restore copy missing entries from +% SharedFontDirectory to FontDirectory. Since this could slow down restore +% considerably, we define a new operator .forcecopynew for this purpose. +% Furthermore, if FAKEFONTS is in effect, we want global real fonts to +% override fake local ones. We handle this by brute force. +/restore % <save> restore - + { dup //restore % bind even if NOBIND + /LocalFontDirectory .systemvar + FAKEFONTS + { mark + % We want to delete a fake font from the local directory + % iff the global directory now has no definition for it, + % or a non-fake definition. + 1 index dup + { % Stack: lfd mark lfd key ... lfd key value + length 1 gt + { % This is a real local definition; don't do anything. + pop + } + { % This is a fake local definition, check for global. + //SharedFontDirectory 1 index .knownget + { % A global definition exists, check for fake. + length 1 eq { pop } { 1 index } ifelse + } + { % No global definition, delete the local one. + 1 index + } + ifelse + } + ifelse + } forall + pop counttomark 2 idiv { .forceundef } repeat pop % readonly + } + if + //SharedFontDirectory exch .forcecopynew pop + .currentglobal .setglobal % Rebind FontDirectory according to current VM. + pop + } .bind odef + +end % level2dict diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_dps2.ps b/Master/tlpkg/tlgs/Resource/Init/gs_dps2.ps new file mode 100644 index 00000000000..cca4ba6fdbd --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_dps2.ps @@ -0,0 +1,246 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Initialization file for basic Display PostScript functions +% that are also included in Level 2. + +level2dict begin + +% ------ Errors ------ % + +% These errors are only defined in Level 2 and DPS. +{ /configurationerror /undefinedresource /unregistered } +{ .registererror } forall + +% ------ Halftones ------ % + +/.makestackdict + { { counttomark -1 roll } forall .dicttomark + } bind def +/currenthalftone % - currenthalftone <dict> + { mark .currenthalftone + { { exch pop } % halftone + { /HalftoneType 1 % screen + { /Frequency /Angle /SpotFunction } + .makestackdict readonly + } + { /HalftoneType 2 % colorscreen + { /RedFrequency /RedAngle /RedSpotFunction + /GreenFrequency /GreenAngle /GreenSpotFunction + /BlueFrequency /BlueAngle /BlueSpotFunction + /GrayFrequency /GrayAngle /GraySpotFunction + } + .makestackdict readonly + } + } + exch get exec + } odef +% Define sethalftone so it converts types 1-4 to type 5. +/.makehalftoneRGBV { % <dict> <type> <keys> <keysRGBV> + 4 -1 roll exch { 1 index exch get exch } forall 15 1 roll + 14 -2 roll mark 15 1 roll { /Gray /Blue /Green /Red } { + % stack: v0 v1 v2 type keys comp + mark + 2 index 0 get 8 -1 roll + 4 index 1 get 9 -1 roll + 6 index 2 get 10 -1 roll + % stack: type keys comp mark k0 v0 k1 v1 k2 v2 + /HalftoneType 10 index .dicttomark + counttomark 2 roll + } forall pop pop + /Default 1 index .dicttomark exch pop { .sethalftone5 } +} bind def + +% The value of each entry in .halftonetypes is a procedure: +% <setdict> <htdict> <<proc>> <setdict'> <htdict'> <sethalftoneproc> +% This allows us to use these procedures both for actually implementing +% sethalftone and for converting subsidiary dictionaries of HalftoneType 5 +% halftones. +systemdict begin +15 dict /.halftonetypes 1 index def begin + 1 { + mark exch /Default exch .dicttomark { .sethalftone5 } + } bind def + 2 { + 1 { /Frequency /Angle /SpotFunction } { + /RedFrequency /RedAngle /RedSpotFunction + /GreenFrequency /GreenAngle /GreenSpotFunction + /BlueFrequency /BlueAngle /BlueSpotFunction + /GrayFrequency /GrayAngle /GraySpotFunction + } .makehalftoneRGBV + } bind def + 3 { + mark exch /Default exch .dicttomark { .sethalftone5 } + } bind def + 4 { + 3 { /Width /Height /Thresholds } { + /RedWidth /RedHeight /RedThresholds + /GreenWidth /GreenHeight /GreenThresholds + /BlueWidth /BlueHeight /BlueThresholds + /GrayWidth /GrayHeight /GrayThresholds + } .makehalftoneRGBV + } bind def + 5 { + pop dup length dict copy + mark 1 index { + % Even HalftoneType 5 dictionaries have entries other than + % subsidiary halftone dictionaries. + dup type /dicttype ne { + 0 + } { + dup /HalftoneType .knownget not { 0 } if + } ifelse dup 5 gt { + % Stack: dict mark ... keyN dictN httypeN + % Assume that all HalftoneTypes > 5 convert to 5. + 1 index 3 1 roll + //.halftonetypes exch get exec pop /Default get + % Stack: dict mark ... keyN setdict'N htdict'N + counttomark 1 add index 3 index 4 -1 roll put + } { + pop + } ifelse + } forall .dicttomark { .sethalftone5 } + } bind def +end +end +/sethalftone { % <dict> sethalftone - + % We must create the new dictionary in the same VM as the + % operand; otherwise, invalidaccess errors may occur. + .currentglobal 1 .argindex dup gcheck .setglobal + dup //.halftonetypes 1 index /HalftoneType get + dup type /integertype ne { + /sethalftone .systemvar /typecheck signalerror + } if + .knownget not { + /sethalftone .systemvar /rangecheck signalerror + } if + exec exec + .setglobal pop +} .bind odef +% Redefine setscreen and setcolorscreen to recognize halftone dictionaries, +% and to insert the Frequency and Angle into Type 1 halftones, per +% Adobe TN 5085. +/.fixsethalftonescreen % <freq> <angle> <dict> .fix...screen + % <freq> <angle> <dict> <dict'> + { dup dup /HalftoneType get 1 eq + { dup wcheck not { dup length dict .copydict } if + dup /Frequency 5 index put + dup /Angle 4 index put + languagelevel 3 ge { dup /AccurateScreens dup getuserparam put } if + } + if + } bind def +/setscreen % <ignore*2> <dict> setscreen - + { dup type /dicttype eq + { .fixsethalftonescreen sethalftone pop pop pop } + { //setscreen } + ifelse + } .bind odef +/setcolorscreen % <ignore*11> <dict> setcolorscreen - + { dup type /dicttype eq + { .fixsethalftonescreen sethalftone 12 { pop } repeat } + { //setcolorscreen } + ifelse + } .bind odef +% Redefine currentscreen and currentcolorscreen to extract the Frequency +% and Angle from Type 1 halftones, per Adobe TN 5085. +/.fixcurrenthalftonescreen % <dict> .fix... <freq> <angle> <proc> + { dup /HalftoneType get 1 eq + { dup /Frequency get 1 index /Angle get } + { 60.0 0.0 } % Adobe returns these as reals + ifelse 3 2 roll + } bind def +/currentscreen % - currentscreen 60 0 <dict> + { .currenthalftone + { { .fixcurrenthalftonescreen } % halftone + { } % screen + { 12 3 roll 9 { pop } repeat % colorscreen + dup type /dicttype eq { .fixcurrenthalftonescreen } if + } + } + exch get exec + } odef +/currentcolorscreen % - currentcolorscreen (60 0 <dict>)*4 +{ .currenthalftone + { { .fixcurrenthalftonescreen 3 copy 6 copy } % halftone + { % screen + % The procedure might not be readable.... + dup rcheck { dup length array copy cvx } if + 3 copy 6 copy + } + { } % colorscreen + } + exch get exec +} odef + +% ------ User objects ------ % + +/.UserObjects { + .userdict /UserObjects +} odef +% In order to get proper error recovery behavior, we need to be careful +% not to pop any operands from the stack until we're done. +% The code below faithfully duplicates the apparent array-growing +% behavior of Adobe interpreters. +/defineuserobject { % <index> <value> defineuserobject - + 1 index 65535 gt { + % .localvmarray throws limitcheck but CET 31-02 wants rangecheck + /defineuserobject .systemvar /rangecheck signalerror + } if + .UserObjects .knownget { + length dup 3 .argindex le { + % Stack: index value len + 2 index eq { 1 index 2 mul } { 1 index 1 add } ifelse + .localvmarray .UserObjects get + 1 index copy pop + .UserObjects 3 -1 roll put + } { + pop + } ifelse + } { + .UserObjects 3 .argindex 1 add 10 .max .localvmarray put + } ifelse + .UserObjects get 2 .argindex 2 index put pop pop +} odef +/execuserobject { % <index> execuserobject - + dup type /integertype ne { + % Adobe validates the argument before accessing UserObjects - CET 31-03 + /execuserobject .systemvar /typecheck signalerror + } if + .UserObjects get 1 .argindex get exch pop exec +} odef +/undefineuserobject { % <index> undefineuserobject - + dup type /integertype ne { + % Adobe validates the argument before accessing UserObjects - CET 31-11 + /undefineuserobject .systemvar /typecheck signalerror + } if + .UserObjects get 1 .argindex //null put pop +} odef + +% ------ Cache control ------ % + +% Dummy definitions for cache control operators + +/ucachestatus { % - ucachestatus -mark- ? ? ? ? <size> + mark 0 0 0 0 /MaxUPathItem getuserparam +} odef +/setucacheparams { % -mark- ... <size> setucacheparams - + % Provoke an appropriate error if needed. + counttomark 1 lt { () 0 get } if + dup 0 or /MaxUPathItem getuserparam .max + 1 dict dup /MaxUPathItem 4 -1 roll put setuserparams cleartomark +} odef + +end % level2dict diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_dscp.ps b/Master/tlpkg/tlgs/Resource/Init/gs_dscp.ps new file mode 100644 index 00000000000..5be220c5f2f --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_dscp.ps @@ -0,0 +1,115 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Postscript interface routines to DSC parser + +/send_orientation { % <orientation> send_orientation - + % .parse_dsc_comments returns -1 for an Orientation key with an + % unrecognized value. + dup 0 ge { + << /Orientation 2 index >> setpagedevice + } if pop +} bind def + +% This dictionary contains local handlers for DSC comments. +% See header in zdscpars.c for more information. +% <dsc_dict> handler <dsc_dict> +/DSCparseprocs mark + /Orientation { dup /Orientation get send_orientation } bind + /PageOrientation { dup /PageOrientation .knownget { send_orientation } + { dup /Orientation .knownget { send_orientation } if } + ifelse } bind + /Page { dup /Orientation .knownget { send_orientation } if } bind + /NOP { } bind +.dicttomark readonly def + +% This procedure is called whenever a DSC comment is found by the interpreter +/do_parse_dsc //false def +/parse_dsc { % <file> <DSC string> [<prev proc>] + % parse_dsc - + % Run any previously installed parser. + 0 get dup //null eq { pop } { 3 copy exec pop } ifelse + + do_parse_dsc { % Check if this parser is enabled + currentglobal //true setglobal % Go to global VM, save old state + 3 1 roll % Put old VM state under <file> <string> + dsc_dict exch % <VM state> <file> <dict> <string> + .parse_dsc_comments % <VM state> <file> <dict> <DSC name> + 4 -1 roll % Get old VM state from under <file> <dict> <DSC name> + setglobal % restore previous VM state + //DSCparseprocs exch .knownget { % Check DSC name against local handler list + exec % execute any local handler + } if + } if + pop pop % remove file, dict +} bind def + +% Check whether the currently installed parser is the one defined in this file. +/.using_parse_dsc { % - .using_parse_dsc <proc> <using?> + currentuserparams /ProcessDSCComment get + dup //null eq { pop {{//null} //parse_dsc exec} } if + dup length 3 eq { + dup dup length 1 sub get /parse_dsc load eq + } { + //false + } ifelse +} bind def + +% Establish a binding for dsc_dict. +userdict /dsc_dict //null put + +% - dsc_init - +/dsc_init { % Initialize DSC parser + currentglobal //true setglobal + /dsc_dict 50 dict store % Size must be large enough for all DSC values + dsc_dict .initialize_dsc_parser + .using_parse_dsc { + % Already using this parser. + pop + } { + % Encapsulate the previous parser. We know it is in global VM: + % allocate the new one in global VM as well. + 1 array astore + /parse_dsc load /exec load 3 array astore cvx readonly + << /ProcessDSCComment 3 -1 roll >> + setuserparams + } ifelse + setglobal + /do_parse_dsc //true def +} bind def + +% Enable the DSC parser defined in this file. +% - enable_dsc - +/enable_dsc { + dsc_init +} bind def + +% Disable the DSC parser defined in this file. +% - disable_dsc - +/disable_dsc { + % There might be another parser installed: if so, restore it. + % (If it has encapsulated our parser, we can't.) + .using_parse_dsc { + % Restore the parser we encapsulated. + 0 get 0 get + currentglobal //true setglobal exch + << /ProcessDSCComment 3 -1 roll >> + exch setglobal setuserparams + } { + pop + } ifelse + % If we couldn't restore the old parser, at least disable ours. + /do_parse_dsc //false def +} bind def diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_epsf.ps b/Master/tlpkg/tlgs/Resource/Init/gs_epsf.ps new file mode 100644 index 00000000000..1ed7e1cbb2e --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_epsf.ps @@ -0,0 +1,291 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Allow the interpreter to encapsulate EPS files, to recognize MS-DOS +% EPSF file headers, and skip to the PostScript section of the file. + +% Encapsulate EPS files and optionally resize page or rescale image. +% To display an EPS file cropped to the bounding box: +% gs -dEPSCrop file.eps +% To display an EPS file scaled to fit the page: +% gs -dEPSFitPage file.eps +% To display a file without EPS encapsulation: +% gs -dNOEPS file.ps + +% When starting to process an EPS file, state is 0. +% After %%BoundingBox processed, state is 1 if OK or 2 if cropped. +% After %%HiResBoundingBox processed, state is 3 if OK or 4 if cropped. +% After %%EndComments processed, state is 5. +/EPSBoundingBoxState 5 def +/EPSBoundingBoxSetState { + //systemdict /EPSBoundingBoxState 3 -1 roll .forceput +} .bind odef % .forceput must be bound and hidden + +% Parse 4 numbers for a bounding box +/EPSBoundingBoxParse { % (llx lly urx ury) -- llx lly urx ury true OR false + mark exch + token {exch token {exch token {exch token {exch pop} if} if} if} if + counttomark + 4 eq { + 5 -1 roll pop % remove mark + //true + } { + cleartomark //false + } ifelse +} bind def + +% Crop the page to the BoundingBox +/EPSBoundingBoxCrop { % llx lly urx ury -- + EPSDEBUG { + (gs_epsf.ps: Setting pagesize from EPS bounding box\n) print flush + } if + exch 3 index sub exch 2 index sub % stack: llx lly urx-llx ury-lly + << /PageSize [ 5 -2 roll ] >> setpagedevice + neg exch neg exch translate +} bind def + +% Rescale, translate and rotate to fit the BoundingBox on the page +/EPSBoundingBoxFitPage { % llx lly urx ury -- + EPSDEBUG { (gs_epsf.ps: Rescaling EPS to fit page\n) print flush } if + clippath pathbbox newpath + % translate to new origin at lower left of clippath + 3 index 3 index translate + % Figure out if rotate is needed. + + 1 index 4 index sub 1 index 4 index sub eq not { + 1 index 4 index sub 1 index 4 index sub gt % bbox page-clipbox page-is-landscape + 6 index 10 index sub 6 index 10 index sub gt % bbox page-clipbox page-is-landscape bbox-is-landscape + xor + }{ + false + }ifelse + 9 1 roll % compute need-rotate. + % stack: rotate-needed bbox page-clipbox + % calculate scale to fit smaller of width or height + exch 4 -1 roll sub 3 1 roll exch sub + 4 2 roll 5 index 5 index 4 2 roll + exch 4 -1 roll sub 3 1 roll exch sub + 4 2 roll + exch 4 -1 roll div 3 1 roll exch div + 1 index 1 index lt {pop}{exch pop} ifelse + dup scale + % translate to EPS -llx,-lly + exch neg exch neg translate + % Finally perform the rotate if needed. + { clippath pathbbox pop 0 exch translate 90 rotate pop pop } if +} bind def + +/EPSBoundingBoxProcess { % (llx lly urx ury) state -- + //systemdict /EPSBoundingBoxState get 1 index lt { + exch EPSBoundingBoxParse + { + //systemdict /EPSCrop known { + EPSBoundingBoxCrop + } { + //systemdict /EPSFitPage known { + EPSBoundingBoxFitPage + } { + % Warn if some of the EPS file will be clipped + clippath pathbbox newpath + { % context for exit + 5 -1 roll lt { 6 { pop } repeat //true exit } if + 4 -1 roll lt { 4 { pop } repeat //true exit } if + 3 -1 roll gt { 2 { pop } repeat //true exit } if + exch gt { //true exit } if + //false exit + } loop + QUIET not and /EPSBoundingBoxState .systemvar 1 and 1 eq and { + (\n **** Warning: Some of the BoundingBox for the EPS file will be clipped.) = + ( Use -dEPSCrop or -dEPSFitPage to avoid clipping.\n) = + flush + 1 add + } if + } ifelse + } ifelse + EPSBoundingBoxSetState + } { + pop % state + } ifelse + } { + pop pop + } ifelse +} bind def + +/ProcessEPSComment { % file comment -- file comment + /EPSBoundingBoxState .systemvar 3 lt { + dup + (%%BoundingBox:) anchorsearch { + pop + EPSDEBUG { (gs_epsf.ps: found %%BoundingBox\n) print flush } if + 1 EPSBoundingBoxProcess + } { + (%%HiResBoundingBox:) anchorsearch { + pop + EPSDEBUG { (gs_epsf.ps: found %%HiResBoundingBox\n) print flush } if + 3 EPSBoundingBoxProcess + } { + pop % Not interested in this DSC comment + } ifelse + } ifelse + } if + /EPSBoundingBoxState .systemvar 5 lt { + dup (%%DocumentCustomColors:) anchorsearch { + pop + [ exch + { { + token not { exit } if + dup type /stringtype ne { stop } if + dup (atend) eq { stop } if + exch + } loop + { + counttomark 2 add index + dup (123) .peekstring not { stop } if + (%%+) eq { + dup (123) readstring pop pop + 256 string readline pop + cvx exec + } { + pop exit + } ifelse + } loop + } stopped { + cleartomark + } { + counttomark 0 gt { + currentpagedevice /MaxSeparations get 4 gt { + ] << /SeparationColorNames 3 -1 roll >> setpagedevice + } { + cleartomark + } ifelse + } { + cleartomark + } ifelse + } ifelse + } { + (%%EndComments) anchorsearch { + pop pop + % Ignore any following comments + 5 EPSBoundingBoxSetState + } { + pop + } ifelse + } ifelse + } if +} bind def + +% Install EPS handler for DSC comments, which we do later +/EPSBoundingBoxInit { + systemdict /NOEPS known not { + % Merge ProcessEPSComment with existing handler + /ProcessEPSComment load /exec load + currentuserparams /ProcessDSCComment get + dup //null eq {pop {pop pop}} if /exec load + 4 array astore cvx readonly + << /ProcessDSCComment 3 -1 roll >> setuserparams + } if +} bind def + +/.runNoEPS /run load def + +/.runEPS { % file OR string -- + /runEPS_save save def + /runEPS_dict_count countdictstack def + /runEPS_op_count count 2 sub def + /runEPS_page_count currentpagedevice /PageCount get def + 0 EPSBoundingBoxSetState + .runNoEPS + currentpagedevice /PageCount get runEPS_page_count sub 0 eq + { /showpage load exec } if + count runEPS_op_count sub {pop} repeat + countdictstack runEPS_dict_count sub {end} repeat + runEPS_save restore +} bind def + +/run { % file OR string -- + dup type /filetype ne { (r) file } if + dup (%!PS-Adobe-) .peekstring { + (%!PS-Adobe-) eq { + dup (%!PS-Adobe-X.X EPSF-X.X) .peekstring { + (EPSF) search { + pop pop pop + EPSDEBUG {(runEPS: Found EPS\n) print flush} if + systemdict /NOEPS known { + cvx .runNoEPS + } { + cvx .runEPS + } ifelse + } { + EPSDEBUG {(runEPS: Normal DSC\n) print flush} if + pop + cvx .runNoEPS + + } ifelse + } { + EPSDEBUG {(runEPS: Short DSC\n) print flush} if + pop + cvx .runNoEPS + } ifelse + } { + EPSDEBUG {(runEPS: Not DSC\n) print flush} if + cvx .runNoEPS + } ifelse + } { + EPSDEBUG {(runEPS: Short non-DSC\n) print flush} if + pop + cvx .runNoEPS + } ifelse +} bind odef + +% Handle DOS EPS files. + +/.runnoepsf /run load def +/.epsfheader <C5D0D3C6> def +/run + { dup type /filetype ne { (r) file } if + % Check for MS-DOS EPSF file (see Red Book p. 729). + dup ( ) .peekstring + { .epsfheader eq { dup ( ) readstring exch pop } { //false } ifelse } + { pop //false } + ifelse + % Stack: file true/false + { % This block is executed if the file is MS-DOS EPSF. + % Build up the little-endian byte offset and length. + 2 + { 1 0 4 + { 2 index read not { pop exit } if % if EOF, let error happen + 2 index mul add exch 256 mul exch + } + repeat exch pop exch + } + repeat + % Stack: offset length file + % Use flushfile to skip quickly to the start of the + % PostScript section. + dup 4 -1 roll 12 sub () /SubFileDecode filter flushfile + % Now interpret the PostScript. + exch () /SubFileDecode filter cvx run + } + { .runnoepsf + } + ifelse + } odef + +% rebind .runstdin to use redefined run +userdict begin +/.runstdin { + { (%stdin) run } execute0 +} bind def +end diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_fapi.ps b/Master/tlpkg/tlgs/Resource/Init/gs_fapi.ps new file mode 100644 index 00000000000..c78b1b9fccc --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_fapi.ps @@ -0,0 +1,460 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, 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 <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 +} 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 % <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 +} 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> + { 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 % <Name> <record> MakeInstance <Name> <Instance> <size> + { currentglobal 3 1 roll //true setglobal + //CIDFontOptions //complete_instance exec + 2 copy //GetSize exec + 4 3 roll setglobal + } bind def +currentdict 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 +} 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 % <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 systemdict /FAPIcidfmap known {/FAPIcidfmap .systemvar} {(FAPIcidfmap)} ifelse 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>> + { (\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 +} 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.\n) print flush } //FAPI_hook_debug exec + } ifelse +} bind def + +% ------------------ Redefine .buildfont* with FAPI : ----------------------- + +/.buildfont1 +{ //.buildfont1 exec 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 diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_fntem.ps b/Master/tlpkg/tlgs/Resource/Init/gs_fntem.ps new file mode 100644 index 00000000000..5775a36a684 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_fntem.ps @@ -0,0 +1,415 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% A procset for Postscript font emulation + +% The procedures must not depend on the presence of the +% procset dictionary on the dictionary stack. + +languagelevel 2 .setlanguagelevel + +%========================= Process xlatmap ==================== +mark +%% Replace 1 (xlatmap) +(xlatmap) .runlibfile +.dicttomark dup systemdict exch /.xlatmap_dict exch put + +% Convert it into a plain text to simplify the processing in C : +% *(fontkind\0\0\ *(charmap\0decoding\0) ) \0 + +() exch { + 3 1 roll =string cvs concatstrings (\0\0) concatstrings + exch + { =string cvs concatstrings (\0) concatstrings + } forall +} forall +(\0) concatstrings +systemdict exch /.xlatmap exch put + +/FontEmulationProcs 10 dict begin + +%-------------------------------Font-------------------------------- + +/FontCommon % - font_common - +{ currentdict /PaintType known not { + /PaintType 0 def + } if + currentdict /Encoding .knownget not { + //StandardEncoding + } if + dup type /nametype eq { + /Encoding findresource + } if + /Encoding exch def +} bind def + +/FontOptions 5 dict begin + /make_procs currentdict def + /NameKey /FontName def + /TypeKey /FontType def + + 1 + { + currentdict /FontMatrix known not { /FontMatrix [0.001 0 0 0.001 0 0] def } if + currentdict /FontBBox known not { /FontBBox [-128 -128 1024 1024] cvx def } if % zfapi.ps refines it. + /Private 0 dict def + % if we're using the FAPI/UFST code for Microtype fonts, + % then we've already created a "fake" CharStrings, so don't replace it. + % See gs_fapi.ps + currentdict /CharStrings known not {/CharStrings << /.notdef () >> def} if + //FontCommon exec + } bind def + + 42 + { /FontMatrix [1 0 0 1 0 0] def + /FontBBox [0 0 1 1] def % zfapi.ps refines it. + /CharStrings <<>> def + /sfnts [<00010000 0000 0000 0000 0000 0000>] def + /GlyphDirectory [] def + //FontCommon exec + } bind def + + %fixme : more font types. + +currentdict end def + +%---------------------------CIDFont--------------------------- + +/TranslateCSI % <record> TranslateCSI <CSI> +{ RESMPDEBUG { (fntem TranslateCSI beg ) = } if + begin + CSI length 2 eq { + << /Registry (Adobe) + /Ordering CSI aload pop + /Supplement exch + >> + } { + << /Registry CSI 0 get + /Ordering CSI 1 get + /Supplement CSI 2 get + >> + } ifelse + end + RESMPDEBUG { (fntem TranslateCSI end ) = } if +} bind def + +/CIDFontCommon +{ /CIDSystemInfo currentdict //TranslateCSI exec def + currentdict /CSI undef + /FontBBox [-128 -128 1024 1024] def % zfapi.ps refines it. + /CIDCount 1 def % ChooseDecoding will set a reasonable value. +} bind def + +% GFlyph substitution table for narrow, wide, proportional glyphs - +% used with TrueTypes. + +currentpacking //false setpacking +/SubstNWP << + + % Array format : orig_type, beg_CID, end_CID, subst_beg_CID, subst_type + % type = (n==narrow, w==wide, p==proportional). + + /Japan1 + { p 1 94 231 n + + p 17 26 780 w + p 34 59 790 w + p 66 91 816 w + w 842 842 7918 w % fixme: These substitutions require to shift the glyph origin. + w 844 844 7919 w + w 846 846 7920 w + w 848 848 7921 w + w 850 850 7922 w + w 876 876 7923 w + w 908 908 7924 w + w 910 910 7925 w + w 912 912 7926 w + w 914 914 7927 w + w 925 925 7928 w + w 927 927 7929 w + w 929 929 7930 w + w 931 931 7931 w + w 933 933 7932 w + w 959 959 7933 w + w 991 991 7934 w + w 993 993 7935 w + w 995 995 7936 w + w 1002 1002 7937 w + w 1009 1009 7938 w + w 1010 1010 7939 w + } cvlit + + /Japan2 1 index + + /CNS1 + { p 1 94 13648 n + + p 17 26 333 w + p 34 59 365 w + p 66 91 391 w + } cvlit + + /GB1 + { p 2 94 814 n + + p 2 94 262 w + + p 1 1 7716 n + } cvlit + + /Korea1 + { p 1 60 8094 n + p 62 94 8155 n + + p 2 59 264 w + p 63 94 325 w + } cvlit + + /Identity [] + + /Unicode [] + +>> def +setpacking + +/CIDFontOptions 5 dict begin + /make_procs currentdict def + /NameKey /CIDFontName def + /TypeKey /CIDFontType def + + 0 + { //CIDFontCommon exec + /FDArray [ + 14 dict begin + /FontName CIDFontName =string cvs (%) concatstrings cvn def + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0 ] def + /PaintType 0 def + /Private 0 dict def + currentdict + end + ] def + /GlyphDirectory [] def + /GDBytes 1 def + /FDBytes 0 def + } bind def + + 1 + { //CIDFontCommon exec + /FontMatrix [1 0 0 1 0 0] def + /BuildGlyph {} def + } bind def + + 2 + { //CIDFontCommon exec + /FontMatrix [1 0 0 1 0 0] def + /GDBytes 2 def + /CIDMap <0000> def + /sfnts [<00010000 0000 0000 0000 0000 0000>] def + /Encoding [] def + /CharStrings << /.notdef 0 >> def + } bind def + +currentdict end def + +/complete_instance % <font_name> <FontDict> <Options> complete_FAPI_Font <font_name> <FontDict> +{ begin + dup length dict copy + begin + dup type /nametype ne { cvn } if + dup NameKey exch def + currentglobal //true setglobal + make_procs TypeKey load .knownget { + exec + } { setglobal + /complete_instance cvx /invalidfont signalerror + } ifelse + setglobal + currentdict end + end +} bind def + +/GetFilePath % <scratch> <Name> <record> GetFilePath <filepath> +{ exch pop % (scratch) <record> + /Path get % (scratch) (path) + exch copy + % What we make here it is not a complete PS resource. + % Unable to provide full conformity : + % the attempt to run this file may fail. +} bind def + +/GetSize % <Name> <record> GetSize <size> +{ pop pop -1 % Unknown size. + % fixme: probably we could provide an estimation size for some fonts. +} bind def + +/RecordVirtualMethodsStub 3 dict begin + /GetFilePath //GetFilePath def + /GetSize //GetSize def +currentdict end def + +% ---------------------- Decoding helpers ---------------------------- + +/encodingnames mark + StandardEncoding /StandardEncoding + ISOLatin1Encoding /ISOLatin1Encoding + SymbolEncoding /SymbolEncoding + DingbatsEncoding /DingbatsEncoding +.dicttomark def + +/ChooseDecoding % <font> ChooseDecoding <font> +{ { % A loop for 'exit' context. + dup /Decoding .knownget { + dup type /nametype eq { + 1 index /CIDFontType known { /CIDDecoding } { /Decoding } ifelse + findresource 1 index exch /Decoding exch put + } { + pop + } ifelse + dup /CIDFontType known { + dup dup /Decoding get /CIDCount get /CIDCount exch put + } if + exit + } if + dup /CIDFontType known { + % This is a hooked CID font, no need for Decoding. + exit + } if + % This works when the renderer can't choose character by name, + % and we cannot determine the charset. + % Probably this branch is to be removed after UFST problem is fixed. + dup /Encoding get % <<font>> encoding + dup type /nametype eq { + /Decoding findresource 1 index exch /Decoding exch put + } { + dup //encodingnames + exch .knownget { + { /Decoding findresource } stopped {pop pop //true}{ exch pop 1 index exch /Decoding exch put //false } ifelse + } + { + //true + } ifelse + + { + % unknown encoding, or an encoding for which we don't have a + % predefined decoding, convert it to decoding : + dup length dict begin + /.notdef 0 def + 0 1 currentdict length 1 sub + { dup 2 index exch get + dup dup /.notdef ne exch type /nulltype ne and { + exch def + } { + pop pop + } ifelse + } for + pop + currentdict end + 1 index exch /Decoding exch put + } if + } ifelse + exit + } loop + dup /CIDFontType known { + dup /SubstNWP .knownget not { + dup /CIDSystemInfo get /Ordering get cvn + } if + dup type /nametype eq { + //SubstNWP exch .knownget not { + [] + } if % <<font>> [SubstNWP] + } if + 1 index exch /SubstNWP exch put + } if +} bind def + +/PrintFontRef % <string|name> <font> PrintFontRef <string|name> <font> +{ dup /FontName known { (Font ) } { (CIDFont ) } ifelse print + 1 index =string cvs print + dup /FontName .knownget not { + dup /CIDFontName get + } if % <string|name> <font> <fontname> + dup 3 index ne { + ( \( aliased from ) print + =string cvs print ( \)) print + } { + pop + } ifelse +} bind def + +/GetFontType % <font> GetFontType int +{ dup /CIDFontType .knownget { + exch pop 9 add + } { + /FontType get + } ifelse +} bind def + +/FindInArray % <array> <elem> .array_find <bool> +{ //false 3 1 roll + exch { % false elem elem_i + 1 index eq { % false elem + pop //true exch + } if + } forall + pop +} bind def + +/ProvideUnicodeDecoding % <font> ProvideUnicodeDecoding <font> +{ + % If the font is maintained by FAPI, or if it is TT-emulated CID font, + % it already has /Decoding. But its value isn't guaranteeed to + % be an Unicode decoding. Since we can't determine whether + % it is an Unicode decoding, we unconditionally load an appropriate Unicode decoding + % and attach it with /GlyphNames2Unicode entry. + % + % Another interesting case is when the font already has /GlyphNames2Unicode. + % The latter to be used instead. Note that /GlyphNames2Unicode + % appears only when type 32 fonts are disable (see .pdf_hook_DSC_Creator), + % but an automatic disabling is not implemented yet. + + currentglobal //true setglobal exch + dup /FontInfo known not { + dup /FontInfo 1 dict put + } if + { % A loop just for 'exit' context. + dup /FontInfo get /GlyphNames2Unicode known { + exit + } if + dup /CIDFontType known { + dup mark exch % bool <font> [ <font> + dup /CIDSystemInfo get /Ordering get (.Unicode) % bool <font> [ <font> () () + concatstrings cvn % bool <font> [ <font> /Name + /CIDDecoding { findresource } stopped { + % Can't provide a decoding, giving up without creating /GlyphNames2Unicode. + cleartomark exit + } if % bool <font> [ <font> <D> + exch /FontInfo get exch % bool <font> [ <FI> <D> + /GlyphNames2Unicode exch + .forceput % FontInfo can be read-only. + pop % bool <font> + exit + } if + dup /FontInfo get % bool <font> <FI> + /GlyphNames2Unicode /Unicode /Decoding findresource + .forceput % FontInfo can be read-only. + exit + } loop + exch setglobal +} bind def + +currentdict end /ProcSet defineresource pop + +.setlanguagelevel diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps b/Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps new file mode 100644 index 00000000000..a3da615cb3f --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps @@ -0,0 +1,1288 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Font initialization and management code. + +% Define the default font. +/defaultfontname /Courier def + +% Define the name of the font map file. +% Note that the "%%Replace " comment below provides the font map file name +% for compiling initialization files into executable. Most likely it should be +% consistent with the one specified here. +/defaultfontmap (Fontmap) def + +/defaultfontmap_content 50 dict +1 dict begin +/; { 2 index 3 1 roll .growput } bind def +%% Replace 0 (Fontmap) +end def + +% ------ End of editable parameters ------ % + +% Define the UniqueIDs and organization XUID assigned to Artifex. +% UniqueIDs 5,066,501 - 5,066,580 are assigned as follows: +% 01 and 02 for shareware Cyrillic +% 33 through 67 for Type 1 versions of the Hershey fonts +% UniqueIDs 5,115,501 - 5,115,600 are currently unassigned. +/AladdinEnterprisesXUID 107 def + +% If SUBSTFONT is defined, make it the default font. +/SUBSTFONT where { pop /defaultfontname /SUBSTFONT load def } if + +% Define a reliable way of accessing FontDirectory in systemdict. +/.FontDirectory +{ /FontDirectory .systemvar +} .bind odef + +% If DISKFONTS is true, we load individual CharStrings as they are needed. +% (This is intended primarily for machines with very small memories.) +% In this case, we define another dictionary, parallel to FontDirectory, +% that retains an open file for every font loaded. +/FontFileDirectory 10 dict def + +% Define a temporary string for local use, since using =string +% interferes with some PostScript programs. +/.fonttempstring 8192 string def + +% Split up a search path into individual directories or files. +/.pathlist % <path> .pathlist <dir1|file1> ... + { { dup length 0 eq { pop exit } if + .filenamelistseparator search not { exit } if + exch pop exch + } + loop + } bind def + +% Load a font name -> font file name map. +userdict /Fontmap .FontDirectory maxlength dict put +userdict /.nativeFontmap .FontDirectory maxlength dict put +/.loadFontmap { % <file> .loadFontmap - + % We would like to simply execute .definefontmap as we read, + % but we have to maintain backward compatibility with an older + % specification that makes later entries override earlier + % ones within the same file. + 50 dict exch .readFontmap + { .definefontmap } forall +} bind def +/.readFontmap { % <dict> <file> .readFontmap <dict> + { dup token not { closefile exit } if + % stack: dict file fontname + % This is a hack to get around the absurd habit of MS-DOS editors + % of adding an EOF character at the end of the file. + dup (\032) eq { pop closefile exit } if + 1 index token not + { (Fontmap entry for ) print dup =only + ( has no associated file or alias name! Giving up.) = flush + {.readFontmap} 0 get 1 .quit + } if + dup type dup /stringtype eq exch /nametype eq or not + { (Fontmap entry for ) print 1 index =only + ( has an invalid file or alias name! Giving up.) = flush + {.readFontmap} 0 get 1 .quit + } if + % stack: dict file fontname filename|aliasname + 1 index type /stringtype eq + 1 index type /nametype eq and 1 index xcheck and + 1 index /run eq 2 index /.runlibfile eq or and { + % This is an inclusion entry. + pop findlibfile { exch pop } { file } ifelse + 2 index exch .readFontmap pop + } { + % This is a real entry. + % Read and pop tokens until a semicolon. + { 2 index token not + { (Fontmap entry for ) print 1 index =only + ( ends prematurely! Giving up.) = flush + {.loadFontmap} 0 get 1 .quit + } if + dup /; eq { pop 3 index 3 1 roll .growput exit } if + pop + } loop + } ifelse + } loop +} bind def +% Add an entry in Fontmap. We redefine this if the Level 2 +% resource machinery is loaded. +/.definefontmapaux % <bool> <fontname> <file|alias> .definefontmapaux - + { % Since Fontmap is global, make sure the values are storable. + % If the fontname contains Unicode (first byte == \000) and + % this is not an alias definition, define an alias using ASCII + % (stripping out the high \000 bytes). Observed with some TT fonts. + 1 index 100 string cvs + dup length 0 gt { + 0 get 0 eq 1 index type /nametype ne and { + 1 index 100 string cvs dup length 2 div cvi string //true exch + 0 1 2 index length 1 sub { + % stack: fontname filename fontnamestring addflag newstring index + dup 4 index exch 2 mul get 0 ne { + % High byte of pair is not \000 + pop pop //false exch + exit + } if + dup 4 index exch 2 mul 1 add get 2 index 3 1 roll put + } for + exch { + DEBUG { (\nAdding alias for: ) print 1 index ==only ( as: ) print dup //== exec flush } if + cvn exch cvn .definefontmapaux % recurse with an alias + } { + pop pop % discard the name + } ifelse + } if + } { + pop + } ifelse + .currentglobal 3 1 roll //true .setglobal + dup type /stringtype eq + { dup .gcheck not { dup length string copy } if + } + if + + 4 -1 roll {.nativeFontmap}{Fontmap} ifelse + 3 -1 roll 2 copy .knownget + { % Add an element to the end of the existing value, + % unless it's the same as the current last element. + mark exch aload pop counttomark 4 add -1 roll + 2 copy eq { cleartomark pop pop } { ] readonly .growput } ifelse + } + { % Make a new entry. + mark 4 -1 roll ] readonly .growput + } + ifelse .setglobal + } bind def + +/.definefontmap % <fontname> <file|alias> .definefontmap - +{ + //false 3 1 roll //.definefontmapaux exec +} bind def + +/.definenativefontmap % <fontname> <file|alias> .definenativefontmap - +{ + //true 3 1 roll //.definefontmapaux exec +} bind def + +% Parse a font file just enough to find the FontName or FontType. +/.findfontvalue { % <file> <key> .findfontvalue <value> true + % <file> <key> .findfontvalue false + % Closes the file in either case. + exch dup read { + 2 copy unread 16#80 eq { + dup (xxxxxx) readstring pop pop % skip .PFB header + } if + { % Stack: key file + % Protect ourselves against syntax errors here. + dup { token } stopped { //false exit } if + not { //false exit } if % end of file + dup /eexec eq { pop //false exit } if % reached eexec section + dup /Subrs eq { pop //false exit } if % Subrs without eexec + dup /CharStrings eq { pop //false exit } if % CharStrings without eexec + dup 3 index eq + { xcheck not { dup token exit } if } % found key + { pop } + ifelse + } loop + % Stack: key file value true (or) + % Stack: key file false + dup { 4 } { 3 } ifelse -2 roll closefile pop + } { closefile pop //false } ifelse +} bind def +/.findfontname + { /FontName .findfontvalue + } bind def + +% If there is no FONTPATH, try to get one from the environment. +NOFONTPATH { /FONTPATH () def } if +/FONTPATH where + { pop } + { /FONTPATH (GS_FONTPATH) getenv not { () } if def } +ifelse +FONTPATH length 0 eq { (%END FONTPATH) .skipeof } if +/FONTPATH [ FONTPATH .pathlist ] def + +% Scan directories looking for plausible fonts. "Plausible" means that +% the file begins with %!PS-AdobeFont or %!FontType1, or with \200\001 +% followed by four arbitrary bytes and then either of these strings. +% To speed up the search, we skip any file whose name appears in +% the Fontmap (with any extension and upper/lower case variation) already, +% and any file whose extension definitely indicates it is not a font. +% +% NOTE: The current implementation of this procedure is somewhat Unix/DOS- +% specific. It assumes that '/' and '\' are directory separators, and that +% the part of a file name following the last '.' is the extension. +% +/.lowerstring % <string> .lowerstring <lowerstring> + { 0 1 2 index length 1 sub + { 2 copy get dup 65 ge exch 90 le and + { 2 copy 2 copy get 32 add put } + if pop + } + for + } bind def +/.splitfilename { % <dir.../base.extn> .basename <base> <extn> + % Make the file name read-only to detect aliasing bugs. + % We really don't like doing this, but we've had one + % such bug already. + readonly { + (/) search { //true } { (\\) search } ifelse { pop pop } { exit } ifelse + } loop + dup { (.) search { pop pop } { exit } ifelse } loop + 2 copy eq { + pop () + } { + exch dup length 2 index length 1 add sub 0 exch getinterval exch + } ifelse +} bind def +/.scanfontdict 1 dict def % establish a binding +/.scanfontbegin + { % Construct the table of all file names already in Fontmap. + currentglobal //true setglobal + .scanfontdict dup maxlength Fontmap length 2 add .max .setmaxlength + Fontmap + { exch pop + { dup type /stringtype eq + { .splitfilename pop .fonttempstring copy .lowerstring cvn + .scanfontdict exch //true put + } + { pop + } + ifelse + } + forall + } + forall + setglobal + } bind def +/.scanfontskip mark + % Strings are converted to names anyway, so.... + /afm //true + /bat //true + /c //true + /cmd //true + /com //true + /dir //true + /dll //true + /doc //true + /drv //true + /exe //true + /fon //true + /fot //true + /h //true + /o //true + /obj //true + /pfm //true + /pss //true % Adobe Multiple Master font instances + /txt //true +.dicttomark def +/.scan1fontstring 8192 string def +% %%BeginFont: is not per Adobe documentation, but a few fonts have it. +/.scanfontheaders [(%!PS-Adobe*) (%!FontType*) (%%BeginFont:*)] def +0 .scanfontheaders { length .max } forall 6 add % extra for PFB header +/.scan1fontfirst exch string def +/.scanfontdir % <dirname> .scanfontdir - + { currentglobal exch //true setglobal + QUIET not { (Scanning ) print dup print ( for fonts...) print flush } if + [ 1 index ] (*) .generate_dir_list_templates + 0 0 0 4 -1 roll % found scanned files + { % stack: <fontcount> <scancount> <filecount> <filename> + exch 1 add exch % increment filecount + dup .splitfilename .fonttempstring copy .lowerstring + % stack: <fontcount> <scancount> <filecount+1> <filename> + % <BASE> <ext> + .scanfontskip exch known exch .scanfontdict exch known or + { pop + % stack: <fontcount> <scancount> <filecount+1> + } + { 3 -1 roll 1 add 3 1 roll + % stack: <fontcount> <scancount+1> <filecount+1> <filename> + dup (r) { file } .internalstopped + { pop pop //null () + % stack: <fontcount> <scancount+1> <filecount+1> <filename> + % null () + } + { + % On some platforms, the file operator will open directories, + % but an error will occur if we try to read from one. + % Handle this possibility here. + dup .scan1fontfirst { readstring } .internalstopped + { pop pop () } + { pop } + ifelse + % stack: <fontcount> <scancount+1> <filecount+1> + % <filename> <file> <header> + } + ifelse + % Check for PFB file header. + dup (\200\001????*) .stringmatch + { dup length 6 sub 6 exch getinterval } + if + % Check for font file headers. + //false .scanfontheaders + { 2 index exch .stringmatch or + } + forall exch pop + { % stack: <fontcount> <scancount+1> <filecount+1> <filename> + % <file> + dup 0 setfileposition .findfontname + { dup .nativeFontmap exch known + { pop pop + } + { exch copystring exch + DEBUG { ( ) print dup =only flush } if + 1 index .definenativefontmap + .splitfilename pop //true .scanfontdict 3 1 roll .growput + % Increment fontcount. + 3 -1 roll 1 add 3 1 roll + } + ifelse + } + { pop + } + ifelse + } + % .findfontname will have done a closefile in the above case. + { dup //null eq { pop } { closefile } ifelse pop + } + ifelse + } + ifelse + } + .scan1fontstring filenameforall + QUIET + { pop pop pop } + { ( ) print =only ( files, ) print =only ( scanned, ) print + =only ( new fonts.) = flush + } + ifelse + pop + setglobal + } bind def + +%END FONTPATH + +% Try to enumerate native fonts registered with the os +% and add them to the fontmap. This relies on a custom +% operator which calls platform-specific C code. It +% returns an array of arrays, each containing a pair +% of strings: what the system thinks is the ps name, +% and the access path. +/.setnativefontmapbuilt { % set whether we've been run + systemdict exch /.nativefontmapbuilt exch .forceput +} .bind executeonly def +systemdict /NONATIVEFONTMAP known .setnativefontmapbuilt +/.buildnativefontmap { % - .buildnativefontmap <bool> + systemdict /.nativefontmapbuilt .knownget not + { //false} if + + {//false} + { + QUIET not { + (Querying operating system for font files...\n) + print flush + } if + .getnativefonts dup + { + exch + { + % stack: [ (name) (path) ] + % verify the font name ourselves + dup 1 get (r) { file } .internalstopped + { + % skip the entry if we can't open the returned path + pop pop pop + }{ + % we could open the font file + mark 2 1 roll + {.findfontname} .internalstopped + { + cleartomark + pop + } + { + counttomark 1 add -1 roll pop + not { dup 0 get } if % stack: (newname) [ (name) (path) ] + % DEBUG { ( found ) print dup print (\n) print flush } if + % add entry to the fontmap + 1 index exch 0 exch dup type /nametype ne {cvn} if put + aload pop .definenativefontmap + } ifelse + } ifelse + } forall + } if + % record that we've been run + //true .setnativefontmapbuilt + } ifelse +} bind def + +% Create the dictionary that registers the .buildfont procedure +% (called by definefont) for each FontType. +/buildfontdict 20 dict def + +% Register Type 3 fonts, which are always supported, for definefont. +buildfontdict 3 /.buildfont3 cvx put + +% Register Type 0 fonts if they are supported. Strictly speaking, +% we should do this in its own file (gs_type0.ps), but since this is +% the only thing that would be in that file, it's simpler to put it here. +/.buildfont0 where { pop buildfontdict 0 /.buildfont0 cvx put } if + +% Define definefont. This is a procedure built on a set of operators +% that do all the error checking and key insertion. +/.growfontdict + { % Grow the font dictionary, if necessary, to ensure room for an + % added entry, making sure there is at least one slot left for FID. + dup maxlength 1 index length sub 2 lt + { dup dup wcheck + { .growdict } + { .growdictlength dict .copydict } + ifelse + } + { dup wcheck not { dup maxlength dict .copydict } if + } + ifelse + } bind def +/.completefont { + { % Check for disabled platform fonts. + NOPLATFONTS + { % Make sure we leave room for FID. + .growfontdict dup /ExactSize 0 put + } + { % Hack: if the Encoding looks like it might be the + % Symbol or Dingbats encoding, load those now (for the + % benefit of platform font matching) just in case + % the font didn't actually reference them. + % Note that some types of font don't have an Encoding. + dup /Encoding .knownget { + dup length 65 ge { + 64 get + dup /congruent eq { SymbolEncoding pop } if + /a9 eq { DingbatsEncoding pop } if + } { + pop + } ifelse + } if + } + ifelse + dup /OrigFont known not { + dup dup /OrigFont exch .growput + } if + //true exch + % If this is a CIDFont, CIDFontType takes precedence + % over FontType. + dup /CIDFontType known { + /.buildcidfont where { + pop exch not exch % true => false + } if + } if + exch { + dup /FontType get //buildfontdict exch get + } { + {.buildcidfont} % so it gets bound + } ifelse + } stopped { $error /command get /invalidfont signalerror } if + + % Execute the .buildxxxfontx outside the 'stopped', because we don't + % want its errors converted to invalidfont. + exec + + { + + DISKFONTS { + FontFileDirectory 2 index known { + dup /FontFile FontFileDirectory 4 index get .growput + } if + } if + systemdict /ProvideUnicode .knownget not { //false } if { + /FontEmulationProcs /ProcSet findresource + /ProvideUnicodeDecoding get exec + } if + readonly % stack: name fontdict + } stopped { $error /command get /invalidfont signalerror } if +} bind def +/definefont + { dup rcheck not { + /definefont cvx /invalidaccess signalerror + } if + /definefont cvx {.completefont} .errorexec + % If the current allocation mode is global, also enter + % the font in LocalFontDirectory. + .currentglobal + { //systemdict /LocalFontDirectory .knownget + { 2 index 2 index { .growput } //superexec } % readonly + if + } + if + dup .FontDirectory 4 -2 roll { .growput } //superexec % readonly + % If the font originated as a resource, register it. + currentfile .currentresourcefile eq { dup .registerfont } if + readonly + } odef + +% Define a procedure for defining aliased fonts. +% We use this only for explicitly aliased fonts, not substituted fonts: +% we think this matches the observed behavior of Adobe interpreters. +/.aliasfont % <name> <font> .aliasfont <newFont> + { .currentglobal 3 1 roll dup .gcheck .setglobal + % <bool> <name> <font> + dup length 2 add dict % <bool> <name> <font> <dict> + dup 3 -1 roll % <bool> <name> <dict> <dict> <font> + { 1 index /FID eq { pop pop } { put dup } ifelse } forall + % <bool> <name> <dict> <dict> + % Stack: global fontname newfont newfont. + % We might be defining a global font whose FontName + % is a local string. This is weird, but legal, + % and doesn't cause problems anywhere else: + % to avoid any possible problems in this case, do a cvn. + % We might also be defining (as an alias) a global font + % whose FontName is a local non-string, if someone passed a + % garbage value to findfont. In this case, just don't + % call definefont at all. + 2 index dup type /stringtype eq exch .gcheck or 1 index .gcheck not or + { pop % <bool> <name> <dict> + 1 index dup type /stringtype eq { cvn } if + % <bool> <name> <dict> <name1> + % HACK: + % We want to know whether we alias a font, + % because in this case its FontName to be replaced with the alias. + % There is no simple way to know that at this point. + % But if the original font has defaultfontname, + % we probably substitute it rather than alias. + % Using such condition as an approximation to the strong condition. + % + % Note it works wrongly if Fontmap maps something to defaultfontname like this : + % /Courier /NimbusMonL-Regu ; + % /Something /Courier ; + % The FontName of Something will not be /Something. It will be /Courier . + % + 1 index /FontName get defaultfontname ne { + 2 copy /FontName exch put + } if + 1 index exch /.Alias exch put % <bool> <name> <dict> + dup dup /OrigFont exch .growput + % Don't bind in definefont, since Level 2 redefines it. + /definefont .systemvar exec + } + { /findfont cvx {.completefont} .errorexec pop exch pop + } + ifelse + exch .setglobal + } odef % so findfont will bind it + +% Define .loadfontfile for loading a font. If we recognize Type 1 and/or +% TrueType fonts, gs_type1.ps and/or gs_ttf.ps will redefine this. +/.loadfontfile { + % According to Ed Taft, Adobe interpreters push userdict + % before loading a font, and pop it afterwards. + userdict begin + cvx exec + end +} bind def +/.setloadingfont { + //systemdict /.loadingfont 3 -1 roll .forceput +} .bind odef % .forceput must be bound and hidden +/.loadfont + { % Some buggy fonts leave extra junk on the stack, + % so we have to make a closure that records the stack depth + % in a fail-safe way. + //true .setloadingfont + { /FAPI_hook_disable pop % gs_fapi accesses this with execstack_lookup - don't remove ! + {{.loadfontfile} .execasresource} count 1 sub 2 .execn + count exch sub { pop } repeat + exit + } loop % this loop is a pattern for execstack_lookup, don't remove ! + //false .setloadingfont + } bind def + +% Find an alternate font to substitute for an unknown one. +% We go to some trouble to parse the font name and extract +% properties from it. Later entries take priority over earlier. +/.substitutefaces [ + % Define substitutes for the fonts we define in Fontmap.GS + [(Charter) /Times 0] + [(Utopia) /Times 0] + [(Antiqua) /Times 0] + [(Calligraphic) /Helvetica 0] + [(Hershey) /Times 0] + % Guess at suitable substitutions for random unknown fonts. + [(Book) /NewCenturySchlbk 0] + [(Grot) /Helvetica 0] + [(Roman) /Times 0] + [(Chancery) /ZapfChancery-MediumItalic 0] + % If the family name appears in the font name, + % use a font from that family. + [(Arial) /Helvetica 0] + [(Avant) /AvantGarde 0] + [(Bookman) /Bookman 0] + [(Century) /NewCenturySchlbk 0] + [(Cour) /Courier 0] + [(Frut) /Helvetica 0] + [(Garamond) /Palatino 0] + [(Geneva) /Helvetica 0] + [(Helv) /Helvetica 0] + [(NewYork) /Bookman 0] + [(Pala) /Palatino 0] + [(Schlbk) /NewCenturySchlbk 0] + [(Swiss) /Helvetica 0] + [(Symbol) /Symbol 0] + [(Times) /Times 0] + % Substitute for Adobe Multiple Master fonts. + [(Minion) /Times 0] + [(Myriad) /Helvetica 0] + % If the font wants to be monospace, use Courier. + [(Monospace) /Courier 0] + [(Typewriter) /Courier 0] + % Define substitutes for the other Adobe PostScript 3 fonts. + % For some of them, the substitution is pretty bad! + [(Albertus) /Palatino 0] + [(AntiqueOlive) /Helvetica 0] + [(Bodoni) /NewCenturySchlbk 0] + [(Chicago) /Helvetica 2] + [(Clarendon) /Bookman 0] + [(Cooper) /NewCenturySchlbk 0] + [(Copperplate) /AvantGarde 0] % inappropriate, small-cap font + [(Coronet) /ZapfChancery-MediumItalic 0] + [(Eurostile) /Helvetica 0] + [(Geneva) /Courier 2] % should be fixed-pitch sans demi + [(GillSans) /Helvetica 2] + [(GillSans-Light) /Helvetica 0] + [(Goudy) /Palatino 0] + [(Hoefler) /NewCenturySchlbk 0] + [(Joanna) /Times 0] + [(LetterGothic) /Courier 0] % should be fixed-pitch sans + [(LubalinGraph-Book) /Bookman 2] + [(LubalinGraph-Demi) /Bookman 0] + [(Marigold) /ZapfChancery-MediumItalic 0] + [(MonaLisa-Recut) /Palatino 0] % inappropriate + [(Monaco) /Courier 2] % should be fixed-pitch sans demi + [(Optima) /Helvetica 0] + [(Oxford) /ZapfChancery-MediumItalic 0] + [(Tekton) /Helvetica 0] + [(Univers) /Helvetica 0] +] readonly def +/.substituteproperties [ + [(It) 1] [(Oblique) 1] + [(Black) 2] [(Bd) 2] [(Bold) 2] [(bold) 2] [(Demi) 2] [(Heavy) 2] [(Sb) 2] + [(Cn) 4] [(Cond) 4] [(Narrow) 4] [(Pkg) 4] [(Compr) 4] + [(Serif) 8] [(Sans) -8] +] readonly def +/.fontnameproperties { % <int> <string|name> .fontnameproperties + % <int'> + .fontnamestring + .substituteproperties { + 2 copy 0 get search { + pop pop pop dup length 1 sub 1 exch getinterval 3 -1 roll exch { + dup 0 ge { or } { neg not and } ifelse + } forall exch + } { + pop pop + } ifelse + } forall pop +} bind def +/.substitutefamilies mark + /AvantGarde + {/AvantGarde-Book /AvantGarde-BookOblique + /AvantGarde-Demi /AvantGarde-DemiOblique} + /Bookman + {/Bookman-Demi /Bookman-DemiItalic /Bookman-Light /Bookman-LightItalic} + /Courier + {/Courier /Courier-Oblique /Courier-Bold /Courier-BoldOblique} + /Helvetica + {/Helvetica /Helvetica-Oblique /Helvetica-Bold /Helvetica-BoldOblique + /Helvetica-Narrow /Helvetica-Narrow-Oblique + /Helvetica-Narrow-Bold /Helvetica-Narrow-BoldOblique} + /NewCenturySchlbk + {/NewCenturySchlbk-Roman /NewCenturySchlbk-Italic + /NewCenturySchlbk-Bold /NewCenturySchlbk-BoldItalic} + /Palatino + {/Palatino-Roman /Palatino-Italic /Palatino-Bold /Palatino-BoldItalic} + /Symbol + {/Symbol /Symbol /Symbol /Symbol} + /Times + {/Times-Roman /Times-Italic /Times-Bold /Times-BoldItalic} + /ZapfChancery-MediumItalic + {/ZapfChancery-MediumItalic} +.dicttomark readonly def +/.nametostring { % <name> .nametostring <string> + % <other> .nametostring <other> + dup type /nametype eq { .namestring } if +} bind def +/.fontnamestring { % <fontname> .fontnamestring <string|name> + dup type dup /nametype eq { + pop .namestring + } { + /stringtype ne { pop () } if + } ifelse +} bind def +/.substitutefontname { % <fontname> <properties> .substitutefontname + % <altname|null> + % Look for properties and/or a face name in the font name. + % If we find any, use Times (serif) or Helvetica (sans) as the + % base font; otherwise, use the default font. + % Note that the "substituted" font name may be the same as + % the requested one; the caller must check this. + exch .fontnamestring { + defaultfontname /Helvetica-Oblique /Helvetica-Bold /Helvetica-BoldOblique + /Helvetica-Narrow /Helvetica-Narrow-Oblique + /Helvetica-Narrow-Bold /Helvetica-Narrow-BoldOblique + /Times-Roman /Times-Italic /Times-Bold /Times-BoldItalic + /Helvetica-Narrow /Helvetica-Narrow-Oblique + /Helvetica-Narrow-Bold /Helvetica-Narrow-BoldOblique + } 3 1 roll + % Stack: facelist properties fontname + % Look for a face name. + .substitutefaces { + 2 copy 0 get search { + pop pop pop + % Stack: facelist properties fontname [(pattern) family properties] + dup 2 get 4 -1 roll or 3 1 roll + 1 get .substitutefamilies exch get + 4 -1 roll pop 3 1 roll + } { + pop pop + } ifelse + } forall pop + 1 index length mod get exec +} bind def +/.substitutefont { % <fontname> .substitutefont <altname> + dup 0 exch .fontnameproperties .substitutefontname + % Only accept fonts known in the Fontmap. + Fontmap 1 index known not + { + .nativeFontmap 1 index known not + {pop defaultfontname } if + } if +} bind def + +% If requested, make (and recognize) fake entries in FontDirectory for fonts +% present in Fontmap but not actually loaded. Thanks to Ray Johnston for +% the idea behind this code. +FAKEFONTS not { (%END FAKEFONTS) .skipeof } if + +% We use the presence or absence of the FontMatrix key to indicate whether +% a font is real or fake. We must pop the arguments at the very end, +% so that stack protection will be effective. + +/definefont { % <name> <font> definefont <font> + dup /FontMatrix known { + //definefont + } { + 2 copy /FontName get findfont //definefont exch pop exch pop + } ifelse +} bind odef + +/scalefont { % <font> <scale> scalefont <font> + 1 index /FontMatrix known { + //scalefont + } { + 1 index /FontName get findfont 1 index //scalefont + exch pop exch pop + } ifelse +} bind odef + +/makefont { % <font> <matrix> makefont <font> + 1 index /FontMatrix known { + //makefont + } { + 1 index /FontName get findfont 1 index //makefont + exch pop exch pop + } ifelse +} bind odef + +/setfont { % <font> setfont - + dup /FontMatrix known { + //setfont + } { + dup /FontName get findfont //setfont pop + } ifelse +} bind odef + +%END FAKEFONTS + +% Define findfont so it tries to load a font if it's not found. +% The Red Book requires that findfont be a procedure, not an operator, +% but it still needs to restore the stacks reliably if it fails, +% so we do all the work in an operator. +/.findfont { % <fontname> .findfont <font> + mark 1 index % <fontname> mark <fontname> + //systemdict begin .dofindfont + % <fontname> mark <alias> ... <font> + % Define any needed aliases. + counttomark 1 sub { .aliasfont } repeat end + % <fontname> mark <font> + exch pop exch pop +} odef +/findfont { + .findfont +} bind def +% Check whether the font name we are about to look for is already on the list +% of aliases we're accumulating; if so, cause an error. +/.checkalias % -mark- <alias1> ... <name> .checkalias <<same>> + { counttomark 1 sub -1 1 + { index 1 index eq + { pop QUIET not + { (Unable to substitute for font.) = flush + } if + /findfont cvx /invalidfont signalerror + } + if + } + for + } bind def +% Get a (non-fake) font if present in a FontDirectory. +/.fontknownget % <fontdir> <fontname> .fontknownget <font> true + % <fontdir> <fontname> .fontknownget false + { .knownget + { FAKEFONTS + { dup /FontMatrix known { //true } { pop //false } ifelse } + { //true } + ifelse + } + { //false + } + ifelse + } bind def +% This is the standard procedure for handling font substitution. +% Its location is per an Adobe newsgroup posting. +% It is called with the font name on the stack, standing in for findfont. +/.stdsubstfont { % mark <alias1> ... <fontname> .stdsubstfont mark <alias1> ... <aliasN> <font> + /SUBSTFONT where { + pop QUIET not { + (Substituting for font ) print dup =only + (.) = flush + } if + % No aliasing. + % This mode is incompatible with high level devices. + cleartomark mark defaultfontname + } { + dup .substitutefont + 2 copy eq { pop defaultfontname } if + .checkalias + QUIET not { + SHORTERRORS { + (%%[) print 1 index =only + ( not found, substituting ) print dup =only (]%%) + } { + (Substituting font ) print dup =only + ( for ) print 1 index =only (.) + } ifelse = flush + } if + } ifelse + /Font findresource +} bind def + +% Default font substitution does {pop /Courier} om many implementations. +% GS post-process font substitution in .stdsubstfont and uses {} for +% backward compatibility +$error /SubstituteFont { } put + +% Scan the next directory on FONTPATH. +/.scannextfontdir { % - .scannextfontdir <bool> + % If we haven't scanned all the directories in + % FONTPATH, scan the next one. + //null 0 1 FONTPATH length 1 sub { + FONTPATH 1 index get //null ne { exch pop exit } if pop + } for dup //null ne { + dup 0 eq { .scanfontbegin } if + FONTPATH 1 index get .scanfontdir + FONTPATH exch //null put //true + } { + pop //false + } ifelse +} bind def +% Do the work of findfont, including substitution, defaulting, and +% scanning of FONTPATH. +/.dofindfont { % mark <fontname> .dofindfont % mark <alias> ... <font> + .tryfindfont not { + + % We didn't find the font. If we haven't scanned + % all the directories in FONTPATH, scan the next one + % now and look for the font again. + .scannextfontdir { + % Start over with an empty alias list. + counttomark 1 sub { pop } repeat % mark <fontname> + .dofindfont + } { + % No more directories to scan. Try building the native + % font map entries if we haven't already done so. + .buildnativefontmap { + % Same stack as at the beginning of .dofindfont. + .dofindfont % start over + } { + % No luck. Make sure we're not already + % looking for the default font. + QUIET not { + (Didn't find this font on the system!\n) + print + } if + dup defaultfontname eq { + QUIET not { + (Unable to load default font ) print + dup =only (! Giving up.) = flush + } if + /findfont cvx /invalidfont signalerror + } if + % Substitute for the font. Don't alias. + % Same stack as at the beginning of .dofindfont. + $error /SubstituteFont get exec + % + % igorm: I guess the surrounding code assumes that .stdsubstfont + % must ADD an alias to allow .checkalias and .findfont to work properly. + % Also I guess that a trailing recursion is + % used in .dofindfont and through .stdsubstfont + % just to represent a simple iteration, + % which accumulates the aliases after the mark. + .stdsubstfont + } ifelse + } ifelse + } if +} bind def +% Try to find a font using only the present contents of Fontmap. +/.tryfindfont { % <fontname> .tryfindfont <font> true + % <fontname> .tryfindfont false + .FontDirectory 1 index .fontknownget + { % Already loaded + exch pop //true + } + { + dup Fontmap exch .knownget + { //true //true } + { % Unknown font name. Look for a file with the + % same name as the requested font. + dup .tryloadfont + { exch pop //true //false } + { + % if we can't load by name check the native font map + dup .nativeFontmap exch .knownget + { //true //true } + { //false //false } ifelse + } ifelse + } ifelse + + { % Try each element of the Fontmap in turn. + pop + //false exch % (in case we exhaust the list) + % Stack: fontname false fontmaplist + { exch pop + dup type /nametype eq + { % Font alias + .checkalias .tryfindfont exit + } + { dup dup type dup /arraytype eq exch /packedarraytype eq or exch xcheck and + { % Font with a procedural definition + exec % The procedure will load the font. + % Check to make sure this really happened. + .FontDirectory 1 index .knownget + { exch pop //true exit } + if + } + { % Font file name + //true .loadfontloop { //true exit } if + } + ifelse + } + ifelse //false + } + forall + % Stack: font true -or- fontname false + { //true + } + { % None of the Fontmap entries worked. + % Try loading a file with the same name + % as the requested font. + .tryloadfont + } + ifelse + } + if + } + ifelse + } bind def + +% any user of .putgstringcopy must use bind and executeonly +/.putgstringcopy % <dict> <name> <string> .putgstringcopy - +{ 2 index gcheck currentglobal + 2 copy eq { + pop pop .forceput + } { + 5 1 roll setglobal + dup length string copy + .forceput setglobal + } ifelse +} .bind odef % must be bound and hidden for .forceput + +% Attempt to load a font from a file. +/.tryloadfont { % <fontname> .tryloadfont <font> true + % <fontname> .tryloadfont false + dup .nametostring + % Hack: check for the presence of the resource machinery. + /.genericrfn where { + pop + pop dup .fonttempstring /FontResourceDir getsystemparam .genericrfn + {//false .loadfontloop} .internalstopped {//false} if { + //true + } { + dup .nametostring + {//true .loadfontloop} .internalstopped {//false} if + } ifelse + } { + {//true .loadfontloop} .internalstopped {//false} if + } ifelse +} bind def + +/.loadfontloop { % <fontname> <filename> <libflag> .loadfontloop + % <font> true + % -or- + % <fontname> false + % See above regarding the use of 'loop'. + { % Is the font name a string? + 1 index type /stringtype ne + { pop + QUIET not + { (Can't find font with non-string name: ) print dup =only (.) = flush + } + if pop //false exit + } if + + % check <libflag> + { + findlibfile not + } { + dup (r) { file } stopped { + pop pop //true + } { + //false + } ifelse + } ifelse { + QUIET not + { (Can't find \(or can't open\) font file ) print dup print + (.) = flush + } + if pop //false exit + } if + % Stack: fontname fontfilename fontfile + DISKFONTS + { .currentglobal //true .setglobal + 2 index (r) file + FontFileDirectory exch 5 index exch .growput + .setglobal + } + if + QUIET not + { (Loading ) print 2 index =only + ( font from ) print 1 index print (... ) print flush + } + if + % If LOCALFONTS isn't set, load the font into local or global + % VM according to FontType; if LOCALFONTS is set, load the font + % into the current VM, which is what Adobe printers (but not + % DPS or CPSI) do. + LOCALFONTS { //false } { /setglobal where } ifelse + { pop /FontType .findfontvalue { 1 eq } { //false } ifelse + % .setglobal, like setglobal, aliases FontDirectory to + % GlobalFontDirectory if appropriate. However, we mustn't + % allow the current version of .setglobal to be bound in, + % because it's different depending on language level. + .currentglobal exch /.setglobal .systemvar exec + % Remove the fake definition, if any. + .FontDirectory 3 index .forceundef % readonly + 1 index (r) file .loadfont .FontDirectory exch + /.setglobal .systemvar exec + } + { .loadfont .FontDirectory + } + ifelse + % Stack: fontname fontfilename fontdirectory + QUIET not + { //systemdict /level2dict known + { .currentglobal //false .setglobal vmstatus + //true .setglobal vmstatus 3 -1 roll pop + 6 -1 roll .setglobal 5 + } + { vmstatus 3 + } + ifelse { =only ( ) print } repeat + (done.) = flush + } if + + % Check to make sure the font was actually loaded. + dup 3 index .fontknownget + { dup /PathLoad 4 index //.putgstringcopy exec + 4 1 roll pop pop pop //true exit + } if + + % Maybe the file had a different FontName. + % See if we can get a FontName from the file, and if so, + % whether a font by that name exists now. + exch dup % Stack: origfontname fontdirectory path path + (r) file .findfontname + { % Stack: origfontname fontdirectory path filefontname + 2 index 1 index .fontknownget + { % Yes. Stack: origfontname fontdirectory path filefontname fontdict + dup 4 -1 roll /PathLoad exch //.putgstringcopy exec + % Stack: origfontname fontdirectory filefontname fontdict + 3 -1 roll pop + % Stack: origfontname filefontname fontdict + dup /FontName get dup FontDirectory exch .forceundef + GlobalFontDirectory exch .forceundef + dup length dict .copydict dup 3 index /FontName exch put + 2 index exch definefont + exch + QUIET + { pop + } + { (Using ) print =only + ( font for ) print 1 index =only + (.) = flush + } + ifelse % Stack: origfontname fontdict + exch pop //true exit + % Stack: fontdict + } + if pop % Stack: origfontname fontdirectory path + } + if pop pop % Stack: origfontname + + % The font definitely did not load correctly. + QUIET not + { (Loading ) print dup =only + ( font failed.) = flush + } if + //false exit + + } loop % end of loop + + } bind executeonly def % must be bound and hidden for .putgstringcopy + +currentdict /.putgstringcopy .undef + +% Define a procedure to load all known fonts. +% This isn't likely to be very useful. +/loadallfonts +{ + [Fontmap .nativeFontmap] { { pop findfont pop } forall } forall +} bind def + +% If requested, load all the fonts defined in the Fontmap into FontDirectory +% as "fake" fonts i.e., font dicts with only FontName and FontType defined. +% (We define FontType only for the sake of some questionable code in the +% Apple Printer Utility 2.0 font inquiry code.) +% +% Note that this procedure only creates fake fonts in the FontDirectory +% associated with the current VM. This is because in multi-context systems, +% creating the fake fonts in local VM leads to undesirable complications. +/.definefakefonts + { + } + { + (gs_fonts FAKEFONTS) VMDEBUG + [Fontmap .nativeFontmap ] + { + { + pop dup type /stringtype eq { cvn } if + .FontDirectory 1 index known not { + 2 dict dup /FontName 3 index put + dup /FontType 1 put + .FontDirectory 3 1 roll { put } //superexec % readonly + } { + pop + } ifelse + } forall + } forall + } +FAKEFONTS { exch } if pop def % don't bind, .current/setglobal get redefined + +% Install initial fonts from Fontmap. +/.loadinitialfonts + { NOFONTMAP not + { /FONTMAP where + { pop [ FONTMAP .pathlist ] + { dup VMDEBUG findlibfile + { exch pop .loadFontmap } + { /undefinedfilename signalerror } + ifelse + } + } + { LIBPATH + { defaultfontmap + //false .file_name_combine + { + dup VMDEBUG + (r) { file } .internalstopped { + pop pop + defaultfontmap_content { .definefontmap } forall + } { + .loadFontmap + } ifelse + } { + pop pop + } ifelse + } + } + ifelse forall + } + if + userdict /defaultfontmap_content .undef + .definefakefonts % current VM is global + } def % don't bind, .current/setglobal get redefined + +% ---------------- Synthetic font support ---------------- % + +% Create a new font by modifying an existing one. paramdict contains +% entries with the same keys as the ones found in a Type 1 font; +% it should also contain enough empty entries to allow adding the +% corresponding non-overridden entries from the original font dictionary, +% including FID. If paramdict includes a FontInfo entry, this will +% also override the original font's FontInfo, entry by entry; +% again, it must contain enough empty entries. + +% Note that this procedure does not perform a definefont. + +/.makemodifiedfont % <fontdict> <paramdict> .makemodifiedfont <fontdict'> + { exch + { % Stack: destdict key value + 1 index /FID ne + { 2 index 2 index known + { % Skip fontdict entry supplied in paramdict, but + % handle FontInfo specially. + 1 index /FontInfo eq + { 2 index 2 index get % new FontInfo + 1 index % old FontInfo + { % Stack: destdict key value destinfo key value + 2 index 2 index known + { pop pop } + { 2 index 3 1 roll put } + ifelse + } + forall pop + } + if + } + { % No override, copy the fontdict entry. + 2 index 3 1 roll put + dup dup % to match pop pop below + } + ifelse + } + if + pop pop + } forall + } bind def + +% Make a modified font and define it. Note that unlike definefont, +% this does not leave the font on the operand stack. + +/.definemodifiedfont % <fontdict> <paramdict> .definemodifiedfont - + { .makemodifiedfont + dup /FontName get exch definefont pop + } bind def diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_frsd.ps b/Master/tlpkg/tlgs/Resource/Init/gs_frsd.ps new file mode 100644 index 00000000000..e815169c6a0 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_frsd.ps @@ -0,0 +1,80 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Implementation of ReusableStreamDecode filter. +% This file must be loaded after gs_lev2.ps and gs_res.ps. + +level2dict begin + +% ------ ReusableStreamDecode filter ------ % + +/.reusablestreamdecode { % <source> <dict> .reusablestreamdecode <file> + % <source> .reusablestreamdecode <file> + % Collect the filter parameters. + dup type /dicttype eq { 2 copy } { dup 0 dict } ifelse + dup .rsdparams + % Construct the filter pipeline. + % The very first filter should use the value of CloseSource + % from the RSD dictionary; all the others should have + % CloseSource = true. + % Stack: source dict filters parms + 2 index /CloseSource .knownget not { //false } if 5 -1 roll + % Stack: dict filters parms CloseSource source + 0 1 5 index length 1 sub { + 4 index 1 index get + % Stack: dict filters parms CloseSource source index filtname + 4 index //null eq { + 0 dict + } { + 4 index 2 index get dup //null eq { pop 0 dict} if + } ifelse + 3 -1 roll pop exch filter + exch pop //true exch % set CloseSource for further filters + } for + % If AsyncRead is true, try to create the filter directly. + % Stack: dict filters parms CloseSource source + 4 index /AsyncRead .knownget not { //false } if { + 1 index { .reusablestream } .internalstopped + } { + //null //true + } ifelse { + pop + % No luck. Read the entire contents of the stream now. + dup type /filetype ne { + % Make a stream from a procedure or string data source. + 0 () .subfiledecode + } if + % We must allocate the string in the same VM space as its + % source, since the reusable stream must be allocated there. + + .currentglobal 1 index gcheck .setglobal exch + currentpacking //false setpacking exch + % Stack: dict filters parms CloseSource oldglobal oldpacking file + [ exch { dup 40000 string readstring not { exit } if exch } loop + exch pop + ] + % Stack: dict filters parms CloseSource oldglobal oldpacking [()...] + 3 1 roll setpacking setglobal + % Stack: dict filters parms CloseSource [()...] + 1 index .reusablestream + } if + % We created the stream successfully: clean up. + 4 { exch pop } repeat + 1 index type /dicttype eq { exch pop } if exch pop +} odef + +filterdict /ReusableStreamDecode /.reusablestreamdecode load put + +end % level2dict diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_icc.ps b/Master/tlpkg/tlgs/Resource/Init/gs_icc.ps new file mode 100644 index 00000000000..8f42ea69731 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_icc.ps @@ -0,0 +1,109 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% We need LanguageLevel 2 or higher in order to have setuserparams and +% << >> dictionaries +languagelevel dup 2 .max .setlanguagelevel + +% ICCBased color space method dictionaries. +% This assumes gs_ciecs2.ps has already been processed. + +.currentglobal //true .setglobal + +% gs_res.ps uses these entries in colorspacedict +% to populate the ColorSpaceFamily resource, so we need +% to add the supported spaces. +% +systemdict /colorspacedict get begin +/ICCBased [] def +end + +NOPSICC { (%END PSICC) .skipeof } if +% Now set up ICC profile loading for PostScript %%BeginICCProfile sections. + +/cs-sig-dict << + (XYZ ) 3 + (Lab ) 3 + (Luv ) 3 + (YCbr) 3 + (Yxy ) 3 + (RGB ) 3 + (GRAY) 1 + (HSV ) 3 + (HLS ) 3 + (CMYK) 4 + (CMY ) 3 +>> readonly def + +systemdict begin +/.ProcessICCcomment { % file comment -- file comment + dup + (%%BeginICCProfile) anchorsearch { + pop pop + DEBUG { (.ProcessICCcomment found %%BeginICCProfile) print flush } if + + % load an ICC profile defined as comments (hex encoded). + % Ends with %%End at the start of a line. Read the data into + % an array of strings. This string can be used directly as a + % source for ReusableStreamDecode filter. + % + % stack: --file-- (%%BeginICCProfile: ...) + 1 index 0 (%%EndICCProfile) /SubFileDecode filter + [ { counttomark 1 add index + 64000 string readhexstring + not { exit } if + } loop + ] exch closefile + + % make a seekable -file- out of the string array + mark /AsyncRead //true .dicttomark /ReusableStreamDecode filter + % stack: --file-- (%%BeginICCProfile: ...) --icc_subfile-- + + dup 16 setfileposition + dup (1234) readstring pop + 1 index 0 setfileposition + + //cs-sig-dict exch .knownget { + 3 dict begin + /Alternate {0 /DeviceGray 0 /DeviceRGB /DeviceCMYK } 2 index get def + /N exch def + /DataSource exch def + [/ICCBased currentdict] + end + { setcolorspace } stopped { + pop + QUIET not { ( *** Unable to load ICC profile from PostScript DSC comments ***) = flush } if + } if + } { + pop + } ifelse + } { + pop % Not interested in this DSC comment + } ifelse +} bind def + +currentdict /cs-sig-dict undef + +% Merge ProcessICCcomment with existing handler +/.ProcessICCcomment load /exec load +currentuserparams /ProcessDSCComment get +dup //null eq {pop {pop pop}} if /exec load +4 array astore cvx readonly +<< /ProcessDSCComment 3 -1 roll >> setuserparams + +end % systemdict +%END PSICC +.setglobal +.setlanguagelevel diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_il1_e.ps b/Master/tlpkg/tlgs/Resource/Init/gs_il1_e.ps new file mode 100644 index 00000000000..8014b8fb544 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_il1_e.ps @@ -0,0 +1,65 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Define the ISO Latin-1 encoding vector. +% The first half is the same as the standard encoding, +% except for minus instead of hyphen at code 055. +/ISOLatin1Encoding +StandardEncoding 0 45 getinterval aload pop + /minus +StandardEncoding 46 82 getinterval aload pop +% NOTE: the following are missing in the Adobe documentation, +% but appear in the displayed table: +% macron at 0225, dieresis at 0230, cedilla at 0233, space at 0240. +% This is an error in the Red Book, corrected in Adobe TN 5085. +% \20x + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent + /dieresis /.notdef /ring /cedilla /.notdef /hungarumlaut /ogonek /caron +% \24x + /space /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot /hyphen /registered /macron + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% \30x + /Agrave /Aacute /Acircumflex /Atilde + /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% \34x + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +% Make an array on large systems, a packed array on small ones. +256 +vmstatus exch pop exch pop +100000 ge { array astore readonly } { packedarray } ifelse +def +1 ISOLatin1Encoding .registerencoding +/ISOLatin1Encoding ISOLatin1Encoding .defineencoding diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_img.ps b/Master/tlpkg/tlgs/Resource/Init/gs_img.ps new file mode 100644 index 00000000000..f2b0f6287da --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_img.ps @@ -0,0 +1,864 @@ +% (C) 2002 Artifex, 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. +% +% 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. + +% image, colorimage, and imagemask implementation + +% +% The design of the overprint facility in Ghostscript requires that color +% specifications include the color space from which they were expressed, +% even after conversion to the device color model. Directly including this +% information in color specifications is usually not efficient, and is +% difficult to integrate into the existing code structure. The alternative +% approach taken is to extend a state mechanism through the device +% interface, and make the current color space, or more specifically, +% certain information about the current color space, a property of this +% state. +% +% For such a mechanism to work, it is necessary to identify all changes +% to the current color space. This is accomplished in the graphic library +% by funneling all changes to the current color space through the +% gs_setcolorspace procedure. At the PostScript interpreter level, this +% result is achieved by forcing color space changes through the +% setcolorspace operator. +% +% Aside from explicit use of setcolorspace, PostScript provides a few +% implicit methods of changing the current color space. The setgray, +% setrgbcolor, and setcmykcolor operators implicitly set the color space +% while explicitly setting the current color. Similarly, the colorimage +% operator and the traditional form of the image operator (5 operands) +% both temporarily modify the current color space while an image is +% being processed. The current file is concerned with the implementation +% of these two operators. In addition, the traditional form of the +% imagemask operator (5 operands), while it does not affect the current +% color space, is closely related to the image operator and thus is +% implemented in this file as well. +% +% In this implementation, all sampled objects are passed through one of +% the internal operators .image1, .imagemask1, .image1alpha, .image2, +% .image3, or .image4, each of which handles a specific ImageType value. +% +% The procedures in this file are responsible for constructing +% image dictionaries from a set of stack entries. This is, in principle, +% a trivial exercise. In practice it appears to be far more complex, +% primarily due to the need to reconstruct the original state in the +% event of an error. This is a particular problem for operators such as +% image, which include data source objects that may, directly or +% indirectly, be procedures. When these procedures are executed, the +% image operator's operands must have been cleared from the operand +% stack. Hence, the operand stack cannot be used to store state +% information. Similarly, the dictionary stack also cannot be used to +% store state information, as the data source procedures may depend on +% a particular dictionary being on the top of this stack. +% +% Adobe's PostScript implementations determine the extent to which the +% interpreter state is restored in the event of an error by the point at +% which the error is detected. Errors in the image/colorimage/imagemask +% operators that are detected before the data source procedures are +% executed restore the state in effect before the image was processed. +% Those that are detected as part of running the data source procedures +% only attempt to restore the state to that in effect at the start of +% the operator that failed (or at the conclusion of the data source +% procedure, if this procedure failed to push a string). +% +% The implementation given here follows the Adobe convention. The +% mechanism used is as follows: +% +% 1. Check that the stack has a sufficient number of operands, and +% that enough of them have the proper type to allow construction +% of the image dictionary. Any errors at this point are handled +% in the conventional manner. +% +% 2. Build the image dictionary, in the process clearing the image/ +% colorimage/imagemask operands from the stack. No errors can +% occur during this process. +% +% (Special precautions could be taken during this step to handle +% a limitcheck or VMError during the building of the image +% dictionary, but this essentially never occurs in practice and, if +% it did, is very unlikely to leave a useable state. Hence, we don't +% bother with this possibility.) +% +% 3. The .image operator is executed in a stopped context. If it +% returns abnormally, a check is made to see if the uppermost +% operand on the stack is a color image dictionary. If so, the +% original stack is created anew using this dictionary. (Because +% the image operand works via colorimage, some additional special +% handling is required in this case.) +% + +% +% Create a dictionary of operators for specific image and image mask types. +% Each of these will always handle ImageType 1. Additional types are added +% as they are supported in specific interpreter levels or versions. +% +% These dictionaries are in systemdict for historical reasons. +% +.currentglobal //true .setglobal +systemdict begin +/.imagetypes + 5 dict + dup 1 /.image1 load put +def +/.imagemasktypes + 5 dict + dup 1 /.imagemask1 load put +def +end +.setglobal + +% +% Build a dictionary of utility procedures and constants for use in +% impelementing the image operators. This dictionary is in global VM but +% is maintained (during initialization) in userdict. It should be pushed +% onto the dictionary stack when constructing image-related procedures +% and pseudo-operators. +% +% This dictionary is removed from userdict when initialization is +% completed. +% +.currentglobal //true .setglobal +userdict /img_utils_dict 30 dict put +img_utils_dict begin + +% +% Some useful local data structures: +% +% img_csary maps the number of components in an image to the implied +% color space. +% +% img_decary is a prototype Decode array; subintervals of this array +% may be used for fewer than 4 color components. +% +% img_params_ary is a list of the parameters to be built in the image +% dictionary for a colorimage invocation. ImageType is given a +% fixed value; the other parameters are in stack order (IMG_NComps +% is the number of components). +% +% img_mask_params_ary is the equivalent of img_params_ary for imagemask +% invocations. Polarity is a proxy for Decode, and is replaced +% by the Decode key in the image dictionary. +% +% img_mask_check_ary is the set of parameters that must be present in +% an image dictionary generated by an imagemask invocation. This +% differs from img_mask_params_ary in that Decode replaces Polarity. +% +/img_csary [ //null /DeviceGray //null /DeviceRGB /DeviceCMYK ] def +/img_decary [ 0 1 0 1 0 1 0 1 ] def + +/img_params_ary + [ + /ImageType /IMG_NComps /MultipleDataSources /DataSource + /ImageMatrix /BitsPerComponent /Height /Width /Decode + ] +def +/img_check_ary //img_params_ary def +/img_unbuild_ary + //img_params_ary 1 1 index length 2 sub getinterval +def + +/img_mask_params_ary + [ /ImageType /DataSource /ImageMatrix /Polarity /Height /Width ] +def +/img_mask_check_ary + [ + /ImageType /BitsPerComponent + /DataSource /ImageMatrix /Decode /Height /Width + ] +def +/img_mask_unbuild_ary + //img_mask_check_ary 2 1 index length 2 sub getinterval +def + +% +% <?any?> <array> img_check_keys <?any?> <bool> +% +% Verify that: +% that there are at least two entries on the stack, and +% the second (lower) entry is a dictionary, and +% that dictionary contains all of the keys in the array +% +% If any one of these conditions does not hold, pop the array and push +% false; otherwise pop the array and push true. This utility is used by +% the colorimage and imagematrix procedures to determine if .image left +% the image dictionary on the stack after an abnormal return. +% +/img_check_keys + { + count 2 ge + { + 1 index type /dicttype eq + { + //true exch + { + 2 index exch known and + dup not + { exit } + if + } + forall + } + { pop //false } + ifelse + } + { pop //false } + ifelse + } +.bind def + +% +% Procedures to convert a set of stack entries to a dictionary. There is +% a procedure associated with each key, though most keys use the same +% procedure. The dictionary to be built is at the top of the dictionary +% stack. Stack handling for the procedures is: +% +% <?val0?> ... <?val(n - 1)?> <key> proc - +% +% Parameters are handle in inverse-stack order, so inter-parameter +% dependencies that on the stack can generally be used here. +% +/img_params_dict + mark + /ImageType { 1 def } .bind + + /IMG_NComps { exch def } .bind % number of components + /MultipleDataSources 1 index + /Width 1 index + /Height 1 index + /ImageMatrix 1 index + /BitsPerComponent 1 index + /DataSource 1 index + + % Polarity is a proxy for Decode; it never appears in a dictionary + /Polarity + { + pop + { { 1 0 } } + { { 0 1 } } + ifelse + /Decode exch cvlit def + } + .bind + + % the definition of Decode is based on the number of components + /Decode { //img_decary 0 IMG_NComps 2 mul getinterval def } .bind + .dicttomark +def + +% +% <oper_0> ... <oper_n> <array> img_build_dict <dict> +% +% Build a dictionary. This will always be done in local VM. The array is +% a list of the keys to be associated with operands on the stack, in +% inverse stack order (topmost element first). The caller should verify +% that the dictionary can be built successfully (except for a possible +% VMerror) before calling this routine. +% +/img_build_dict + { + % build the dictionary in local VM; all for 2 extra entries + .currentglobal //false .setglobal + 1 index length 2 add dict + exch .setglobal + begin + + % process all keys in the array + { //img_params_dict 1 index get exec } + forall + + % if BitsPerComponent is not yet defined, define it to be 1 + currentdict /BitsPerComponent known not + { /BitsPerComponent 1 def } + if + + currentdict end + } +.bind def + +% +% <dict> <array> img_unbuild_dict <oper_0> ... <oper_n> +% +% "Unbuild" a dictionary: spread the contents the dictionary back onto the +% stack, in the inverse of the order indicated in the array (inverse is +% used as this order is more convenient for img_build_dict, which is +% expected to be invoked far more frequently). +% +/img_unbuild_dict + { + exch begin + dup length 1 sub -1 0 + { 1 index exch get load exch } + for + pop + end + } +.bind def + +% +% Check the image types that can be used as data sources +% <any> foo <bool> +% +/good_image_types mark + /filetype { pop //true } .bind + /stringtype 1 index + /arraytype //xcheck + /packedarraytype //xcheck +.dicttomark readonly def + +% +% <width> <height> <bits/component> <matrix> <dsrc0> ... +% <multi> <ncomp> <has_alpha> +% img_build_image_dict +% <dict> <has_alpha> +% +% Build the dictionary corresponding to a colorimage operand stack. This +% routine will check just enough of the stack to verify that the +% dictionary can be built, and will generate the appropriate error if this +% is not the case. +% +% The <has_alpha> boolean is used to support the Next alphaimage extension. +% +% At the first level, errors in this procedure are reported as colorimage +% errors. The error actually reported will usually be determined by the +% pseudo-operator which invokes this routine. +% +/img_build_image_dict + { + % Veify that at least 8 operands are available, and that the top three + % operands have the expected types + count 8 lt + { /.colorimage cvx /stackunderflow signalerror } + if + 3 copy + type /booleantype ne exch + type /integertype ne or exch + type /booleantype ne or + { /.colorimage cvx /typecheck signalerror } + if + + % verify that the number of components is 1, 3, or 4 + 1 index 1 lt 2 index 2 eq or 2 index 4 gt or + { /.colorimage cvx /rangecheck signalerror } + if + + % Verify that the required number of operands are present if multiple + % data sources are being used. If this test is successful, convert + % the data sources to an array (in local VM). + 2 index + { + % if an alpha component is present, this adds one more component + 2 copy + { 1 add } + if + dup count 9 sub gt + { + % Adobe interpreters appear to test the arguments sequentially + % starting from the top of the stack and report the 1st error found. + % To satisfy CET test 12-02.PS we emulate this logic. + //true exch -1 1 + { 3 add index + //good_image_types 1 index type .knownget + { exec and + } + { pop pop //false + } + ifelse + } + for + { /stackunderflow + } + { /typecheck + } + ifelse + /.colorimage cvx exch signalerror + } + if + + % build the DataSource array in local VM + dup .currentglobal //false .setglobal exch array exch .setglobal + + % stack: <w> <h> <bps> <mtx> <d0> ... <multi> <n> <alpha> <n'> <array> + 5 1 roll 4 add 3 roll astore 4 1 roll + } + if + + % the image dictionary can be built; do so + % stack: <w> <h> <bps> <mtx> <dsrc|dsrc_array> <multi> <n> <alpha> + 8 1 roll //img_params_ary //img_build_dict exec exch + } +.bind def +currentdict /good_image_types .undef + +% +% <?dict?> +% img_unbuild_image_dict +% <width> <height> <bits/component> <matrix> <dsrc0> ... +% <multi> <ncomp> +% +% If the top entry of the stack is a dictionary that has the keys required +% by a colorimage dictionary, unpack that dictionary onto the stack. +% Otherwise just leave things as they are. Note that the <has_alpha> +% parameter is not pushd onto the stack. +% +/img_unbuild_image_dict + { + //img_check_ary //img_check_keys exec + { + //img_unbuild_ary //img_unbuild_dict exec + 1 index type /booleantype eq + { + 1 index + { 3 -1 roll aload length 2 add -2 roll } + if + } + if + } + if + } +.bind def + +% +% <width> <height> <polarity> <matrix> <dsrc> +% img_unbuild_imagemask_dict +% <dict> +% +% Build the dictionary corresponding to an imagemask stack. This routine +% will verify that the appropriate number of operands are on the stack, +% and that polarity is a boolean. This is all that is necessary to build +% the dictionary. +% +/img_build_imagemask_dict + { + % check for proper number of operands + count 5 lt + { /imagemask .systemvar /stackunderflow signalerror } + if + + % verify that polarity is a boolean + 2 index type /booleantype ne + { /imagemask .systemvar /typecheck signalerror } + if + + % the imagemask dictionary can be built; do so + //img_mask_params_ary //img_build_dict exec + } +.bind def + +% +% <?dict?> +% img_unbuild_imagemask_dict +% <width> <height> <polarity> <matrix> <dsrc> +% +% If the top entry of the stack is a dictionary that has the keys rquired +% by an imagemask dictionary, unpack that dictionary onto the stack. +% Otherwise just leave things as they are. +% +/img_unbuild_imagemask_dict + { + //img_mask_check_ary //img_check_keys exec + { + //img_mask_unbuild_ary //img_unbuild_dict exec + 3 -1 roll + dup type dup /arraytype eq exch /packedarraytype eq or + 1 index rcheck and + { 0 get 1 eq } + if + 3 1 roll + } + if + } +.bind def + +% +% <width> <height> <bits/component> <matrix> <dsrc_0> ... +% <multi> <ncomp> <has_alpha> +% .colorimage +% - +% +% Convert the image/colorimage operator from their traditional form to +% the dictionary form. The <has_alpha> operand is used ot support the +% Next alphaimage extension. +% +% Error handling for these operators is a bit complex, due to the stack +% handling required of operators that potentially invoke procedures. +% This problem is discussed in the comment above. The facts relevant to +% this particular implementation are: +% +% 1. The .image1 (or .alphaimage) operator is executed in a stopped +% context, so that we can undo the gsave context in the event of +% an error. +% +% 2. In the event of an error, the stack is examined to see if the +% dictionary passed to .image1 (.alphaimage) is still present. +% If so, this dictionary is "unpacked" onto the stack to re- +% create the original stack. The <has_alpha> parameter is not +% pushed onto the stack, as it is not required for any of the +% pseudo-operators than invoke this procedure. +% +% 3. The use of pseudo-operators in this case may yield incorrect +% results for late-detected errors, as the stack depth will be +% restored (even though the stack is not). This is, however, no +% worse than the prior (level >= 2) code, so it should cause no +% new problems. +% +/.colorimage + { + % build the image dictionary + //img_build_image_dict exec + + % execute .image1 in a stopped context + { + gsave + % The CET test file 12-02.ps creates colorimages with a width and + % height of 0. Ignore these since that is what the CET expects. + 1 index dup /Height get 0 eq exch /Width get 0 eq or + { pop pop } % Ignore colorimage. Pop bool and dict + { + 0 .setoverprintmode % disable overprint mode for images + //img_csary 2 index /IMG_NComps get get setcolorspace + { .alphaimage } + { .image1 } + ifelse + } + ifelse + } + stopped + grestore + { + //img_unbuild_image_dict exec + /.colorimage cvx $error /errorname get + signalerror + } + if + } +.bind def + +% +% <width> <height> <bits/component> <matrix> <dsrc_0> ... +% <multi> <ncomp> +% colorimage +% - +% +% Build the colorimage pseudo-operator only if setcolorscreen is visible. +% +systemdict /setcolorscreen .knownget + { + type /operatortype eq + { + /colorimage + { + //false + //.colorimage + stopped + { /colorimage .systemvar $error /errorname get signalerror } + if + } + .bind systemdict begin odef end + } + if + } +if + +% +% width height bits_per_component matrix data_src image - +% +% <dict> image - +% +% Some special handling is required for ImageType 2 (Display PostScript +% pixmap images) so as to set the appropriate color space as the current +% color space. +% +/image + { + dup type /dicttype eq .languagelevel 2 ge and + { + dup /ImageType get dup 2 eq + { + % verify the ImageType 2 is supported + //.imagetypes exch known + { + % + % Set either DevicePixel or DeviceRGB as the current + % color space. DevicePixel is used if the image data is + % to be copied directly, with only a geometric + % transformation (PixelCopy true). The use of DeviceRGB + % in the alternate case is not, in general, correct, and + % reflects a current implementation limitation. Ideally, + % an intermediate color space should be used only if + % the source and destination color models vary; otherwise + % the native color space corresponding to the color model + % should be used. + % + % The mechanism to determine depth for the DevicePixel + % color space when BitsPerPixel is not available is + % somewhat of a hack. + % + gsave + 0 .setoverprintmode % disable overprintmode for images + dup /PixelCopy .knownget dup + { pop } + if + { + [ + /DevicePixel + currentpagedevice dup /BitsPerPixel .knownget + { exch pop } + { + /GrayValues .knownget not + { 2 } % try a guess + if + ln 2 ln div round cvi + } + ifelse + ] + } + { /DeviceRGB } + ifelse + setcolorspace + //.imagetypes 2 get + stopped + grestore + { /image .systemvar $error /errorname get signalerror } + if + } + { /image .systemvar /rangecheck signalerror + } + ifelse + } + { + dup //.imagetypes exch .knownget + { + exch pop gsave + 0 .setoverprintmode % disable overprintmode for images + stopped + grestore + { /image .systemvar $error /errorname get signalerror } + if + } + { + /image .systemvar exch type /integertype eq + { /rangecheck } { /typecheck } + ifelse signalerror + } + ifelse + } + ifelse + } + { + //false 1 //false + //.colorimage + stopped + { /image .systemvar $error /errorname get signalerror } + if + } + ifelse + } +.bind systemdict begin odef end + +% An auxiliary function for checking whether an imagemask to be interpolated. +/.is_low_resolution % <image dict> .is_low_resolution <bool> +{ % Checking whether image pixel maps to more than 2 device pixels. + % The threshold 2 is arbitrary. + 1 exch 0 exch + 0 exch 1 exch + /ImageMatrix get dup + 2 { + 4 1 roll + idtransform dtransform dup mul exch dup mul add sqrt + } repeat + max + 2 gt % arbitrary +} .bind def + +% +% width height polarity matrix datasrc imagemask - +% +% See the comment preceding the definition of .colorimage for information +% as to the handling of error conditions. +% +/imagemask + { + dup type /dicttype eq .languagelevel 2 ge and + { dup /ImageType get + //.imagemasktypes exch .knownget + { 1 index //.is_low_resolution exec + 2 index /ImageType get 1 eq and + 2 index /BitsPerComponent get 1 eq and + 2 index /Interpolate .knownget not { //false } if and + //filterdict /ImscaleDecode known and + %% + %% Don't apply ImScaleDecode to interpolate imagemasks if + %% the current device is a high level device. + %% + /HighLevelDevice /GetDeviceParam .special_op { + exch pop not + }{ + //true + }ifelse + and + { + % Apply interpolated imagemask scaling filter + exch .currentglobal exch dup .gcheck .setglobal + dup length dict .copydict + dup dup /DataSource get + dup type /stringtype eq { + 1 array astore cvx % image.* operators read strings repeatesly + } if + mark /Width 3 index /Width get /Height 5 index /Height get .dicttomark + /ImscaleDecode filter /DataSource exch put + dup dup /Width get 4 mul /Width exch put + dup dup /Height get 4 mul /Height exch put + dup dup /ImageMatrix get + { 4 0 0 4 0 0 } matrix concatmatrix /ImageMatrix exch put + 3 1 roll .setglobal + } if + exec + } + { % CET 12-08b.ps wants /typecheck + /imagemask .systemvar /typecheck signalerror + } + ifelse + } + { + //img_build_imagemask_dict exec + { .imagemask1 } + stopped + { + //img_unbuild_imagemask_dict exec + /imagemask .systemvar $error /errorname get signalerror + } + if + } + ifelse + } +.bind systemdict begin odef end + +end % img_utils_dict + +% Conditionally turn image interpolation on or off. +% INTERPOLATE is not yet set, handle all cases +currentdict /INTERPOLATE known +currentdict /DOTERPOLATE known or +currentdict /NOTERPOLATE known or not { + currentfile 1 (%END INTERPOLATE) .subfiledecode flushfile +} if + +/.interpolate { + dup /Interpolate .knownget not { //false } if + /INTERPOLATE .systemvar ne { + dup gcheck .currentglobal exch .setglobal + exch dup length dict copy + dup /Interpolate /INTERPOLATE .systemvar put + exch .setglobal + } if +} .bind odef + +/colorimage + { /INTERPOLATE .systemvar + { .currentglobal % w h bit [] {}...{} multi ncomp glob + //false .setglobal + 9 dict begin % w h bit [] {}...{} multi ncomp glob + 2 .argindex { 1 index 7 add } { 8 } ifelse + dup .argindex pop % check # of arguments + copy gsave pop % preserve the arguments + { 0 /DeviceGray 0 /DeviceRGB /DeviceCMYK } + 1 index get setcolorspace % ... glob w h bit [] {}...{} multi ncomp + {0 1 0 1 0 1 0 1} + 1 index 2 mul 0 exch % ... glob w h bit [] {}...{} multi ncomp {0 1 ...} 0 2*ncomp + getinterval /Decode exch def % ... glob w h bit [] {}...{} multi ncomp + exch dup % ... glob w h bit [] {}...{} ncomp multi multi + /MultipleDataSources exch def % ... glob w h bit [] {}...{} ncomp multi + { array astore} { pop } ifelse % ... glob w h bit [] [{}...{}] + /DataSource exch def % ... glob w h bit [] + /ImageMatrix exch def % ... glob w h bit + /BitsPerComponent exch def % ... glob w h + /Height exch def % ... glob w + /Width exch def % ... glob + /ImageType 1 def + /Interpolate //true def + .setglobal currentdict end % ... <<>> + image grestore + exch { 4 add } { 6 } ifelse + { pop } repeat % - + } + { colorimage + } + ifelse + } .bind odef + +/image + { dup type /dicttype eq + { dup /ImageType get 3 eq + { .currentglobal //false .setglobal exch + dup length dict copy begin .setglobal + /DataDict DataDict .interpolate def + /MaskDict MaskDict .interpolate def + currentdict end + } + { .interpolate + } + ifelse + image + } + { /INTERPOLATE .systemvar + { 4 .argindex pop % check # of args + .currentglobal //false .setglobal + 8 dict begin .setglobal + /ImageType 1 def + /DataSource 1 index def + /ImageMatrix 2 index def + /BitsPerComponent 3 index def + /Decode {0 1} def + /Height 4 index def + /Width 5 index def + /Interpolate //true def + currentdict end + gsave /DeviceGray setcolorspace image grestore + 5 { pop } repeat + } + { image + } + ifelse + } + ifelse + } .bind odef + +/imagemask { + dup type /dicttype eq { + .interpolate imagemask + } { + /INTERPOLATE .systemvar { + 4 .argindex pop % check # of args + .currentglobal //false .setglobal + 8 dict begin .setglobal + /ImageType 1 def + /DataSource 1 index def + /ImageMatrix 2 index def + /BitsPerComponent 1 def + 2 index { {1 0} } { {0 1} } ifelse /Decode exch def + /Height 4 index def + /Width 5 index def + /Interpolate //true def + currentdict end imagemask 5 { pop } repeat + } { + imagemask + } ifelse + } ifelse +} .bind odef + +currentdict /.interpolate .undef + +%END INTERPOLATE + +.setglobal % restore VM mode diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_init.ps b/Master/tlpkg/tlgs/Resource/Init/gs_init.ps new file mode 100644 index 00000000000..ddde17115f4 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_init.ps @@ -0,0 +1,2261 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Initialization file for the interpreter. +% When this is run, systemdict is still writable. + +% Comment lines of the form +% %% Replace <n> <file(s)> +% indicate places where the next <n> lines should be replaced by +% the contents of <file(s)>, when creating a single merged init file. + +% The interpreter can call out to PostScript code. All procedures +% called in this way, and no other procedures defined in these +% initialization files, have names that begin with %, e.g., +% (%Type1BuildChar) cvn. + +% Interpreter library version number +% NOTE: the interpreter code requires that the first non-comment token +% in this file be an integer, and that it match the compiled-in version! +921 + +% Check the interpreter revision. +dup revision ne + { (gs: Interpreter revision \() print revision 10 string cvs print + (\) does not match gs_init.ps revision \() print 10 string cvs print + (\).\n) print flush //null 1 .quit + } +if pop + +% Acquire userdict, and set its length if necessary. +/userdict where + { pop userdict maxlength 0 eq } + { //true } +ifelse +systemdict exch + { % userdict wasn't already set up by iinit.c. + dup /userdict + currentdict dup 200 .setmaxlength % userdict + .forceput % userdict is local, systemdict is global + } +if begin + +% Define dummy local/global operators if needed. +systemdict /.setglobal known + { //true .setglobal + } + { /.setglobal { pop } bind def + /.currentglobal { //false } bind def + /.gcheck { pop //false } bind def + } +ifelse + +% Define .languagelevel if needed. +systemdict /.languagelevel known not { /.languagelevel 1 def } if + +% Optionally choose a default paper size other than U.S. letter. +% The default page size for many devices is set at compile time to +% letter, but this can be changed to A4 although this is rarely done. +% Some devices such as bbox have a different default page size, +% and should not be set to A4 or letter. +% When ghostscript is used in countries that use the international +% standard page size A4 rather than US letter, the page size of +% devices that default to letter or A4 can be changed by setting +% DEFAULTPAPERSIZE. +% /DEFAULTPAPERSIZE (a4) def + +% Turn on array packing for the rest of initialization. +//true setpacking + +% Define the old MS-DOS EOF character as a no-op. +% This is a hack to get around the absurd habit of MS-DOS editors +% of adding an EOF character at the end of the file. +<1a> cvn { } def + +% Acquire the debugging flags. +currentdict /DEBUG known /DEBUG exch def + +% if DEBUG is set, set ALL of the subset debugging flags +mark % '[' isn't defined yet + /CCFONTDEBUG % Compiled Fonts + /CFFDEBUG % CFF Fonts + /CMAPDEBUG % CMAP + /DOCIEDEBUG % CIE color + /EPSDEBUG % EPS handling + /FAPIDEBUG % Font API + /INITDEBUG % Initialization + /PDFDEBUG % PDF Interpreter + /PDFWRDEBUG % PDF Writer + /SETPDDEBUG % setpagedevice + /TTFDEBUG % TTF Fonts + /VGIFDEBUG % ViewGIF + /VJPGDEBUG % ViewJPEG + /RESMPDEBUG % Resource map +counttomark array astore exch pop % ']' isn't defined yet +{ dup currentdict exch known DEBUG or def } forall + +currentdict /PDFSTEP known /PDFSTEP exch def +% if PDFSTEP is on, turn on PDFDEBUG +PDFSTEP { /PDFDEBUG //true def } if + +currentdict /PDFSTOPONERROR known /PDFSTOPONERROR exch def +currentdict /PDFSTOPONWARNING known {/PDFSTOPONWARNING true def /PDFSTOPONERROR true def}{/PDFSTOPONWARNING false def} ifelse +currentdict /PDFNOCIDFALLBACK known /PDFNOCIDFALLBACK exch def + + /VMDEBUG + INITDEBUG {{print mark + systemdict /level2dict known + { .currentglobal dup //false .setglobal vmstatus + //true .setglobal vmstatus 3 -1 roll pop + 6 -2 roll pop .setglobal + } + { vmstatus 3 -1 roll pop + } + ifelse usertime 16#fffff and counttomark + { ( ) print ( ) cvs print } + repeat pop + ( ) print systemdict length ( ) cvs print + ( ) print countdictstack ( ) cvs print + ( <) print count ( ) cvs print (>\n) print flush + }} + {{pop + }} + ifelse + def + +currentdict /BATCH known /BATCH exch def +currentdict /DELAYBIND known /DELAYBIND exch def +currentdict /DISKFONTS known /DISKFONTS exch def +currentdict /DOINTERPOLATE .knownget { /INTERPOLATE exch def } if +currentdict /ESTACKPRINT known /ESTACKPRINT exch def +currentdict /FAKEFONTS known /FAKEFONTS exch def +currentdict /FIXEDMEDIA known /FIXEDMEDIA exch def +currentdict /FIXEDRESOLUTION known /FIXEDRESOLUTION exch def +currentdict /LOCALFONTS known /LOCALFONTS exch def +currentdict /JOBSERVER known /JOBSERVER exch def +currentdict /NOBIND known /NOBIND exch def +/.bind /bind load def +NOBIND { /bind { } def } if +currentdict /NOCACHE known /NOCACHE exch def +currentdict /NOCCFONTS known /NOCCFONTS exch def +currentdict /NOCIE known /NOCIE exch def +currentdict /NOPSICC known /NOPSICC exch def +currentdict /NODISPLAY known not /DISPLAYING exch def +currentdict /NOFONTMAP known /NOFONTMAP exch def +currentdict /NOFONTPATH known /NOFONTPATH exch def +currentdict /NOGC known /NOGC exch def +currentdict /NOINTERPOLATE .knownget { /INTERPOLATE exch not def } if +currentdict /NOMEDIAATTRS known /NOMEDIAATTRS exch def +currentdict /NOOUTERSAVE known /NOOUTERSAVE exch def +currentdict /NOPAGEPROMPT known /NOPAGEPROMPT exch def +currentdict /NOPAUSE known /NOPAUSE exch def +currentdict /NOPLATFONTS known /NOPLATFONTS exch def +currentdict /NOPROMPT known /NOPROMPT exch def +currentdict /NOTRANSPARENCY known /NOTRANSPARENCY exch def +currentdict /DOPS known /DOPS exch def +currentdict /NOSUBSTDEVICECOLORS known /NOSUBSTDEVICECOLORS exch def +% The default value of ORIENT1 is true, not false. +currentdict /ORIENT1 known not { /ORIENT1 //true def } if +currentdict /OSTACKPRINT known /OSTACKPRINT exch def +currentdict /OUTPUTFILE known % obsolete + { /OutputFile /OUTPUTFILE load def + currentdict /OUTPUTFILE .undef + } if +currentdict /QUIET known /QUIET exch def +% DELAYSAFER is effectively the same as newer NOSAFER +currentdict /DELAYSAFER known { /DELAYSAFER //true def /NOSAFER //true def } if +/SAFER currentdict /NOSAFER known { + //false +} { + currentdict /SAFER known + currentdict /PARANOIDSAFER known or % PARANOIDSAFER is equivalent +} +ifelse def +currentdict /SHORTERRORS known /SHORTERRORS exch def +currentdict /STRICT known /STRICT exch def +currentdict /TTYPAUSE known /TTYPAUSE exch def +currentdict /WRITESYSTEMDICT known /WRITESYSTEMDICT exch def +currentdict /RENDERTTNOTDEF known /RENDERTTNOTDEF exch def +currentdict /SCANCONVERTERTYPE known +{ + currentdict /SCANCONVERTERTYPE get .setscanconverter +} if + +% We rely on PSFitPage to actually implement EPSFitPage +currentdict /EPSFitPage known { /PSFitPage //true def } if +% This is a "convenience" option that sets a combination of EPSFitPage, PDFFitPage and PSFitPage +currentdict /FitPage known { /EPSFitPage //true def /PDFFitPage //true def /PSFitPage //true def } if + +% Acquire environment variables. +currentdict /DEVICE known not + { (GS_DEVICE) getenv { /DEVICE exch def } if } if + +(START) VMDEBUG + +% Open the standard files, so they will be open at the outermost save level. +(%stdin) (r) file pop +(%stdout) (w) file pop +(%stderr) (w) file pop + +/.currentuserparams where { + pop mark + % The Adobe implementations appear to have very large maximum + % stack sizes. This turns out to actually make a difference, + % since some badly-behaved files include extremely long procedures, + % or construct huge arrays on the operand stack. + % We reset the stack sizes now so that we don't have to worry + % about overflowing the (rather small) built-in stack sizes + % during initialization. + /MaxDictStack 500 + /MaxExecStack 5000 + /MaxOpStack 300000 + .dicttomark .setuserparams +} if + +% Define a procedure for skipping over an unneeded section of code. +% This avoids allocating space for the skipped procedures. +% We can't use readline, because that imposes a line length limit. +/.skipeof % <string> .skipeof - + { currentfile exch 1 exch .subfiledecode flushfile + } .bind def + +% Define procedures to assist users who don't read the documentation. +userdict begin +/help + { (Enter PostScript commands. '(filename) run' runs a file, 'quit' exits.\n) + print flush + } .bind def +end + +% Define =string, which is used by some PostScript programs even though +% it isn't documented anywhere. +% Put it in userdict so that each context can have its own copy. +userdict /=string 256 string put + +% Print the greeting. + +/printgreeting + { mark + product (GPL Ghostscript) search + { pop pop pop + (This software comes with NO WARRANTY: see the file PUBLIC for details.\n) + } + { pop + } + ifelse + (\n) copyright + (\)\n) revisiondate 10 mod revisiondate 10 idiv 10 mod (-) + revisiondate 100 idiv 10 mod revisiondate 1000 idiv 10 mod (-) + revisiondate 10000 idiv ( \() + revision 10 mod + revision 100 mod 10 idiv (.) + revision 100 idiv ( ) + product + counttomark + { (%stdout) (w) file exch 0 .writecvp + } repeat pop + } .bind def + +QUIET not { printgreeting flush } if + +% Define a special version of def for making operator procedures. +/obind { % <name> <proc> obind <name> <oper> + 1 index exch .makeoperator +} .bind def +/odef { % <name> <proc> odef - + 1 index exch .makeoperator def +} .bind def + +% Define a special version of def for storing local objects into global +% dictionaries. Like .forceput, this exists only during initialization. +/.forcedef { % <key> <value> .forcedef - + 1 .argindex pop % check # of args + currentdict 3 1 roll .forceput +} .bind odef + +% Define procedures for accessing variables in systemdict and userdict +% regardless of the contents of the dictionary stack. +/.systemvar { % <name> .systemvar <value> + //systemdict exch get +} .bind odef +/.systemexec { + .systemvar exec +} .bind odef +/.userdict { % - .userdict <dict> + /userdict .systemvar +} .bind odef +/.uservar { % <name> .uservar <value> + .userdict exch get +} .bind odef + +% If we're delaying binding, remember everything that needs to be bound later. +DELAYBIND NOBIND not and + { .currentglobal //false .setglobal + systemdict /.delaybind 2000 array .forceput + .setglobal + userdict /.delaycount 0 put + % When we've done the delayed bind, we want to stop saving. + % Detect this by the disappearance of .delaybind. + /bind + { /.delaybind .systemvar dup length 0 ne + { .delaycount 2 index put + .userdict /.delaycount .delaycount 1 add put + } + { pop /.bind cvx exec + } + ifelse + } .bind def + } if + +%**************** BACKWARD COMPATIBILITY **************** +/hwsizedict mark /HWSize //null .dicttomark readonly def +/copyscanlines { % <device> <y> <string> copyscanlines <substr> + 0 3 1 roll 3 index //hwsizedict .getdeviceparams + exch pop exch pop aload pop 3 2 roll + 0 exch //null exch .getbitsrect exch pop +} bind odef +currentdict /hwsizedict .undef +/getdeviceprops + { //null .getdeviceparams + } bind odef +/.putdeviceprops + { //null //true counttomark 1 add 3 roll .putdeviceparams + dup type /booleantype ne + { dup mark eq { /unknown /rangecheck } if + counttomark 4 add 1 roll cleartomark pop pop pop + /.putdeviceprops .systemvar exch signalerror + } + if + } bind odef +/.currentfilladjust { .currentfilladjust2 pop } bind odef +/.setfilladjust { dup .setfilladjust2 } bind odef +/.writecvs { 0 .writecvp } bind odef +%**************** DEPRECATED PROCEDURES **************** +%**************** DO NOT USE THESE IN NEW CODE **************** +/max { .max } bind def % use .max instead +/min { .min } bind def % use .min instead +/unread /.unread load def % use .peekstring instead +%**************** END OF BACKWARD COMPATIBILITY SECTION **************** + +% Utility for removing all entries from a dictionary +/.PurgeDict % <dict> .PurgeDict - +{ { //true + 1 index { pop exch pop //false exit + } forall + { exit + } if + 1 index exch undef + } loop + pop +} bind def + +% Define predefined procedures substituting for operators, +% in alphabetical order. + +userdict /#copies 1 put +% Adobe implementations don't accept /[ or /], so we don't either. +([) cvn + /mark load def +(]) cvn + {counttomark array astore exch pop} odef +% .beginpage is redefined if setpagedevice is present. +/.beginpage { } odef +% In LanguageLevel 3, copypage erases the page. +/copypage { + .languagelevel 3 ge + dup { 0 } { 1 } ifelse .endpage .doneshowpage { + .currentnumcopies 1 index .outputpage + (>>copypage, press <return> to continue<<\n) .confirm + dup { erasepage } if + } if pop + systemdict /..page_default_spaces .knownget { //.PurgeDict exec } if + .beginpage +} odef +/currentmatrix { + dup type /arraytype ne + { /currentmatrix load /typecheck signalerror } if + dup length 6 ne + { /currentmatrix load /rangecheck signalerror } if + .currentmatrix 6 .argindex astore pop +} odef +% .currentnumcopies is redefined in Level 2. +/.currentnumcopies { #copies } odef +/setcolorscreen where { pop % not in all Level 1 configurations + /currentcolorscreen + { .currenthalftone + { { 60.0 exch 0.0 exch 3 copy 6 copy } % halftone - not possible + { 3 copy 6 copy } % screen + { } % colorscreen + } + exch get exec + } odef +} if +/currentscreen + { .currenthalftone + { { 60.0 exch 0.0 exch } % halftone - not possible + { } % screen + { 12 3 roll 9 { pop } repeat } % colorscreen + } + exch get exec + } odef +/.echo /echo load def +userdict /.echo.mode //true put +/echo {dup /.echo.mode exch store .echo} odef +/.eexec_param_dict mark + /eexec //true + /seed 55665 +.dicttomark readonly def +/eexec { + % Rebind .currentresourcefile if it is the source for the eexec. + dup //.eexec_param_dict //filterdict /eexecDecode get exec + cvx exch .currentresourcefile eq + //systemdict begin { {exec} .execasresource } { exec } ifelse + % Only pop systemdict if it is still the top element, + % because this is apparently what Adobe interpreters do. + currentdict //systemdict eq { end } if +} odef +% .endpage is redefined if setpagedevice is present. +/.endpage { 2 ne } odef +% erasepage mustn't use gsave/grestore, because we call it before +% the graphics state stack has been fully initialized. +/erasepage + { /currentcolor where + { pop currentcolor currentcolorspace { setcolorspace setcolor } } + { /currentcmykcolor where + { pop currentcmykcolor { setcmykcolor } } + { currentrgbcolor { setrgbcolor } } + ifelse + } + ifelse + currentoverprint //false setoverprint 1 setgray .fillpage setoverprint + exec + } odef +% To satisfy the Genoa FTS, executive must be a procedure, not an operator. +/executive + { { prompt + { (%statementedit) (r) .systemvmfile } stopped + { pop pop $error /errorname get /undefinedfilename eq + { .clearerror exit } if % EOF + /handleerror .systemvar exec //null % ioerror?? + } + if + cvx { .runexec } .execute pop + } loop + } bind def +/filter + { //filterdict 1 .argindex .knownget + { exch pop exec } + { /filter .systemvar /undefined signalerror } + ifelse + } odef +% handleerror procedure as mentioned in the "Operators" section of the PLRM Section 8.2 +% This invokes the handleerror procedure from errordict (unless we are running under a +% JOBSERVER where we want to always use a defined error handler (many error handlers in +% 'wild' PostScript files are broken and don't indicate the error in any useful fashion). +% +% We run the handleerror procedure using .internalstopped so that broken error handlers +% won't cause nested errors (Unexpected Error conditions). +/handleerror + JOBSERVER { + { /.GShandleerror .systemvar .internalstopped pop } bind % always use .GShandleerror. + } { + { /errordict .systemvar /handleerror get .internalstopped pop } bind % PLRM standard errorhandling + } ifelse def +/identmatrix [1.0 0.0 0.0 1.0 0.0 0.0] readonly def +/identmatrix { + dup type /arraytype ne { /identmatrix load /typecheck signalerror } if + dup length 6 ne { /identmatrix load /rangecheck signalerror } if + dup 0 //identmatrix putinterval +} odef +/languagelevel 1 def % gs_lev2.ps may change this +/makeimagedevice { //false makewordimagedevice } odef +/matrix { 6 array identmatrix } odef +% .promptmsg is redefined if the interpreter includes readline support. +/.promptmsg { + (GS) print + count 0 ne { (<) print count =only } if + (>) print flush +} bind def +/prompt { flush flushpage NOPROMPT not { .promptmsg } if } bind def +/pstack { 0 1 count 3 sub { index == } for } bind def +/putdeviceprops + { .putdeviceprops { erasepage } if } odef +/quit { /quit load 0 .quit } odef +/run { dup type /filetype ne { (r) .systemvmfile } if + % We must close the file when execution terminates, + % regardless of the state of the stack, + % and then propagate an error, if any. + cvx //null {.runexec} .errorexec + } odef +% Execute a file. +% Level 2 uses 2 .stop to clear the e-stack for a successful startjob: +% we detect that here, since we need to handle this even if we start out +% without job control in effect. +% +% What we push on the e-stack is the following to be executed in this order: +% <lit-file|fileproc> .runexec1 <lit-file|fileproc> .runexec2 +/.runexec1 { % <file|fileproc> .runexec1 - + dup type /filetype ne { cvx exec } if + cvx //null 2 .stopped + % If we got back here from a startjob, just keep going. + % startjob replaces the null on the o-stack with a procedure + % to be executed when we get back here. + dup //null ne { exec //true } { pop //false } ifelse +} bind def +/.runexec2 { % <continue> <file|fileproc> .runexec2 - + exch { + .runexec + } { + dup type /filetype ne { cvx exec } if + closefile + } ifelse +} bind def +/.runexec { % <file|fileproc> .runexec - + cvlit /.runexec1 cvx 1 index /.runexec2 cvx 4 .execn +} bind def +% The following is only for compatibility with Adobe interpreters. +/setdash { + 0 .argindex type dup /integertype eq exch /realtype eq or not { + /setdash .systemvar /typecheck signalerror + } if + //setdash +} odef +/setdevice + { + .setdevice + { + mark + { % Reset the halftone since the device may differ + currenthalftone + dup type /dicttype eq + { sethalftone } + { pop } + ifelse + } + stopped + cleartomark + erasepage + } + if + } +odef +/setlinecap { + dup 2 gt { /setlinecap .systemvar /rangecheck signalerror } if + .setlinecap +} odef +/setlinejoin { + dup 2 gt { /setlinejoin .systemvar /rangecheck signalerror } if + .setlinejoin +} odef +/setmatrix { + dup type /arraytype ne { + dup type /packedarraytype ne { + /setmatrix load /typecheck signalerror + } if + } if + dup length 6 ne { /setmatrix load /rangecheck signalerror } if + dup aload pop .setmatrix pop +} odef +/showpage { + 0 .endpage .doneshowpage { + .currentnumcopies //true .outputpage + (>>showpage, press <return> to continue<<\n) .confirm + % Uncomment the following line, and use a Memento build to track + % blocks that are created and not destroyed between each successive + % page. + % 2 .vmreclaim .mementolistnewblocks + initgraphics + currentoverprint //false setoverprint 1 setcolor + .fillpage + setoverprint 0 setcolor + } + { initgraphics } ifelse + systemdict /..page_default_spaces .knownget { //.PurgeDict exec } if + .beginpage +} odef +% Code output by Adobe Illustrator relies on the fact that +% `stack' is a procedure, not an operator!!! +/stack { 0 1 count 3 sub { index = } for } bind def +/start { BATCH { //null 0 .quit } { executive } ifelse } def +% Internal uses of stopped that aren't going to do a stop if an error occurs +% should use .internalstopped to avoid setting newerror et al. +/.internalstopped { //null 1 .stopped //null ne } bind def +/store { % Don't alter operands before completing. + 1 .argindex where { 2 index 2 index put pop pop } { def } ifelse +} odef +/.typenames mark .typenames counttomark packedarray exch pop def +/type { + //.typenames .type +} odef +currentdict /.typenames .undef +% When running in Level 1 mode, this interpreter is supposed to be +% compatible with PostScript "version" 54.0 (I think). +/version (54.0) readonly def +/.wheredict 10 dict def +/.where /where load def +/where { + //.wheredict 1 .argindex .knownget { exec } { .where } ifelse +} odef + +% internaldict is defined in systemdict, but the dictionary is allocated +% in local VM. However, the procedure must be global, since it is an +% "operator" and must be bind-able into global procedures. +% We make a procedure for creating it, since we must create a new one +% for each context with private local VM. +/.makeinternaldict { + .currentglobal //true .setglobal + [ /dup .systemvar 1183615869 /eq .systemvar + [ /pop .systemvar //null ] cvx + //false .setglobal + dup 1 10 dict .forceput % proc is global, dict is local + //true .setglobal + [ /internaldict /cvx .systemvar /invalidaccess /signalerror cvx ] cvx + /ifelse .systemvar + ] cvx executeonly + exch .setglobal +} odef +systemdict /internaldict dup .makeinternaldict .makeoperator +.forceput % proc is local, systemdict is global + +% Define some additional built-in procedures (beyond the ones defined by +% the PostScript Language Reference Manual). +% Warning: these are not guaranteed to stay the same from one release +% to the next! +/concatstrings % (str1) (str2) concatstrings (str1str2) + { exch dup length 2 index length add string % str2 str1 new + dup dup 4 2 roll copy % str2 new new new1 + length 4 -1 roll putinterval + } bind def +/copyarray + { dup length array copy } bind def +% Copy a dictionary per the Level 2 spec even in Level 1. +/.copydict % <fromdict> <todict> .copydict <todict> + { dup 3 -1 roll { put dup } forall pop } bind def +/copystring + { dup length string copy } bind def +/findlibfile { + .systemvmlibfile { dup .filename pop exch //true } { //false } ifelse +} odef +/.growdictlength % get size for growing a dictionary + { length 3 mul 2 idiv 1 add + } bind def +/.growdict % grow a dictionary + { dup .growdictlength .setmaxlength + } bind def +/.growput % put, grow the dictionary if needed + { 2 index length 3 index maxlength eq + { 3 copy pop known not { 2 index .growdict } if + } if + put + } bind def +% .localvmarray may be an operator: see zsysvm.c. +/.localvmarray where { + pop +} { + /.localvmarray { + .currentglobal //false .setglobal + exch array exch .setglobal + } bind def +} ifelse +/.localvmdict where { + pop +} { + /.localvmdict { + .currentglobal //false .setglobal + exch dict exch .setglobal + } bind def +} ifelse +/.packtomark + { counttomark packedarray exch pop } bind def +/ppstack + { 0 1 count 3 sub { index === } for } bind def +/runlibfile + { % We don't want to bind 'run' into this procedure, + % since run may get redefined. + findlibfile + { exch pop /run .systemvar exec } + { /undefinedfilename signalerror } + ifelse + } bind def +/selectdevice + { finddevice setdevice .setdefaultscreen } bind def +/signalerror % <object> <errorname> signalerror - + { /errordict .systemvar exch get exec } bind def +/signaloperror { % <object> <errorname> signaloperror - + % Same as signalerror, except that if we are inside a pseudo-operator + % or .errorexec, we use its error object, just as errors generated by + % real operators do. + /errordict .systemvar exch get + .finderrorobject { 3 -1 roll pop exch } if + exec +} bind def + +% Define the =[only] procedures. Also define =print, +% which is used by some PostScript programs even though +% it isn't documented anywhere. +/write=only { + .writecvs +} bind def +/write= { + 1 index exch write=only (\n) writestring +} bind def +/=only { (%stdout) (w) file exch write=only } bind def +/= { =only (\n) print } bind def +/=print /=only load def +% Temporarily define == as = for the sake of runlibfile0. +/== /= load def + +% The following procedures are documented. +/copydevice { % <device> copydevice <newdevice> + //false .copydevice2 +} odef +/finddevice { % <devicename> finddevice <device> + /devicedict .systemvar exch get + dup 1 get //null eq { + % This is the first request for this type of device. + % Create a default instance now. + % Stack: [proto null] + .currentglobal //true .setglobal exch + dup dup 0 get copydevice 1 exch put + exch .setglobal + } if 1 get +} bind def +/findprotodevice { % <devicename> findprotodevice <protodevice> + /devicedict .systemvar exch get 0 get +} bind def + +% Run a resource file. This allows us to distinguish resource objects +% from objects coming from input files. +userdict /.currentresourcefile //null put +/.execasresource { % <file> <proc|runfile> .execasresource - + /stopped .systemvar + /.currentresourcefile .uservar + % Stack: file proc -stopped- currfile + .userdict /.currentresourcefile 5 index cvlit put + 2 .execn % stopped <file> + .userdict /.currentresourcefile 3 -1 roll put + { stop } if +} bind def +/.runresource { % <file> .runresource - + { /run .systemvar exec } .execasresource +} bind def + +% Define procedures for getting and setting the current device resolution. + +/gsgetdeviceprop % <device> <propname> gsgetdeviceprop <value> + { 2 copy mark exch //null .dicttomark .getdeviceparams + dup mark eq % if true, not found + { pop dup /undefined signalerror } + { 5 1 roll pop pop pop pop } + ifelse + } bind def +/gscurrentresolution % - gscurrentresolution <[xres yres]> + { currentdevice /HWResolution gsgetdeviceprop + } bind def +/gssetresolution % <[xres yres]> gssetresolution - + { 2 array astore mark exch /HWResolution exch + currentdevice copydevice putdeviceprops setdevice + } bind def + +% Define auxiliary procedures needed for the above. +/shellarguments % -> shell_arguments true (or) false + { /ARGUMENTS where + { /ARGUMENTS get dup type /arraytype eq + { aload pop /ARGUMENTS //null store //true } + { pop //false } + ifelse } + { //false } ifelse + } bind def +/.confirm { + DISPLAYING NOPAUSE not TTYPAUSE or and { + % Print a message (unless NOPAGEPROMPT or NOPROMPT is true) + % and wait for the user to type something. + % If the user just types a newline, flush it. + NOPAGEPROMPT NOPROMPT or { pop } { print flush } ifelse + .confirmread + } { + pop + } ifelse +} bind def +/.confirmread { + TTYPAUSE { + (/dev/tty) (r) file dup read pop pop closefile + } { + .echo.mode //false echo + (%stdin) (r) file dup read { + dup (\n) 0 get eq { pop pop } { unread } ifelse + } { + pop + } ifelse echo + } ifelse +} bind def + +% Define the procedure used by .runfile, .runstdin and .runstring +% for executing user input. +% This is called with a procedure or executable file on the operand stack. +/.execute { % <obj> .execute <stopped> + stopped $error /newerror get and + { /handleerror .systemvar exec flush //true } { //false } ifelse +} bind def +/execute { % <obj> execute - + .execute pop +} odef +% Define an execute analogue of runlibfile0. +/execute0 { % <obj> execute0 - + .execute { /execute0 cvx 1 .quit } if +} bind def +% Define the procedure that the C code uses for running files +% named on the command line. +/.runfile { + { runlibfile } execute0 +} def +% Define the procedure that the C code uses for running piped input. +% We don't use the obvious { (%stdin) run }, because we want the file to be +% reopened if a startjob does a restore. +/.runstdin { + { { (%stdin) (r) file cvx } .runexec } execute0 +} bind def +% Define the procedure that the C code uses for running commands +% given on the command line with -c. We turn the string into a file so that +% .runexec can do the right thing with a startjob. +/.runstring { + 0 0 .systemvmstring .systemvmSFD cvx { .runexec } execute0 +} bind def +% Define the procedure that the C code uses to set up for executing +% a string that may be received in pieces. +/.runstringbegin { + 1 .systemvmarray dup 0 /.needinput load put cvx % { .needinput } in systemvm + 0 0 .systemvmstring .systemvmSFD cvx .runexec +} bind def + +% Define a special version of runlibfile that aborts on errors. +/runlibfile0 + { cvlit dup dup /.currentfilename exch def + { findlibfile not { stop } if } + stopped + { (Can't find \(or open\) initialization file ) print + .currentfilename == flush /runlibfile0 cvx 1 .quit + } if + exch pop cvx + { stopped } 0 get 3 -1 roll 2 array astore cvx exec + /.currentfilename exch store + { (While reading ) print .currentfilename print (:\n) print flush + /handleerror .systemvar exec /runlibfile0 1 .quit + } if + } bind def +% Temporarily substitute it for the real runlibfile. +/.runlibfile /runlibfile load def +/runlibfile /runlibfile0 load def + +% Create the error handling machinery. +% Define the standard error handlers. +% The interpreter has created the ErrorNames array. +/.unstoppederrorhandler % <command> <errorname> .unstoppederrorhandler - + { % This is the handler that gets used for recursive errors, + % or errors outside the scope of a 'stopped'. + 2 copy SHORTERRORS + { (%%[ Error: ) print =only flush + (; OffendingCommand: ) print =only ( ]%%) = + } + { (Unrecoverable error: ) print =only flush + ( in ) print = flush + count 2 gt + { (Operand stack:\n ) print + count 1 sub -1 2 { ( ) print index =only flush } for + () = flush + } if + } + ifelse + -1 0 1 //ErrorNames length 1 sub + { dup //ErrorNames exch get 3 index eq + { not exch pop exit } { pop } ifelse + } + for exch pop .quit + } bind def +/.errorhandler % <command> <errorname> .errorhandler - + { % Detect an internal 'stopped'. + 1 .instopped { //null eq { pop pop stop } if } if + (I) //false .setdebug + $error /.inerror get 1 .instopped { pop } { pop //true } ifelse + { .unstoppederrorhandler + } if % detect error recursion + $error /globalmode .currentglobal //false .setglobal put + $error /.inerror //true put + $error /newerror //true put + $error exch /errorname exch put + $error exch /command exch put + $error /errorinfo known not { $error /errorinfo //null put } if + $error /recordstacks get $error /errorname get /VMerror ne and + { % Attempt to store the stack contents atomically. + count array astore dup $error /ostack 4 -1 roll + % Grab the execstack, then remove to two elements that are from + % this error handler (not interesting). + countexecstack array execstack dup length 2 sub 0 exch getinterval + $error /estack 3 -1 roll + countdictstack array dictstack $error /dstack 3 -1 roll + put put put aload pop + } + { $error /dstack .undef + $error /estack .undef + $error /ostack .undef + } + ifelse + $error /position currentfile status + { currentfile { fileposition } .internalstopped { pop //null } if + } + { % If this was a scanner error, the file is no longer current, + % but the command holds the file, which may still be open. + $error /command get dup type /filetype eq + { { fileposition } .internalstopped { pop //null } if } + { pop //null } + ifelse + } + ifelse put + % During initialization, we don't reset the allocation + % mode on errors. + $error /globalmode get $error /.nosetlocal get and .setglobal + $error /.inerror //false put + stop + } bind def +% Define the standard handleerror. We break out the printing procedure +% (.printerror) so that it can be extended for binary output +% if the Level 2 facilities are present. + /.printerror + { $error begin newerror + { + /command load errorname SHORTERRORS + { (%%[ Error: ) print =only flush + (; OffendingCommand: ) print =only + errorinfo dup //null eq { + pop + } { + (;\nErrorInfo:) print + dup type /arraytype eq + { { ( ) print =only } forall } + { ( ) print =only } + ifelse + } ifelse + ( ]%%) = flush + } + { (Error: ) print ==only flush + ( in ) print ==only flush + errorinfo dup //null eq { + pop + } { + (\nAdditional information: ) print ==only flush + } ifelse + .printerror_long + } + ifelse + .clearerror flush + } + { % newerror is //false, test to see if user has set handleerror to a different + % routine, if so execute it, otherwise, just return. This code deals with the + % Genoa issue of setting /handleerror, and then calling it, without an error + % being set. We were erroring in this case, due to /command load failing. + + //JOBSERVER { + /errordict .systemvar /handleerror get /.GShandleerror .systemvar ne + } { + //false + } ifelse + { /errordict .systemvar begin /handleerror load .internalstopped pop end + } + if + } + ifelse % newerror + end + flush + } bind def + /.printerror_long % long error printout, + % $error is on the dict stack + { % Push the (anonymous) stack printing procedure. + % <heading> <==flag> <override-name> <stackname> proc + { + currentdict exch .knownget % stackname defined in $error? + { + 4 1 roll % stack: <stack> <head> <==flag> <over> + /errordict .systemvar exch .knownget % overridename defined? + { + exch pop exch pop exec % call override with <stack> + } + { + exch print exch % print heading. stack <==flag> <stack> + 1 index not { () = } if + { 1 index { (\n ) } { ( ) } ifelse print + dup type /dicttype eq + { + (--dict:) print + dup rcheck { + dup length =only (/) print dup maxlength =only + dup wcheck not { ((ro)) print } if + } if + /gcheck where { + pop gcheck { ((G)) } { ((L)) } ifelse print + } { + pop + } ifelse (--) print + } + { + dup type /stringtype eq 2 index or + { ==only } { =only } ifelse + } ifelse + } forall + pop + } + ifelse % overridden + } + { pop pop pop + } + ifelse % stack known + } + + (\nOperand stack:) OSTACKPRINT /.printostack /ostack 4 index exec + (\nExecution stack:) ESTACKPRINT /.printestack /estack 4 index exec + (\nBacktrace:) //true /.printbacktrace /backtrace 4 index exec + (\nDictionary stack:) //false /.printdstack /dstack 4 index exec + () = + pop % printing procedure + + errorname /VMerror eq + { (VM status:) print mark vmstatus + counttomark { ( ) print counttomark -1 roll dup =only } repeat + cleartomark () = + } if + + .languagelevel 2 ge + { (Current allocation mode is ) print + globalmode { (global\n) } { (local\n) } ifelse print + } if + + .oserrno dup 0 ne + { (Last OS error: ) print + errorname /VMerror ne + { dup .oserrorstring { = pop } { = } ifelse } + { = } + ifelse + } + { pop + } + ifelse + + position //null ne + { (Current file position is ) print position = } + if + + } bind def +% Define a procedure for clearing the error indication. +/.clearerror + { $error /newerror //false put + $error /errorname //null put + $error /errorinfo //null put + 0 .setoserrno + } bind def + +% Define $error. This must be in local VM. +.currentglobal //false .setglobal +/$error 40 dict .forcedef % $error is local, systemdict is global + % newerror, errorname, command, errorinfo, + % ostack, estack, dstack, recordstacks, + % binary, globalmode, + % .inerror, .nosetlocal, position, + % plus extra space for badly designed error handers. +$error begin + /newerror //false def + /recordstacks //true def + /binary //false def + /globalmode .currentglobal def + /.inerror //false def + /.nosetlocal //true def + /position //null def + /errorinfo //null def +end +% Define errordict similarly. It has one entry per error name, +% plus handleerror. However, some astonishingly badly written PostScript +% files require it to have at least one empty slot. +/errordict ErrorNames length 3 add dict +.forcedef % errordict is local, systemdict is global +.setglobal % back to global VM +% For greater Adobe compatibility, we put all non-standard errors in a +% separate dictionary, gserrordict. It does not need to be in local VM, +% because PostScript programs do not access it. +% NOTE: the name gserrordict is known to the interpreter. +/gserrordict 5 dict def +% Register an error in errordict. We make this a procedure because we only +% register the Level 1 errors here: the rest are registered by "feature" +% files. However, ErrorNames contains all of the error names regardless of +% what features are included, so we have to "know" that VMerror is the last +% Level 1 error. +/.registererror % <name> .registererror - + { errordict exch .registererror2 + } bind def +/.registererror2 % <dict> <name> .registererror - + { .currentglobal //true .setglobal % create procs in global VM + 3 1 roll + mark 1 index systemdict /.errorhandler get /exec load .packtomark cvx put + .setglobal + } bind def +ErrorNames + { dup .registererror /VMerror eq {exit} if + } forall +errordict begin +% The handlers for interrupt and timeout are special; there is no +% 'current object', so they push their own name. + { /interrupt /timeout } + { mark 1 index dup systemdict /.errorhandler get /exec load .packtomark cvx def + } forall +/handleerror % this key is 'well known' and some PS may redefine it + { /.printerror .systemvar exec + } bind def +end % errordict + +% Put non-standard errors in gserrordict. +gserrordict /unknownerror errordict /unknownerror get put +errordict /unknownerror .undef +% Define a stable private copy of handleerror that we will always use under +% JOBSERVER mode. +/.GShandleerror errordict /handleerror get def + +% Define the [write]==[only] procedures. +/.dict 8 dict dup +begin def + /.cvp {1 index exch 1 .writecvp} bind def + /.p {1 index exch writestring} bind def + /.p1 {2 index exch writestring} bind def + /.p2 {3 index exch writestring} bind def + /.print + { dup type .dict exch .knownget { exec } { .cvp } ifelse + } bind def + /arraytype + {dup rcheck + {() exch dup xcheck + {({) .p2 + {exch .p1 + 1 index exch .print pop ( )} forall + (})} + {([) .p2 + {exch .p1 + 1 index exch .print pop ( )} forall + (])} + ifelse exch pop .p} + {.cvp} + ifelse} bind def + /packedarraytype /arraytype load def +{//.dict begin .print pop end} + bind +end + +/write==only exch def +/write== {1 index exch write==only (\n) writestring} bind def +/==only { (%stdout) (w) file exch write==only } bind def +/== {==only (\n) print} bind def + +% Define [write]===[only], an extension that prints dictionaries +% in readable form and doesn't truncate strings. +/.dict /write==only load 0 get dup length 2 add dict .copydict dup +begin def + /dicttype + { dup rcheck + { (<< ) .p1 + { 2 index 3 -1 roll .print pop ( ) .p1 + 1 index exch .print pop ( ) .p + } + forall (>>) .p + } + { .cvp + } + ifelse + } bind def + /stringtype + { 1 index exch 2 .writecvp + } bind def + +{//.dict begin .print pop end} + bind +end + +/write===only exch def +/write=== {1 index exch write===only (\n) writestring} bind def +/===only { (%stdout) (w) file exch write===only } bind def +/=== { ===only (\n) print } bind def + +% Create the initialization queue. + +/.delayed_init_queue 10 dict def + +/.schedule_init % <priority> <proc> .schedule_init - +{ + //.delayed_init_queue 2 index known { + (.delayed_init_queue priority conflict with ) print 1 index = + /.schedule_init cvx /configurationerror signalerror + } if + //.delayed_init_queue 3 1 roll .growput +} bind def + +/.execute_scheduled_inits % - .execute_scheduled_inits - +{ + { 0 //null //.delayed_init_queue { % maxp {} p {} + 3 index 2 index lt { + 4 2 roll + } if + pop pop + } forall + exch //.delayed_init_queue exch undef + dup //null eq { + pop exit + } if + exec + } loop +} bind def + +(END PROCS) VMDEBUG + +% Define the font directory. +/FontDirectory //false .setglobal 100 dict //true .setglobal +.forcedef % FontDirectory is local, systemdict is global + +% Define the encoding dictionary. +/EncodingDirectory 16 dict def % enough for Level 2 + PDF standard encodings + +% Define .findencoding. (This is redefined in Level 2.) +/.findencoding + { //EncodingDirectory exch get exec + } bind def +/.defineencoding + { //EncodingDirectory 3 1 roll put + } bind def +% If we've got the composite font extensions, define findencoding. +% To satisfy the Genoa FTS, findencoding must be a procedure, not an operator. +/rootfont where { pop /findencoding { .findencoding } def } if + +% Define .registerencoding. +% NOTE: This procedure no longer does anything, but it must continue to +% exist for the sake of toolbin/encs2c.ps. +/.registerencoding { % <index> <array> .registerencoding - + pop pop +} bind odef + +% Load StandardEncoding. +%% Replace 1 (gs_std_e.ps) +(gs_std_e.ps) dup runlibfile VMDEBUG + +% Load ISOLatin1Encoding. +%% Replace 1 (gs_il1_e.ps) +(gs_il1_e.ps) dup runlibfile VMDEBUG + +% Define stubs for the Symbol and Dingbats encodings. +% Note that the first element of the procedure must be the file name, +% since gs_lev2.ps extracts it to set up the Encoding resource category. + + /SymbolEncoding { /SymbolEncoding .findencoding } bind def +%% Replace 3 (gs_sym_e.ps) + EncodingDirectory /SymbolEncoding + { (gs_sym_e.ps) //systemdict begin runlibfile SymbolEncoding end } + bind put + + /DingbatsEncoding { /DingbatsEncoding .findencoding } bind def +%% Replace 3 (gs_dbt_e.ps) + EncodingDirectory /DingbatsEncoding + { (gs_dbt_e.ps) //systemdict begin runlibfile DingbatsEncoding end } + bind put + +(END FONTDIR/ENCS) VMDEBUG + +% Special handling for device parameters. Must follow definition of 'type' +% make -dPDFA equivalent to -dPDFA=1 (backwards compatible) +currentdict /PDFA known { PDFA type /booleantype eq { /PDFA 1 def } if } if + +% Construct a dictionary of all available devices. +% These are (read-only) device prototypes that can't be +% installed or have their parameters changed. For this reason, +% the value in the dictionary is actually a 2-element writable array, +% to allow us to create a default instance of the prototype on demand. + + % Loop until the .getdevice gets a rangecheck. +errordict /rangecheck 2 copy get +errordict /rangecheck { pop stop } put % pop the command + 0 { {dup .getdevice exch 1 add} loop} .internalstopped pop + 1 add dict /devicedict 1 index def + begin % 2nd copy of count is on stack + { dup .devicename exch + dup wcheck { dup } { //null } ifelse 2 array astore def + } repeat + end +put % errordict /rangecheck +.clearerror +/devicenames devicedict { pop } forall devicedict length packedarray def + +% Determine the default device. +/defaultdevice DISPLAYING + { systemdict /DEVICE .knownget + { devicedict 1 index known not + { (Unknown device: ) print = + flush /defaultdevice cvx 1 .quit + } + if + } + { .getdefaultdevice .devicename + } + ifelse + } + { /nullpage + } +ifelse +/.defaultdevicename 1 index def +finddevice % make a copy +def +devicedict /Default devicedict .defaultdevicename get put + +(END DEVS) VMDEBUG + +% Define statusdict, for the benefit of programs +% that think they are running on a LaserWriter or similar printer. +%% Replace 1 (gs_statd.ps) +(gs_statd.ps) runlibfile + +(END STATD) VMDEBUG + +% Load the standard font environment. +%% Replace 1 (gs_fonts.ps) +(gs_fonts.ps) runlibfile + +(END GS_FONTS) VMDEBUG + +% Define the default halftone screen and BG/UCR functions now, so that +% it will bind in the original definitions of set[color]screen. +% We make this a procedure so we can call it again when switching devices. + +% Use an ordered dither for low-resolution devices. +/.setloreshalftone { % <dpi> .setloreshalftone - + % The following 'ordered dither' spot function was contributed by + % Gregg Townsend. Thanks, Gregg! + 16.001 div 0 % not 16: avoids rounding problems + { 1 add 7.9999 mul cvi exch 1 add 7.9999 mul cvi 16 mul add < + 0E 8E 2E AE 06 86 26 A6 0C 8C 2C AC 04 84 24 A4 + CE 4E EE 6E C6 46 E6 66 CC 4C EC 6C C4 44 E4 64 + 3E BE 1E 9E 36 B6 16 96 3C BC 1C 9C 34 B4 14 94 + FE 7E DE 5E F6 76 D6 56 FC 7C DC 5C F4 74 D4 54 + 01 81 21 A1 09 89 29 A9 03 83 23 A3 0B 8B 2B AB + C1 41 E1 61 C9 49 E9 69 C3 43 E3 63 CB 4B EB 6B + 31 B1 11 91 39 B9 19 99 33 B3 13 93 3B BB 1B 9B + F1 71 D1 51 F9 79 D9 59 F3 73 D3 53 FB 7B DB 5B + 0D 8D 2D AD 05 85 25 A5 0F 8F 2F AF 07 87 27 A7 + CD 4D ED 6D C5 45 E5 65 CF 4F EF 6F C7 47 E7 67 + 3D BD 1D 9D 35 B5 15 95 3F BF 1F 9F 37 B7 17 97 + FD 7D DD 5D F5 75 D5 55 FF 7F DF 5F F7 77 D7 57 + 02 82 22 A2 0A 8A 2A AA 00 80 20 A0 08 88 28 A8 + C2 42 E2 62 CA 4A EA 6A C0 40 E0 60 C8 48 E8 68 + 32 B2 12 92 3A BA 1A 9A 30 B0 10 90 38 B8 18 98 + F2 72 D2 52 FA 7A DA 5A F0 70 D0 50 F8 78 D8 58 + > exch get 256 div + } + bind + % Use correct, per-plane screens for CMYK devices only. + //systemdict /setcolorscreen known processcolors 4 eq and + { 3 copy 6 copy //setcolorscreen } + { //setscreen } + ifelse +} bind def +/.setloresscreen { % <dpi> .setloresscreen - + .setloreshalftone + 0 array cvx settransfer % Genoa CET won't accept a packed array! + /setstrokeadjust where { pop //true setstrokeadjust } if +} bind def +% Use a 45-degree spot screen for high-resolution devices. +% The PS3 CET insists that the screen be an array and not a packedarray (!). +currentpacking //false setpacking +/.linescreen +% The following screen algorithm is used by permission of the author. + { ((C) 1989 Berthold K.P. Horn) pop + 1 add 180 mul cos 1 0.08 add mul exch 2 add 180 mul cos + 1 0.08 sub mul add 2 div + } +bind readonly def +setpacking +/.sethireshalftone { % <dpi> .sethireshalftone <doscreen> + % According to information published by Hewlett-Packard, + % they use a 60 line screen on 300 DPI printers and + % an 85 line screen on 600 DPI printers. + % However, we use a 106 line screen, which produces smoother- + % looking shades but fewer of them (32 vs. 50). + % 46 was suggested as a good frequency value for printers + % between 200 and 400 DPI, so we use it for lower resolutions. + % Imagesetters need even higher frequency screens. + //systemdict /DITHERPPI known + { DITHERPPI + } + { dup cvi 100 idiv 15 .min + {//null 46 46 60 60 60 106 106 106 106 133 133 133 133 133 150} + exch get + } + ifelse + 1 index 4.01 div .min % at least a 4x4 cell + 45 + //.linescreen + % Determine whether we have lots of process colors. + % If so, don't bother with color screening or gamma correction. + % Also don't do gamma correction on very high-resolution devices. + % (This should depend on dot gain, not resolution, but we don't + % currently have a way to determine this.) Ignore missing components + % (*Values = 1). + currentdevice mark + /RedValues 0 /GreenValues 0 /BlueValues 0 /GrayValues 0 + .dicttomark .getdeviceparams + counttomark 2 idiv 1 sub + { exch pop dup 1 le + { pop } + { exch dup 1 le + { pop } + { .min } + ifelse + } + ifelse + } + repeat + exch pop exch pop 32 lt 4 index 800 lt and 5 1 roll + % Stack: doscreen dpi freq angle proc + % Ghostscript currently doesn't use correct, per-plane halftones + % unless setcolorscreen has been executed. Since these are + % computationally much more expensive than binary halftones, + % we check to make sure they are really warranted, i.e., we have + % a high-resolution CMYK device (i.e., not a display) with + % fewer than 5 bits per plane (i.e., not a true-color device). + 4 -1 roll 150 ge + { /setcolorscreen where + { pop //systemdict /COLORSCREEN known + { COLORSCREEN } + { 3 index } + ifelse + dup //false ne + { 4 1 roll 3 copy 6 copy 13 -1 roll + % For really high-quality screening on printers, we need to + % give each plane its own screen angle. Unfortunately, + % this currently has very large space and time costs. + //true eq % true => different angles, + % 0 => same angles + { { 45 90 15 75 } { 3 1 roll exch pop 12 3 roll } forall + } + if //setcolorscreen + } + { pop //setscreen % false => single binary screen + } + ifelse + } + { //setscreen % setcolorscreen not known + } + ifelse + } + { //setscreen % not high resolution + } + ifelse +} bind def +/.sethiresscreen { % <dpi> .sethiresscreen + .sethireshalftone % pushes true if a screen halftone used + % Stack: doscree + { + % Set the transfer function to lighten up the grays. + % Parameter values closer to 1 are better for devices with + % less dot spreading; lower values are better with more spreading. + % The value 0.8 is a compromise that will probably please no one! + % + % Because of a bug in FrameMaker, we have to accept operands + % outside the valid range of [0..1]. + { + dup dup 0.0 gt exch 1.0 lt and + { + 0.8 exp + } + if + } + } + { + % Set the transfer function to the identity. + 0 array cvx % Genoa CET won't accept a packed array! + } + ifelse + settransfer + /setstrokeadjust where + { pop //false setstrokeadjust } + if + + % Increase fill adjustment so that we effectively use Adobe's + % any-part-of-pixel rule. + 0.5 .setfilladjust +} bind def +% Set the default screen and BG/UCR. +/.setdefaultbgucr { + systemdict /setblackgeneration known { + { pop 0 } dup setblackgeneration setundercolorremoval + } if +} bind def +/.useloresscreen { % - .useloresscreen <bool> + % Compute min(|dpi x|,|dpi y|) as the definition of the resolution. + 72 72 matrix defaultmatrix dtransform abs exch abs .min + dup 150 lt //systemdict /DITHERPPI known not and +} bind def + +% The following implementation uses LL2 extensions, but only in stopped +% contexts so that with LL1, the .set??reshalftone will be used. +% +% - .getdefaulthalftone <halftonedict> true if default found +% false +/.getdefaulthalftone { + % try the device to see if it has a default halftone + { currentdevice /HalftoneDefault gsgetdeviceprop } .internalstopped + { pop pop //false } % no device property + { dup type /dicttype eq { //true } { pop //false } ifelse } + ifelse + % stack: <halftonedict> true if default found + % false not found + dup not + { % device did not provide a default, try Resource + pop { /Default /Halftone /findresource .systemvar exec } .internalstopped + { pop pop //false } { //true } ifelse + } + if +} bind def + +/.setdefaulthalftone { + .getdefaulthalftone + { sethalftone } + { % default not found + .useloresscreen { .setloreshalftone } { .sethireshalftone pop } ifelse + } + ifelse +} bind def + +/.setdefaultscreen { + .useloresscreen { .setloresscreen } { .sethiresscreen } ifelse + .setdefaultbgucr +} bind def + +% Rendering intent mapping for setcolorrendering1 and PDF interpreter +/.renderingintentdict mark + /Perceptual 0 + /RelativeColorimetric 1 + /Saturation 2 + /AbsoluteColorimetric 3 +.dicttomark readonly def + +% Load basic color support +%% Replace 1 (gs_cspace.ps) +(gs_cspace.ps) runlibfile + +(END BASIC COLOR) VMDEBUG + +% Load image support +%% Replace 1 (gs_img.ps) +(gs_img.ps) runlibfile + +(END IMAGE) VMDEBUG + +% Auxiliary procedures for generating file name templates. + +% Convert a path name into a string suitable for filenameforall +% For example: (a\\b*?c) to (a\\\\b\\*\\?c) +/.makepathtemplate { % str1 -- str2 + dup length dup add string 0 % result string up to twice the size + 0 1 4 index length 1 sub { + 3 index exch get + dup 92 eq { % \ -> \\ + 2 index 2 index 92 + put + exch 1 add exch + } + if + dup 42 eq { % * -> \* + 2 index 2 index 92 + put + exch 1 add exch + } + if + dup 63 eq { % ? -> \? + 2 index 2 index 92 + put + exch 1 add exch + } + if + 2 index 2 index 3 -1 roll put 1 add + } for + 0 exch getinterval exch pop +} bind def + +% false <dir_list> <template> .generate_dir_list_templates_with_length <t1> ... <tN> +% true <dir_list> <template> .generate_dir_list_templates_with_length <t1> <l1> ... <tN> <ln> +% +% Generates various valid templates combining a directory list with a given template. +% With 'true' operand it also returns lengths of directory pathes. +% +% Example1 (DOS, Windows) : +% false [(/gs/lib) (/gs/Resource/) (\gs8.00\Resource)] (*/*) --> +% (/gs/lib/*/*) (/gs/Resource/*/*) (\\gs8.00\\Resource/*/*) +% +% Example2 (OpenVMS) : +% false [(gs:[lib]) (gs:[Resource]) (gs800:[Resource)] (*]*) --> +% ((gs:[lib.*]*) [gs:[Resource.*]*) ([gs800:[Resource.*]*) +% +/.generate_dir_list_templates_with_length +{ % [dl] (templ) + % We need to convert paths into templates, + % because it can include '\' on DOS. + % In same time, the <template> must not convert, + % because it is already a template. + % Besides that, we cannot combine template using .file_name_combine, + % because template syntax breaks the platform path syntax. + % To resolve this, we first convert the <template> into + % a fake filename, and combine it with path, + % obtaining a correct separator. Then we replace + % the fake file name with the given template. + % + + % Create the fake file name : + dup dup length string copy % b [dl] (templ) (ffn) + (*) 0 get (?) 0 get (\\) 0 get (x) 0 get 0 0 % b [dl] (templ) (ffn) * ? \ x i j + { 1 index 7 index length ge { exit } if + 6 index 2 index get % b [dl] (templ) (ffn) * ? \ x i j c + dup 7 index eq % b [dl] (templ) (ffn) * ? \ x i j c bool + 1 index 7 index eq or { % *? + pop 2 index + } if % b [dl] (templ) (ffn) * ? \ x i j C + dup 5 index eq { % \ + 3 2 roll 1 add 3 1 roll % b [dl] (templ) (ffn) * ? \ x i' j C + 2 index 8 index length ge { pop exit } if + pop 6 index 2 index get % b [dl] (templ) (ffn) * ? \ x i' j C' + } if + 7 index 2 index 3 2 roll put % b [dl] (templ) (ffn) * ? \ x i' j + 1 add exch 1 add exch % b [dl] (templ) (ffn) * ? \ x i'' j' + } loop % b [dl] (templ) (ffn) * ? \ x i j + 6 1 roll pop % b [dl] (templ) (ffn) j * ? \ x + exch pop exch pop exch pop exch % b [dl] (templ) (ffn) x j + { dup 3 index length ge { exit } if + 3 copy exch put + 1 add + } loop + pop pop % b [dl] (templ) (ffn) + + % An internal procedure : + { % {} b [dl] (templ) (ffn) (dffn) + dup length + 2 index length sub % drop "ffn", remaining "ldffn" = length of the "directory" part + exch % {} b [dl] (templ) (ffn) ldffn (dffn) + .makepathtemplate % {} b [dl] (templ) (ffn) ldffn (Dffn) + dup % {} b [dl] (templ) (ffn) ldffn (Dffn) (Dffn) + 4 index length dup % {} b [dl] (templ) (ffn) ldffn (Dffn) (Dffn) templL templL + 2 index length % {} b [dl] (templ) (ffn) ldffn (Dffn) (Dffn) templL templL DffnL + exch sub % {} b [dl] (templ) (ffn) ldffn (Dffn) (Dffn) templL i + exch getinterval % {} b [dl] (templ) (ffn) ldffn (Dffn) (suffix) + 4 index exch copy pop % {} b [dl] (templ) (ffn) ldffn (dt) + 5 index { + exch % {} b [dl] (templ) (ffn) (dt) ldffn + 7 2 roll % (dt) ldffn {} b [dl] (templ) (ffn) + } { + exch pop % {} b [dl] (templ) (ffn) (dt) + 6 1 roll % (dt) {} b [dl] (templ) (ffn) + } ifelse + } + 5 1 roll % {} b [dl] (templ) (ffn) + + % Generate templates : + dup .file_name_is_absolute { + dup % {} b [dl] (templ) (ffn) (ffn) + 5 index exec % (t1) {} b [dl] (templ) (ffn) + } { + 2 index { % ... {} b [dl] (templ) (ffn) (d) + 1 index % ... {} b [dl] (templ) (ffn) (d) (ffn) + //false .file_name_combine { % ... {} b [dl] (templ) (ffn) (dffn) + 5 index exec % ... (t1) ?l1 {} b [dl] (templ) (ffn) + } { % ... {} b [dl] (templ) (ffn) (d) (ffn) + pop pop % ... {} b [dl] (templ) (ffn) + } ifelse + } forall + } ifelse % (t1) ?l1 (t2) ?l2 ... (tN) ?ln {} b [dl] (templ) (ffn) + pop pop pop pop pop % (t1) ?l1 (t2) ?l2 ... (tN) ?ln +} bind def + +% <dir_list> <template> .generate_dir_list_templates <t1> ... <tN> +% +% Generates various valid templates combining a directory list with a given template. +% It's the 'false' case of the function above. +% +/.generate_dir_list_templates +{ //false 3 1 roll //.generate_dir_list_templates_with_length exec +} bind def + +% Load the initialization files for optional features. +%% Replace 4 INITFILES +systemdict /INITFILES known + { INITFILES { <00> search { exch pop dup runlibfile VMDEBUG }{ dup runlibfile VMDEBUG exit } ifelse } .bind loop + } +if + +% If Level 2 (or higher) functionality is implemented, enable it now. +/.setlanguagelevel where { + pop 2 .setlanguagelevel + % If the resource machinery is loaded, fix up some things now. + /.fixresources where { pop .fixresources } if +} if +/ll3dict where { + pop 3 .setlanguagelevel +} if + +(END INITFILES) VMDEBUG + +% Create a null font. This is the initial font. +8 dict dup begin + /FontMatrix [ 1 0 0 1 0 0 ] readonly def + /FontType 3 def + /FontName () def + /Encoding StandardEncoding def + /FontBBox { 0 0 0 0 } readonly def % executable is bogus, but customary ... + /BuildChar { pop pop 0 0 setcharwidth } bind def + /PaintType 0 def % shouldn't be needed! +end +/NullFont exch definefont setfont + +% Define NullFont as the font. +/NullFont currentfont def + +% Load initial fonts from FONTPATH directories, Fontmap file, +% and/or .getccfont as appropriate. +.loadinitialfonts + +% Remove NullFont from FontDirectory, so it can't be accessed by mistake. +/undefinefont where { + pop /NullFont undefinefont +} { + FontDirectory /NullFont .undef +} ifelse + +(END FONTS) VMDEBUG + +% Restore the real definition of runlibfile. +/runlibfile /.runlibfile load def +currentdict /.runlibfile .undef + +% Bind all the operators defined as procedures. +/.bindoperators % binds operators in currentdict + { % Temporarily disable the typecheck error. + errordict /typecheck 2 copy get + errordict /typecheck { pop } put % pop the command + currentdict + { dup type /operatortype eq + { % This might be a real operator, so bind might cause a typecheck, + % but we've made the error a no-op temporarily. + .bind % do a real bind even if NOBIND is set + } + if pop pop + } forall + put + } def +NOBIND DELAYBIND or not { .bindoperators } if + +% Establish a default environment. + +defaultdevice +% The following line used to skip setting of page size and resolution if +% NODISPLAY was selected. We think this was only to save time and memory, +% and it is a bad idea because it prevents setting the resolution in this +% situation, which pstoedit (among other programs) relies on. +%DISPLAYING not { setdevice (%END DISPLAYING) .skipeof } if + +% If the paper size is not specifed and the device defaults to +% letter or A4 paper, select the DEFAULTPAPERSIZE. +systemdict /DEFAULTPAPERSIZE known not { + % Use .defaultpapersize if it returns a known paper size + .defaultpapersize { + statusdict /.pagetypeprocs get 1 index known { + systemdict exch /DEFAULTPAPERSIZE exch put + } { + QUIET { + pop + } { + (Unknown .defaultpapersize: ) print ==only (.) = + } ifelse + } ifelse + } if +} if +systemdict /DEFAULTPAPERSIZE known +systemdict /PAPERSIZE known not and +systemdict /DEVICEWIDTH known not and +systemdict /DEVICEHEIGHT known not and +systemdict /DEVICEWIDTHPOINTS known not and +systemdict /DEVICEHEIGHTPOINTS known not and + { + defaultdevice mark /PageSize //null .dicttomark .getdeviceparams + .dicttomark /PageSize get + dup 0 get 0.5 add cvi 612 eq 1 index 1 get 0.5 add cvi 792 eq and + 1 index 0 get 0.5 add cvi 595 eq 2 index 1 get 0.5 add cvi 842 eq and + or exch pop + { + % the default paper size was letter, so replace it with DEFAULTPAPERSIZE + /PAPERSIZE DEFAULTPAPERSIZE def + } if + } +if + +systemdict /DEVICEWIDTH known +systemdict /DEVICEHEIGHT known or +systemdict /DEVICEWIDTHPOINTS known or +systemdict /DEVICEHEIGHTPOINTS known or +systemdict /DEVICEXRESOLUTION known or +systemdict /DEVICEYRESOLUTION known or +systemdict /PAPERSIZE known or +not { (%END DEVICE) .skipeof } if +% Let DEVICE{WIDTH,HEIGHT}[POINTS] override PAPERSIZE. +systemdict /PAPERSIZE known +systemdict /DEVICEWIDTH known not and +systemdict /DEVICEHEIGHT known not and +systemdict /DEVICEWIDTHPOINTS known not and +systemdict /DEVICEHEIGHTPOINTS known not and { + % Convert the paper size to device dimensions. + statusdict /.pagetypeprocs get PAPERSIZE .knownget { + dup 0 get /DEVICEWIDTHPOINTS exch def + 1 get /DEVICEHEIGHTPOINTS exch def + } { + (Unknown paper size: ) print PAPERSIZE ==only (.) = + } ifelse +} if +% Adjust the device parameters per the command line. +% It is possible to specify resolution, pixel size, and page size; +% since any two of these determine the third, conflicts are possible. +% We simply pass them to .setdeviceparams and let it sort things out. + mark /HWResolution //null /HWSize //null /PageSize //null .dicttomark + .getdeviceparams .dicttomark begin + mark + % Check for resolution. + /DEVICEXRESOLUTION where dup + { exch pop HWResolution 0 DEVICEXRESOLUTION put } + if + /DEVICEYRESOLUTION where dup + { exch pop HWResolution 1 DEVICEYRESOLUTION put } + if + or { /HWResolution HWResolution } if + % Check for device sizes specified in pixels. + /DEVICEWIDTH where dup + { exch pop HWSize 0 DEVICEWIDTH put } + if + /DEVICEHEIGHT where dup + { exch pop HWSize 1 DEVICEHEIGHT put } + if + or { /HWSize HWSize } if + % Check for device sizes specified in points. + /DEVICEWIDTHPOINTS where dup + { exch pop PageSize 0 DEVICEWIDTHPOINTS put } + if + /DEVICEHEIGHTPOINTS where dup + { exch pop PageSize 1 DEVICEHEIGHTPOINTS put } + if + or { /PageSize PageSize } if + % Check whether any parameters were set. + dup mark eq { pop defaultdevice } { defaultdevice putdeviceprops } ifelse + end +%END DEVICE +% Set any device properties defined on the command line. +% If BufferSpace is defined but not MaxBitmap, set MaxBitmap to BufferSpace. +systemdict /BufferSpace known +systemdict /MaxBitmap known not and + { systemdict /MaxBitmap BufferSpace put + } if +dup getdeviceprops +counttomark 2 idiv + { systemdict 2 index known + { pop dup load counttomark 2 roll } + { pop pop } + ifelse + } repeat +counttomark dup 0 ne + { 2 add -1 roll putdeviceprops } + { pop pop } +ifelse +% If the initial device parameters are invalid, the setdevice may fail. +% Trap this and produce a reasonable error message. +{ setdevice } % does an erasepage +INITDEBUG { exec //false } { .internalstopped } ifelse { + (**** Unable to open the initial device, quitting.) = flush 1 .quit +} if + +% If the media size is fixed, update the current page device dictionary. +FIXEDMEDIA +dup { pop systemdict /.currentpagedevice known } if +dup { pop .currentpagedevice exch pop } if +not { (%END MEDIA) .skipeof } if +currentpagedevice dup length dict .copydict +dup /Policies + % Stack: <pagedevice> <pagedevice> /Policies +1 index /InputAttributes +2 copy get dup length dict .copydict + % Stack: <pagedevice> <pagedevice> /Policies <pagedevice> + % /InputAttributes <inputattrs'> +dup 0 2 copy get dup length dict .copydict + % Stack: <pagedevice> <pagedevice> /Policies <pagedevice> + % /InputAttributes <inputattrs'> <inputattrs'> 0 <attrs0'> +dup /PageSize 7 index /PageSize get +put % PageSize in 0 +put % 0 in InputAttributes +put % InputAttributes in pagedevice +% Also change the page size policy so we don't get an error. + % Stack: <pagedevice> <pagedevice> /Policies +2 copy get dup length dict .copydict + % Stack: <pagedevice> <pagedevice> /Policies <policies'> +dup /PageSize 7 put % PageSize in Policies +put % Policies in pagedevice +.setpagedevice +%END MEDIA + +% Set up the interpreter context version of -dUSeCIEColor option +% so that .getuseciecolor has the correct value (see gs_setpd.ps) +/setpagedevice where { + pop systemdict /UseCIEColor known { + mark /UseCIEColor UseCIEColor /..StartupGlobal //true .dicttomark setpagedevice + } if +} if + +%END DISPLAYING + +(END DEVICE) VMDEBUG + +% Establish a default upper limit in the character cache, +% namely, enough room for a 18-point character at the resolution +% of the default device, or for a character consuming 1% of the +% maximum cache size, whichever is larger. +mark + % Compute limit based on character size. + 18 dup dtransform + exch abs cvi 31 add 32 idiv 4 mul % X raster + exch abs cvi mul % Y + % Compute limit based on allocated space. + cachestatus pop pop pop pop pop exch pop 0.01 mul cvi + .max dup 10 idiv exch +setcacheparams +% Conditionally disable the character cache. +NOCACHE { 0 setcachelimit } if + +(END CONFIG) VMDEBUG + +% Initialize graphics. + +.setdefaultscreen +initgraphics + +% The interpreter relies on there being at least 2 entries +% on the graphics stack. Establish the second one now. +gsave + +% Define some control sequences as no-ops. +% This is a hack to get around problems +% in some common PostScript-generating applications. +<04> cvn JOBSERVER { + { { clear cleardictstack //false 0 .startnewjob } 2 .stop } bind + } { + { } + } ifelse def +<1b> cvn { % UEL is <esc>%-12345X and acts the same as ^D + currentfile (%-12345X) .peekstring pop (%-12345X) eq <04> cvn load if +} bind def +<1b45> cvn { } def % PJL reset prologue (ESC E) +<1b451b> cvn <1b> cvn load def % PJL reset epilogue (ESC E + UEL) +(\001M) cvn % TBCP initiator + { currentfile /TBCPDecode filter cvx exec + } bind def +/@PJL % H-P job control + { + % Windows 2000 driver includes PJL into %%BeginFeature block. + % Identify this from the pattern on the stack: countdictstack lucas mark + % and fail the feature request. + + count 3 ge { + dup mark eq { + 2 index countdictstack eq { + 1 index /lucas where { /lucas get eq } { pop //false } ifelse { + stop + } if + } if + } if + } if + currentfile //=string readline pop pop + } bind def + +% Install the EPS handler if needed +systemdict /EPSBoundingBoxInit known { EPSBoundingBoxInit } if + +% If we want a "safer" system, disable some obvious ways to cause havoc. +.currentglobal //true .setglobal +/SAFETY 2 dict + dup /safe //false put + dup /tempfiles 10 dict readonly put +readonly def +.setglobal + +/.locksafe_userparams { + SAFETY /safe get not { + << + /PermitFileReading [ + currentuserparams /PermitFileReading get aload pop + /FONTPATH .systemvar (*) .generate_dir_list_templates + % Library files : + /LIBPATH .systemvar (*) .generate_dir_list_templates + % Resource files on OpenVMS requires a separate template (gs:[dir.*]*) + % because the (gs:[dir]*) doesn't cover them. + /LIBPATH .systemvar (*) .file_name_separator (*) + concatstrings concatstrings .generate_dir_list_templates + .languagelevel 2 ge { + % Default resources : + [ currentsystemparams /GenericResourceDir get] (*) .generate_dir_list_templates + % Default resources (OpenVMS, see comment above.) : + [ currentsystemparams /GenericResourceDir get] (*) .file_name_separator (*) + concatstrings concatstrings .generate_dir_list_templates + } if + ] + /LockFilePermissions //true + >> setuserparams + } + if +} bind def + +/.locksafe { + .locksafe_userparams + systemdict /getenv {pop //false} .forceput + % setpagedevice has the side effect of clearing the page, but + % we will just document that. Using setpagedevice keeps the device + % properties and pagedevice .LockSafetyParams in agreement even + % after a restore that changes the value to false. + currentglobal currentpagedevice gcheck setglobal % use correct VM space + << /.LockSafetyParams //true >> setpagedevice + setglobal + //SAFETY /safe //true .forceput % overrides readonly +} .bind executeonly odef + +%% This is only used during startup. Its required so that +%% we can detect in setpagdevice that we are in fact in startup +%% and allocate a *global* instead of local VM. We need it to be +%% global to satisfy Display PostScript (see start of /setpagdevice +%% in gs_setpd.ps) +%% +/.locksafeglobal { + .locksafe_userparams + systemdict /getenv {pop //false} put + % setpagedevice has the side effect of clearing the page, but + % we will just document that. Using setpagedevice keeps the device + % properties and pagedevice .LockSafetyParams in agreement even + % after a restore that changes the value to false. + currentglobal currentpagedevice gcheck setglobal % use correct VM space + << /.LockSafetyParams //true + /..StartupGlobal //true + >> setpagedevice + setglobal + //SAFETY /safe //true .forceput % overrides readonly +} .bind executeonly odef + +/.setsafe +{ + SAFETY /safe get not { + << + /PermitFileReading [ ] + /PermitFileWriting [ ] + /PermitFileControl [ ] + >> setuserparams + } + if + .locksafe +} .bind executeonly odef + +%% See /.locksafeglobal above. +%% +/.setsafeglobal { + SAFETY /safe get not { + << + /PermitFileReading [ ] + /PermitFileWriting [ ] + /PermitFileControl [ ] + >> setuserparams + } + if + .locksafeglobal +} bind executeonly odef + +/deletefile { + dup { deletefile } stopped { + pop //deletefile $error /errorname get signalerror + } { + % deletefile succeeded. Remove from tempfile list if present + //SAFETY /tempfiles get exch cvn 2 copy known { + .forceundef + } { + pop pop + } + ifelse + } + ifelse +} .bind executeonly odef + +% If a file is opened with .tempfile with SAFER not (yet) set, +% the file can be deleted later, even if SAFER is set. +/.tempfile { + .tempfile % filename file + //SAFETY /tempfiles get 2 .argindex //true .forceput +} .bind executeonly odef + +% If we are running in SAFER mode, lock things down +SAFER { .setsafeglobal } if + +% If we delayed binding, make it possible to do it later. +/.bindnow { + currentuserparams /IdiomRecognition .knownget { + 1 dict dup /IdiomRecognition //false put setuserparams + } if + //systemdict begin .bindoperators end + % Temporarily disable the typecheck error. + errordict /typecheck 2 copy get + errordict /typecheck { pop } put % pop the command + 0 1 .delaycount 1 sub { .delaybind exch get .bind pop } for + //systemdict /.delaybind {} .forceput % reclaim the space + //systemdict /.bindnow .forceundef % ditto + put + //systemdict /.forcecopynew .forceundef % remove temptation + //systemdict /.forcedef .forceundef % ditto + //systemdict /.forceput .forceundef % ditto + //systemdict /.forceundef .forceundef % ditto + currentuserparams /IdiomRecognition known { + 1 dict dup /IdiomRecognition 4 -1 roll put setuserparams + } if +} .bind odef + +% Turn off array packing, since some PostScript code assumes that +% procedures are writable. +//false setpacking + +(END INIT) VMDEBUG + +/.currentuserparams where { + pop + % Remove real user params from psuserparams. + mark .currentuserparams counttomark 2 idiv { + pop psuserparams exch undef + } repeat pop + % Update the copy of the user parameters. + mark .currentuserparams counttomark 2 idiv { + userparams 3 1 roll .forceput % userparams is read-only + } repeat pop + % Turn on idiom recognition, if available. + currentuserparams /IdiomRecognition known { + /IdiomRecognition //true .definepsuserparam + } if + psuserparams readonly pop + systemdict /.definepsuserparam undef + % Save a copy of userparams for use with save/restore + % (and, if implemented, context switching). + .currentglobal //false .setglobal + mark userparams { } forall .dicttomark readonly + /userparams exch .forcedef % systemdict is read-only + .setglobal +} if +/.currentsystemparams where { + pop + % Remove real system params from pssystemparams. + mark .currentsystemparams counttomark 2 idiv { + pop pssystemparams exch .forceundef + } repeat pop +} if + +% Set up AlignToPixels : + +/AlignToPixels where { + mark /AlignToPixels 2 index /AlignToPixels get .dicttomark setuserparams + /AlignToPixels undef +} if + +% Set up GridFitTT : + +/GridFitTT where { + mark /GridFitTT 2 index /GridFitTT get .dicttomark setuserparams + /GridFitTT undef +} if + +% Establish local VM as the default. +//false /setglobal where { pop setglobal } { .setglobal } ifelse +$error /.nosetlocal //false put + +(END GLOBAL) VMDEBUG + +%% .savelocalstate is part of Display PostScript (if included). Part of the function of +%% the .savelocalstate routine is to store the 'initial saved gstate' (savedinitialgstate) +%% in systemdict. The code in dps1.c, gstate_check_space, disallows writing or creating +%% gstates in global VM in certain conditions. If we execute setpagedevice before we +%% reach this point, we must ensure that we do so using /..StartupGlobal so that +%% the dictionary is defined in global VM, because the gstate contains a pointer to the +%% device dictionary, and if that is allocated in local VM we will fail the gstate check. +/.savelocalstate where { + % If we might create new contexts, save away copies of all dictionaries + % referenced from systemdict that are stored in local VM, + % and also save a copy of the initial gstate. + pop .savelocalstate +} { + % If we're *not* running in a multi-context system and FAKEFONTS is + % defined, add the fake fonts to LocalFontDirectory. + .definefakefonts % current VM is local +} ifelse + +% Execute scheduled inits : +//.execute_scheduled_inits exec +currentdict /.execute_scheduled_inits undef +currentdict /.delayed_init_queue undef + +% Make global and local FontDirectory read-only. +FontDirectory readonly pop +/GlobalFontDirectory where { pop GlobalFontDirectory readonly pop } if + +% Remove systemdict entries for things that have been bound in where used +% and that shouldn't be accessible by name, and close up systemdict. +currentdict /filterdict .undef +currentdict /.cidfonttypes .undef +currentdict /.colorrenderingtypes .undef +currentdict /.formtypes .undef +currentdict /.halftonetypes .undef +currentdict /.imagetypes .undef +currentdict /.imagemasktypes .undef +currentdict /.patterntypes .undef +currentdict /.shadingtypes .undef +currentdict /.wheredict .undef +currentdict /.renderingintentdict .undef +end + +% Clean up VM, and enable GC. Use .vmreclaim to force the GC. +/vmreclaim where + { pop NOGC not { 2 .vmreclaim 0 vmreclaim } if + } if +DELAYBIND not { + systemdict /.forcecopynew .undef % remove temptation + systemdict /.forcedef .undef % ditto + systemdict /.forceput .undef % ditto + systemdict /.forceundef .undef % ditto +} if +% Move superexec to internaldict if superexec is defined. +currentdict /superexec .knownget { + 1183615869 internaldict /superexec 3 -1 roll put + currentdict /superexec .undef +} if +WRITESYSTEMDICT not { systemdict readonly pop } if +(END GC) VMDEBUG + +% The Adobe AGM_Core used by Illustrator 9 has some code that breaks +% if the 'product' is not (Adobe PostScript Parser). A bug has been +% submitted to Adobe since this also fails with Acrobat Distiller. +% As a temporary work around, the following HACK will work for +% devices without spot color support. Once Ghostscript can +% support DeviceN and spot color separations this will need to +% be 'true' in some cases. +userdict /AGM_preserve_spots //false put + +% The interpreter will run the initial procedure (start). diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_l2img.ps b/Master/tlpkg/tlgs/Resource/Init/gs_l2img.ps new file mode 100644 index 00000000000..c24f3d6bf0f --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_l2img.ps @@ -0,0 +1,183 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Emulate the Level 2 dictionary-based image operator in Level 1, +% except for Interpolate (ignored) and MultipleDataSources = true; +% also, we require that the data source be either a procedure of a +% particular form or a stream, not a string or a general procedure. + +% pdf2ps copies the portion of this file from %BEGIN to %END if Level 1 +% compatible output is requested. + +/currentglobal where + { pop currentglobal { setglobal } //true setglobal } + { { } } +ifelse + +/packedarray where + { pop } + { /packedarray { array astore readonly } bind def } +ifelse + +%BEGIN + +11 dict /.csncompdict 1 index def begin + /DeviceGray { 1 /setgray load } bind def + /DeviceRGB { 3 /setrgbcolor load } bind def + /DeviceCMYK { 4 /setcmykcolor load } bind def + /Indexed + { dup 1 index 1 get //.csncompdict exch get exec + % Stack: [/Indexed base hival map] ncomp basesetcolor + 3 -1 roll 3 get mark 3 1 roll + % Stack: ncomp -mark- basesetcolor map + dup type /stringtype eq + { { - + { exch round cvi get 255 div + } + - + { exch round cvi 3 mul 2 copy 2 copy get 255 div + 3 1 roll 1 add get 255 div + 4 2 roll 2 add get 255 div + } + { exch round cvi 4 mul 2 copy 2 copy 2 copy get 255 div + 3 1 roll 1 add get 255 div + 4 2 roll 2 add get 255 div + 5 3 roll 3 add get 255 div + } + } + 4 index get aload pop counttomark -1 roll + } + { /exec load 3 -1 roll + % Stack: -mark- mapproc --exec-- basesetcolor + } + ifelse .packtomark cvx + exch pop 1 exch + } bind def + /Separation + { dup 2 index //.csncompdict exch get exec + % Stack: [/Separation name alt xform] ncomp altsetcolor + 3 -1 roll 3 get /exec load 3 -1 roll 3 array astore readonly cvx + exch pop 1 exch + } bind def + % Substitute device spaces for CIE spaces. + /CIEBasedA /DeviceGray load def + /CIEBasedABC /DeviceRGB load def + /CIEBasedDEF /DeviceRGB load def + /CIEBasedDEFG /DeviceCMYK load def +end + +/.packtomark { counttomark packedarray exch pop } bind def + +/.csinextbits % - .csinextbits <bits> + % Uses b, nnb, i, row, mask, BitsPerComponent; + % sets b, nnb, i. + { /nnb nnb BitsPerComponent add + { dup 0 le { exit } if + /b b 8 bitshift row i get add def + /i i 1 add def 8 sub + } + loop def + b nnb bitshift mask and + } bind def + +% Note that the ColorSpace key must be present in the image dictionary. +/.colorspaceimage % <imagedict> .colorspaceimage - + { save exch + dup length 15 add dict begin { cvlit def } forall + ColorSpace dup dup type /nametype ne { 0 get } if + .csncompdict exch get exec + /setpixelcolor exch def /ncomp exch def pop + /row ncomp BitsPerComponent mul Width mul 7 add 8 idiv string def + /mask 1 BitsPerComponent bitshift 1 sub def + /nextbits BitsPerComponent 8 eq + { { row i get /i i 1 add def } } + { /.csinextbits load } + ifelse def + /nextpixel mark 0 2 ncomp 1 sub 2 mul + { /nextbits cvx exch + Decode exch 2 getinterval + dup aload pop exch sub + dup mask eq { pop } { mask div /mul load 3 -1 roll } ifelse + 0 get dup 0 eq { pop } { /sub load 3 -1 roll } ifelse + } + for + /setpixelcolor load dup type /operatortype ne { /exec load } if + .packtomark cvx def + /readrow + /DataSource load dup type + dup /arraytype eq exch /packedarraytype eq or + { % Must be { <file> <string> ... } + aload length 1 add array /pop load exch astore + dup 1 row put cvx + } + { pop + % Adobe requires readstring to signal an error if given + % an empty string. Work around this nonsense here. + row length 0 eq + { { } } + { { DataSource row readstring pop pop } } + ifelse + } + ifelse def + ImageMatrix matrix invertmatrix concat + /imat matrix def + 0 1 Height 1 sub + { imat 5 3 -1 roll neg put + readrow + /b 0 def /nnb 0 def /i 0 def + 0 1 Width 1 sub + { imat 4 3 -1 roll neg put nextpixel + 1 1 //true imat {<80>} imagemask + } + for + } + for + end restore + } bind def + +%END +exec +currentfile closefile + +% Patch for testing. +/.cincompdict 3 dict begin + 1 { {0 1} {/DeviceGray} } def + 3 { {0 1 0 1 0 1} {/DeviceRGB} } def + 4 { {0 1 0 1 0 1 0 1} {/DeviceCMYK} } def +currentdict end def +/.imagekeys [ + /Decode /DataSource /ImageMatrix /BitsPerComponent /Height /Width +] def +/colorimage % <width> <height> <bits/comp> <matrix> + % <datasrc> false <ncomp> colorimage - + { 1 index { /colorimage .systemvar /rangecheck signalerror } if exch pop + //.cincompdict exch get exec + 7 dict begin /ColorSpace exch cvlit def + .imagekeys { exch cvlit def } forall + currentdict end .colorspaceimage + } bind odef +/image + { dup type /dicttype ne + { 7 dict begin /ColorSpace /DeviceGray def [0 1] + .imagekeys { exch cvlit def } forall + currentdict end + } + { dup length 1 add dict .copydict dup /ColorSpace currentcolorspace put + } + ifelse + .colorspaceimage + } bind odef + +exec diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_lev2.ps b/Master/tlpkg/tlgs/Resource/Init/gs_lev2.ps new file mode 100644 index 00000000000..93037388f8f --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_lev2.ps @@ -0,0 +1,1198 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Initialization file for Level 2 functions. +% When this is run, systemdict is still writable, +% but (almost) everything defined here goes into level2dict. + +level2dict begin + +% ------ System and user parameters ------ % + +% User parameters must obey save/restore, and must also be maintained +% per-context. We implement the former, and some of the latter, here +% with PostScript code. NOTE: our implementation assumes that user +% parameters change only as a result of setuserparams -- that there are +% no user parameters that are ever changed dynamically by the interpreter +% (although the interpreter may adjust the value presented to setuserparams) +% +% There are two types of user parameters: those which are actually +% maintained in the interpreter, and those which exist only at the +% PostScript level. We maintain the current state of both types in +% a read-only local dictionary named userparams, defined in systemdict. +% In a multi-context system, each context has its own copy of this +% dictionary. In addition, there is a constant dictionary named +% psuserparams where each key is the name of a user parameter that exists +% only in PostScript and the value is a procedure to check that the value +% is legal: setuserparams uses this for checking the values. +% setuserparams updates userparams explicitly, in addition to setting +% any user parameters in the interpreter; thus we can use userparams +% to reset those parameters after a restore or a context switch. +% NOTE: the name userparams is known to the interpreter, and in fact +% the interpreter creates the userparams dictionary. + +% Check parameters that are managed at the PostScript level. +/.checkparamtype { % <newvalue> <type> .checkparamtype <bool> + exch type eq +} .bind def +/.checksetparams { % <newdict> <opname> <checkdict> + % .checksetparams <newdict> + 2 .argindex { + % Stack: newdict opname checkdict key newvalue + 3 copy 3 1 roll .knownget { + exec not { + pop pop pop load /typecheck signalerror + } if + dup type /stringtype eq { + dup rcheck not { + pop pop pop load /invalidaccess signalerror + } if + } if + } { + pop + } ifelse pop pop + } forall pop pop +} .bind def % not odef, shouldn't reset stacks + +% currentuser/systemparams creates and returns a dictionary in the +% current VM. The easiest way to make this work is to copy any composite +% PostScript-level parameters to global VM. Currently we have strings +% as well as arrays. For arrays, we also need to copy any contents that +% are in VM. Also copying string parameters insures the contents won't +% be changed. Also be careful to preserve 'executable' state. +/.copyparam { % <value> .copyparam <value'> + dup type /arraytype eq { + .currentglobal //true .setglobal exch + dup wcheck exch dup xcheck exch % original attributes + dup length array exch dup { % stack: destination_array original_array original_array + dup type /arraytype eq { + dup 2 index ne { % avoid recursion + .copyparam % recurse to handle composite array elements + } { + % this array self referenced, do it again (yuk!) + pop 1 index % get copy of destination array + } ifelse + } { + dup type /stringtype eq { + .copyparam + } if + } + ifelse 3 1 roll % keep arrays on top + } forall pop astore + exch { cvx } if % set executable state + exch not { readonly } if % set readonly attribute as original + exch .setglobal + } if + dup type /stringtype eq { + dup wcheck exch % save attr for setting readonly + .currentglobal //true .setglobal + 1 index length string exch .setglobal + copy exch not { readonly } if + } if +} .bind def + +% Some user parameters are managed entirely at the PostScript level. +% We take care of that here. +systemdict begin +/psuserparams 48 dict def +/getuserparam { % <name> getuserparam <value> + /userparams .systemvar 1 .argindex get exch pop +} odef +% Fill in userparams (created by the interpreter) with current values. +mark .currentuserparams +counttomark 2 idiv { + userparams 3 1 roll put +} repeat pop +/.definepsuserparam { % <name> <value> .definepsuserparam - + psuserparams 3 copy pop + type cvlit /.checkparamtype cvx 2 packedarray cvx put + userparams 3 1 roll put +} .bind def +end +/currentuserparams { % - currentuserparams <dict> + /userparams .systemvar dup length dict .copydict +} odef +% We break out setuserparams into a separate procedure so that setvmxxx +% can use it without affecting the command in case of an error. +/.setuserparams2 { + % Check that we will be able to set the PostScript-level + % user parameters. + /setuserparams /psuserparams .systemvar .checksetparams + % Set the C-level user params. If this succeeds, we know that + % the password check succeeded. + dup .setuserparams + % Now set the PostScript-level params. + % The interpreter may have adjusted the values of some of the + % parameters, so we have to read them back. + dup { + /userparams .systemvar 2 index known { + psuserparams 2 index known not { + pop dup .getuserparam + } if + .copyparam + % special protection for the security related parameters + [ /PermitFileReading /PermitFileWriting /PermitFileControl ] + { 2 index eq { % force all strings to readonly but make sure the + % array is in the correct VM space (local/global). + currentglobal exch dup gcheck setglobal + dup length array exch { readonly exch } forall astore + exch setglobal + } if + } forall + % protect top level of parameters that we copied + dup type dup /arraytype eq exch /stringtype eq or { readonly } if + /userparams .systemvar 3 1 roll .forceput % userparams is read-only + } { + pop pop + } ifelse + } forall + % A context switch might have occurred during the above loop, + % causing the interpreter-level parameters to be reset. + % Set them again to the new values. From here on, we are safe, + % since a context switch will consult userparams. + .setuserparams +} .bind def +/setuserparams { % <dict> setuserparams - + .setuserparams2 +} .bind odef +% Initialize user parameters managed here. +/JobName () .definepsuserparam + +% Restore must restore the user parameters. +% (Since userparams is in local VM, save takes care of saving them.) +/restore { % <save> restore - + //restore /userparams .systemvar .setuserparams +} .bind odef + +% The pssystemparams dictionary holds some system parameters that +% are managed entirely at the PostScript level. +systemdict begin +currentdict /pssystemparams known not { + /pssystemparams 40 dict readonly def +} if +/getsystemparam { % <name> getsystemparam <value> + //pssystemparams 1 .argindex .knownget { exch pop } { .getsystemparam } ifelse +} odef +end +/currentsystemparams { % - currentsystemparams <dict> + mark .currentsystemparams //pssystemparams { } forall .dicttomark +} odef +/setsystemparams { % <dict> setsystemparams - + % Check that we will be able to set the PostScript-level + % system parameters. + dup pop % check # of args + /SAFETY .systemvar /safe get { + % SAFER mode disallows some changes + [ /GenericResourceDir /FontResourceDir /GenericResourcePathSep ] { + 2 copy .knownget { + exch //pssystemparams exch .knownget { + ne { /setsystemparams /invalidaccess signalerror } if + } { + pop + } ifelse + } { + pop + } ifelse + } forall + } if + /setsystemparams //pssystemparams mark exch { + type cvlit /.checkparamtype cvx 2 packedarray cvx + } forall .dicttomark .checksetparams + % Set the C-level system params. If this succeeds, we know that + % the password check succeeded. + dup .setsystemparams + % Now set the PostScript-level params. We must copy local strings + % into global VM. + dup + { //pssystemparams 2 index known + { % Stack: key newvalue + .copyparam + % protect top level parameters that we copied + dup type dup /arraytype eq exch /stringtype eq or { readonly } if + //pssystemparams 3 1 roll .forceput % pssystemparams is read-only + } + { pop pop + } + ifelse + } + forall pop +} .bind odef + +% Initialize the passwords. +% NOTE: the names StartJobPassword and SystemParamsPassword are known to +% the interpreter, and must be bound to noaccess strings. +% The length of these strings must be max_password (iutil2.h) + 1. +/StartJobPassword 65 string noaccess def +/SystemParamsPassword 65 string noaccess def + +% Redefine cache parameter setting to interact properly with userparams. +/setcachelimit { + { mark /MaxFontItem 2 .argindex .dicttomark setuserparams pop } + stopped + { /setcachelimit .systemvar $error /errorname get signalerror + } if +} .bind odef +/setcacheparams { + % The MaxFontCache parameter is a system parameter, which we might + % not be able to set. Fortunately, this doesn't matter, because + % system parameters don't have to be synchronized between this code + % and the VM. + counttomark 1 add copy setcacheparams + currentcacheparams % mark size lower upper + 3 -1 roll pop + /MinFontCompress 3 1 roll + /MaxFontItem exch + .dicttomark { setuserparams cleartomark } stopped { + /setcacheparams .systemvar $error /errorname get signalerror + } if +} .bind odef + +% Add bogus user and system parameters to satisfy badly written PostScript +% programs that incorrectly assume the existence of all the parameters +% listed in Appendix C of the Red Book. Note that some of these may become +% real parameters later: code near the end of gs_init.ps takes care of +% removing any such parameters from ps{user,system}params. + +% psuserparams + /MaxFormItem 100000 .definepsuserparam + /MaxPatternItem 20000 .definepsuserparam + /MaxScreenItem 48000 .definepsuserparam + /MaxUPathItem 0 .definepsuserparam + +% File Access Permission parameters + .currentglobal //true .setglobal + /.checkFilePermitparams { + type /arraytype eq { + currentuserparams /LockFilePermissions get { + 5 { pop } repeat /setuserparams /invalidaccess signalerror + }{ + % in addition to validating the value, ensure the value is read/only + dup { readonly exch } forall + .currentglobal exch dup gcheck .setglobal length array exch .setglobal + astore readonly + } + ifelse + } { + 5 { pop } repeat /setuserparams /typecheck signalerror + } + ifelse + //true + } .bind def +% Initialize the File Permission access control to wide open +% These will only be accessed via current/set userparams. +% Values are a string containing multiple nul terminated path strings + /PermitFileReading dup [ (*) ] .definepsuserparam + psuserparams exch /.checkFilePermitparams load put + /PermitFileWriting dup [ (*) ] .definepsuserparam + psuserparams exch /.checkFilePermitparams load put + /PermitFileControl dup [ (*) ] .definepsuserparam + psuserparams exch /.checkFilePermitparams load put + .setglobal + +pssystemparams begin + /CurDisplayList 0 .forcedef + /CurFormCache 0 .forcedef + /CurInputDevice () .forcedef + /CurOutlineCache 0 .forcedef + /CurOutputDevice () .forcedef + /CurPatternCache 0 .forcedef + /CurUPathCache 0 .forcedef + /CurScreenStorage 0 .forcedef + /CurSourceList 0 .forcedef + /DoPrintErrors //false .forcedef + /JobTimeout 0 .forcedef + /LicenseID (LN-001) .forcedef % bogus + /MaxDisplayList 140000 .forcedef + /MaxFormCache 100000 .forcedef + /MaxImageBuffer 524288 .forcedef + /MaxOutlineCache 65000 .forcedef + /MaxPatternCache 100000 .forcedef + /MaxUPathCache 300000 .forcedef + /MaxScreenStorage 84000 .forcedef + /MaxSourceList 25000 .forcedef + /PrinterName product .forcedef + /RamSize 4194304 .forcedef + /WaitTimeout 40 .forcedef +end + +% Define the procedures for handling comment scanning. The names +% %ProcessComment and %ProcessDSCComment are known to the interpreter. +% These procedures take the file and comment string and file as operands. +/.checkprocesscomment { + dup //null eq { + pop //true + } { + dup xcheck { + type dup /arraytype eq exch /packedarraytype eq or + } { + pop //false + } ifelse + } ifelse +} .bind def +/ProcessComment //null .definepsuserparam +psuserparams /ProcessComment {.checkprocesscomment} put +(%ProcessComment) cvn { + /ProcessComment getuserparam + dup //null eq { pop pop pop } { exec } ifelse +} bind def +/ProcessDSCComment //null .definepsuserparam +psuserparams /ProcessDSCComment {.checkprocesscomment} put +/.loadingfont //false def +(%ProcessDSCComment) cvn { + /ProcessDSCComment getuserparam + dup //null eq .loadingfont or { pop pop pop } { exec } ifelse +} bind def + +% ------ Miscellaneous ------ % + +(<<) cvn % - << -mark- + /mark load def +% (>> is defined primitively.) +/languagelevel 2 def +% When running in Level 2 mode, this interpreter is supposed to be +% compatible with Adobe version 2017. +/version (2017) readonly def + +% If binary tokens are supported by this interpreter, +% set an appropriate default binary object format. +/setobjectformat where + { pop + /RealFormat getsystemparam (IEEE) eq { 1 } { 3 } ifelse + /ByteOrder getsystemparam { 1 add } if + setobjectformat + } if + +% Aldus Freehand versions 2.x check for the presence of the +% setcolor operator, and if it is missing, substitute a procedure. +% Unfortunately, the procedure takes different parameters from +% the operator. As a result, files produced by this application +% cause an error if the setcolor operator is actually defined +% and 'bind' is ever used. Aldus fixed this bug in Freehand 3.0, +% but there are a lot of files created by the older versions +% still floating around. Therefore, at Adobe's suggestion, +% we implement the following dreadful hack in the 'where' operator: +% If the key is /setcolor, and +% there is a dictionary named FreeHandDict, and +% currentdict is that dictionary, +% then "where" consults only that dictionary and not any other +% dictionaries on the dictionary stack. +.wheredict /setcolor { + /FreeHandDict .where { + /FreeHandDict get currentdict eq { + pop currentdict /setcolor known { currentdict //true } { //false } ifelse + } { + .where + } ifelse + } { + .where + } ifelse +} bind put + +% ------ Virtual memory ------ % + +/currentglobal % - currentglobal <bool> + /currentshared load def +/gcheck % <obj> gcheck <bool> + /scheck load def +/setglobal % <bool> setglobal - + /setshared load def +% We can make the global dictionaries very small, because they auto-expand. +/globaldict currentdict /shareddict .knownget not { 4 dict } if def +/GlobalFontDirectory SharedFontDirectory def + +% VMReclaim and VMThreshold are user parameters. +/setvmthreshold { % <int> setvmthreshold - + mark /VMThreshold 2 .argindex .dicttomark .setuserparams2 pop +} odef +/vmreclaim { % <int> vmreclaim - + dup 0 gt { + dup 2 le 1 index type /integertype eq and { + pop % ignore user requests for vmreclaim + % (reclaim will still happen controlled by vmthreshold) + } + { .vmreclaim } % let internal operator handle error conditions + ifelse + } { + % VMReclaim userparam controls enable/disable GC + mark /VMReclaim 2 index .dicttomark .setuserparams2 pop + } ifelse +} odef +-1 setvmthreshold + +% ------ IODevices ------ % + +/.getdevparams where { + pop /currentdevparams { % <iodevice> currentdevparams <dict> + .getdevparams .dicttomark + } odef +} if +/.putdevparams where { + pop /setdevparams { % <iodevice> <dict> setdevparams - + dup type /dicttype ne { /setdevparams .systemvar /typecheck signalerror } if + mark 1 index { } forall counttomark 2 add index + .putdevparams pop pop + } odef +} if + +% ------ Job control ------ % + +serverdict begin + +% We could protect the job information better, but we aren't attempting +% (currently) to protect ourselves against maliciousness. + +/.jobsave //null def % top-level save object +/.jobsavelevel 0 def % save depth of job (0 if .jobsave is null, + % 1 otherwise) +/.adminjob //true def % status of current unencapsulated job + +end % serverdict + +% Because there may be objects on the e-stack created since the job save, +% we have to clear the e-stack before doing the end-of-job restore. +% We do this by executing a 2 .stop, which is caught by the 2 .stopped +% in .runexec; we leave on the o-stack a procedure to execute aftewards. +% +%**************** The definition of startjob is not complete yet, since +% it doesn't reset stdin/stdout. +/.startnewjob { % <exit_bool> <password_level> + % .startnewjob - + serverdict /.jobsave get dup //null eq { pop } { restore } ifelse + exch { + % Unencapsulated job + serverdict /.jobsave //null put + serverdict /.jobsavelevel 0 put + serverdict /.adminjob 3 -1 roll 1 gt put + } { + % Encapsulated job + pop + serverdict /.jobsave save put + serverdict /.jobsavelevel 1 put + .userdict /quit { stop } .bind put % CET 28-10 requires a procedure + } ifelse + % Reset the interpreter state. + clear cleardictstack + initgraphics + //false setglobal +} bind def +/.startjob { % <exit_bool> <password> <finish_proc> + % .startjob <ok_bool> + vmstatus pop pop serverdict /.jobsavelevel get eq + 2 .argindex .checkpassword 0 gt and { + exch .checkpassword exch count 3 roll count 3 sub { pop } repeat + cleardictstack + % Reset the e-stack back to the 2 .stopped in .runexec, + % passing the finish_proc to be executed afterwards. + 2 .stop + } { % Password check failed + pop pop pop //false + } ifelse +} odef +/startjob { % <exit_bool> <password> startjob <ok_bool> + % This is a hack. We really need some way to indicate explicitly + % to the interpreter that we are under control of a job server. + 1 .argindex type /booleantype ne { + /startjob .systemvar /typecheck signalerror + } if + { .startnewjob //true } .startjob +} odef + +% The procedure to undo the job encapsulation +/.endjob { + clear cleardictstack + serverdict /.jobsave get dup //null eq { pop } { restore } ifelse + serverdict /.jobsave //null put + 2 .vmreclaim % recover local and global VM +} odef + +systemdict begin +/quit { % - quit - + //systemdict begin serverdict /.jobsave get //null eq + { end //quit } + { /quit .systemvar /invalidaccess /signalerror load end exec } + ifelse +} bind odef +end + +% We would like to define exitserver as a procedure, using the code +% that the Red Book says is equivalent to it. However, since startjob +% resets the exec stack, we can't do this, because control would never +% proceed past the call on startjob if the exitserver is successful. +% Instead, we need to construct exitserver out of pieces of startjob. + +serverdict begin + +/exitserver { % <password> exitserver - + //true exch { .startnewjob } .startjob not { + /exitserver /invalidaccess signalerror + } if +} bind def + +end % serverdict + +% ------ Compatibility ------ % + +% In Level 2 mode, the following replace the definitions that gs_statd.ps +% installs in statusdict and serverdict. +% Note that statusdict must be allocated in local VM. +% We don't bother with many of these yet. + +/.dict1 { exch mark 3 1 roll .dicttomark } bind def + +currentglobal //false setglobal 25 dict exch setglobal begin +currentsystemparams + +% The following do not depend on the presence of setpagedevice. +/buildtime 1 index /BuildTime get def +% Also define /buildtime in systemdict because Adobe does so and some fonts use it as ID +systemdict /buildtime dup load put +/byteorder 1 index /ByteOrder get def +/checkpassword { .checkpassword 0 gt } bind def +dup /DoStartPage known + { /dostartpage { /DoStartPage getsystemparam } bind def + /setdostartpage { /DoStartPage .dict1 setsystemparams } bind def + } if +dup /StartupMode known + { /dosysstart { /StartupMode getsystemparam 0 ne } bind def + /setdosysstart { { 1 } { 0 } ifelse /StartupMode .dict1 setsystemparams } bind def + } if +%****** Setting jobname is supposed to set userparams.JobName, too. +/jobname { /JobName getuserparam } bind def +/jobtimeout { /JobTimeout getuserparam } bind def +/ramsize { /RamSize getsystemparam } bind def +/realformat 1 index /RealFormat get def +dup /PrinterName known + { /setprintername { /PrinterName .dict1 setsystemparams } bind def + } if +/printername + { currentsystemparams /PrinterName .knownget not { () } if exch copy + } bind def +currentuserparams /WaitTimeout known + { /waittimeout { /WaitTimeout getuserparam } bind def + } if + +% The following do require setpagedevice. +/.setpagedevice where { pop } { (%END PAGEDEVICE) .skipeof } ifelse +/defaulttimeouts + { currentsystemparams dup + /JobTimeout .knownget not { 0 } if + exch /WaitTimeout .knownget not { 0 } if + currentpagedevice /ManualFeedTimeout .knownget not { 0 } if + } bind def +/margins + { currentpagedevice /Margins .knownget { exch } { [0 0] } ifelse + } bind def +/pagemargin + { currentpagedevice /PageOffset .knownget { 0 get } { 0 } ifelse + } bind def +/pageparams + { currentpagedevice + dup /Orientation .knownget { 1 and ORIENT1 { 1 xor } if } { 0 } ifelse exch + dup /PageSize get aload pop 3 index 0 ne { exch } if 3 2 roll + /PageOffset .knownget { 0 get } { 0 } ifelse 4 -1 roll + } bind def +/setdefaulttimeouts + { exch mark /ManualFeedTimeout 3 -1 roll + /Policies mark /ManualFeedTimeout 1 .dicttomark + .dicttomark setpagedevice + /WaitTimeout exch mark /JobTimeout 5 2 roll .dicttomark setsystemparams + } bind def +/.setpagesize { 2 array astore /PageSize .dict1 setpagedevice } bind def +/setduplexmode { /Duplex .dict1 setpagedevice } bind def +/setmargins + { exch 2 array astore /Margins .dict1 setpagedevice + } bind def +/setpagemargin { 0 2 array astore /PageOffset .dict1 setpagedevice } bind def +/setpageparams + { mark /PageSize 6 -2 roll + 4 index 1 and ORIENT1 { 1 } { 0 } ifelse ne { exch } if 2 array astore + /Orientation 5 -1 roll ORIENT1 { 1 xor } if + /PageOffset counttomark 2 add -1 roll 0 2 array astore + .dicttomark setpagedevice + } bind def +/setresolution + { dup 2 array astore /HWResolution .dict1 setpagedevice + } bind def +%END PAGEDEVICE + +% The following are not implemented yet. +%manualfeed +%manualfeedtimeout +%pagecount +%pagestackorder +%setpagestackorder + +% -------- ICC manager -------- % +% All color management is going +% through ICC flow. We need +% to have the default device +% spaces gray, RGB and CMYK +% defined by ICC profiles + +//systemdict /ICCProfilesDir .knownget { + % Set the directory sepcified by the command line option + mark exch /ICCProfilesDir exch .dicttomark .setuserparams2 +} { + % First see if the current value is valid so we don't have to guess + mark .currentuserparams .dicttomark /ICCProfilesDir get + (default_gray.icc) concatstrings {status} .internalstopped + {pop //false} if + { + pop pop pop pop % current value was OK. Just clean up stack + } { + % Search for valid (iccprofiles) directory as a sibling to (Resource) + % and set it as a default if found. + LIBPATH { + (Resource) search { + exch pop exch pop (iccprofiles) concatstrings + .file_name_separator concatstrings + dup (default_gray.icc) concatstrings status { + pop pop pop pop + mark exch /ICCProfilesDir exch .dicttomark .setuserparams2 + exit + } { + pop + } ifelse + } { + pop + } ifelse + } forall + } ifelse % if currentuserparams ICCProfilesDir +} ifelse % ICCProfilesDir set in systemdict (command line option) + +mark % collect dict key value pairs for anything set in systemdict (command line options) +[ /DefaultRGBProfile /DefaultGrayProfile /DefaultCMYKProfile /DeviceNProfile + /NamedProfile /SourceObjectICC /OverrideICC +] +{ dup //systemdict exch .knownget not { + pop % discard keys not in systemdict + } if +} forall +.dicttomark .setuserparams2 + +pop % currentsystemparams + +% Flag the current dictionary so it will be swapped when we +% change language levels. (See zmisc2.c for more information.) +/statusdict currentdict def + +currentdict end +/statusdict exch .forcedef % statusdict is local, systemdict is global + +% The following compatibility operators are in systemdict. They are +% defined here, rather than in gs_init.ps, because they require the +% resource machinery. + +/devforall { % <proc> <scratch> devforall - + exch { + 1 index currentdevparams + /Type .knownget { /FileSystem eq } { //false } ifelse + { exec } { pop pop } ifelse + } /exec load 3 packedarray cvx exch + (*) 3 1 roll /IODevice resourceforall +} odef +/devstatus { % <(%disk*%)> devstatus <searchable> <writable> + % <hasNames> <mounted> <removable> <searchOrder> + % <freePages> <size> true + % <string> devstatus false + dup length 5 ge { + dup 0 5 getinterval (%disk) eq { + dup /IODevice resourcestatus { + pop pop dup currentdevparams + dup /Searchable get + exch dup /Writeable get + exch dup /HasNames get + exch dup /Mounted get + exch dup /Removable get + exch dup /SearchOrder get + exch dup /Free get + exch /LogicalSize get + 9 -1 roll pop //true + } { + pop //false + } ifelse + } { + pop //false + } ifelse + } { + pop //false + } ifelse +} odef + +% ------ Color spaces ------ % +% gs_res.ps uses these entries in colorspacedict +% to populate the ColorSpaceFamily resource, so we need +% to add the supported spaces. +% +systemdict /colorspacedict get begin +/CIEBasedA [] def +/CIEBasedABC [] def +/DevicePixel [] def +/Indexed [] def +/Pattern [] def +/Separation [] def +end + +% ------ CIE color rendering ------ % + +% Define findcolorrendering and a default ColorRendering ProcSet. + +/findcolorrendering { % <intentname> findcolorrendering + % <crdname> <found> + % Adobe interpreters report /findcolorrendering (literal name), not the + % operator itself, if an error occurs in findcolorrendering. + /findcolorrendering { + /ColorRendering /ProcSet findresource + 1 .argindex dup type /nametype eq { .namestring } if (.) concatstrings + 1 index /GetPageDeviceName get exec dup type /nametype eq { .namestring } if (.) concatstrings + 2 index /GetHalftoneName get exec dup type /nametype eq { .namestring } if + concatstrings concatstrings cvn % stack: intentname procset crdname + dup /ColorRendering resourcestatus { + pop pop exch pop exch pop //true + } { + pop /GetSubstituteCRD get exec //false + } ifelse + } .errorexec +} odef + +5 dict dup begin + +/GetPageDeviceName { % - GetPageDeviceName <name> + currentpagedevice dup /PageDeviceName .knownget { + exch pop dup //null eq { pop /none } if + } { + pop /none + } ifelse +} bind def + +/GetHalftoneName { % - GetHalftoneName <name> + currenthalftone /HalftoneName .knownget not { /none } if +} bind def + +/GetSubstituteCRD { % <intentname> GetSubstituteCRD <crdname> + pop /DefaultColorRendering +} bind def + +end +% The resource machinery hasn't been activated, so just save the ProcSet +% and let .fixresources finish the installation process. +/ColorRendering exch def + +% Define setcolorrendering. + +/.colorrenderingtypes 5 dict def + +/setcolorrendering { % <crd> setcolorrendering - + dup /ColorRenderingType get + dup type /integertype ne { + /setcolorrendering .systemvar /typecheck signalerror + } if + //.colorrenderingtypes exch .knownget { + exec + } { + /setcolorrendering .systemvar /rangecheck signalerror + } ifelse +} odef + +/.setcolorrendering1 where { pop } { (%END CRD) .skipeof } ifelse + +.colorrenderingtypes 1 { + % Adobe ProcSet "Adobe_AGM_Core 2.0 0" places an /Intent key into CRD's + dup /Intent .knownget { + //.renderingintentdict exch .knownget { .setrenderingintent } if + } if + dup .buildcolorrendering1 .setcolorrendering1 +} .bind put + +% Note: the value 101 in the next line must be the same as the value of +% GX_DEVICE_CRD1_TYPE in gscrdp.h. +.colorrenderingtypes 101 { + dup .builddevicecolorrendering1 .setdevicecolorrendering1 +} .bind put + +% sRGB output CRD, D65 white point +mark +/ColorRenderingType 1 +/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ] readonly + +% Bradford Cone Space +/MatrixPQR [ 0.8951 -0.7502 0.0389 + 0.2664 1.7135 -0.0685 + -0.1614 0.0367 1.0296] readonly + +/MatrixLMN [ 3.240449 -0.969265 0.055643 + -1.537136 1.876011 -0.204026 + -0.498531 0.041556 1.057229 ] readonly + +% Inverse sRGB gamma transform +/EncodeABC [ { dup 0.00304 le + { 12.92321 mul } + { 1 2.4 div exp 1.055 mul 0.055 sub } + ifelse + } bind dup dup + ] readonly + +/WhitePoint [ 0.9505 1 1.0890 ] readonly % D65 +/BlackPoint [ 0 0 0 ] readonly + +% VonKries-like transform in Bradford Cone Space + /TransformPQR + % The implementations have been moved to C for performance. + [ { .TransformPQR_scale_WB0 } bind + { .TransformPQR_scale_WB1 } bind + { .TransformPQR_scale_WB2 } bind + ] readonly +.dicttomark setcolorrendering + +%END CRD + +% Initialize a CIEBased color space for sRGB. +/CIEsRGB [ /CIEBasedABC + mark + /DecodeLMN [ { + dup 0.03928 le { 12.92321 div } { 0.055 add 1.055 div 2.4 exp } ifelse + } bind dup dup ] readonly + /MatrixLMN [ + 0.412457 0.212673 0.019334 + 0.357576 0.715152 0.119192 + 0.180437 0.072175 0.950301 + ] readonly + /WhitePoint [0.9505 1.0 1.0890] readonly + .dicttomark readonly +] readonly def + +% Special type to install +% sRGB ICC profile color space +/CIEsRGBICC [ /ICCBased + mark + /N 3 + /DataSource (srgb) + /Alternate [/DeviceRGB] + /Name (srgb) + .dicttomark +] def + +% Special type to install +% sGray ICC profile color space +/CIEsGRAYICC [ /ICCBased + mark + /N 1 + /DataSource (sgray) + /Alternate [/DeviceGray] + /Name (sgray) + .dicttomark +] def + +% ------ Painting ------ % + +%% We don't want to do any high level forms stuff if the source +%% is PDF because : +%% 1) Transparent forms are handled separately and we don't want to ge confused +%% 2) PDF forms are too llikely to trip over the limitations in our support +%% 3) Its highly unusual to find a PDF file which uses forms sensibly. +%% +%% So we have a special PDF version of execform which doesn't do high level forms. + +/.PDFexecform { + % This is a separate operator so that the stacks will be restored + % properly if an error occurs. + dup /Matrix get concat + dup /BBox get aload pop + exch 3 index sub exch 2 index sub rectclip + dup /PaintProc get + 1 index /Implementation known not { + 1 index dup /Implementation //null .forceput readonly pop + } if + exec +}.bind odef + +/PDFexecform { + gsave { + .PDFexecform + } stopped grestore {stop} if +} odef + +% A straightforward definition of execform that doesn't actually +% do any caching. +/.execform1 { + % This is a separate operator so that the stacks will be restored + % properly if an error occurs. + %% High level forms need the CTM before the Form Matrix is applied + /UNROLLFORMS where {/UNROLLFORMS get}{false}ifelse not + {matrix currentmatrix exch} if + dup /Matrix get concat + dup /BBox get aload pop + exch 3 index sub exch 2 index sub rectclip + dup /PaintProc get + 1 index /Implementation known not { + 1 index dup /Implementation //null .forceput readonly pop + } if + /UNROLLFORMS where {/UNROLLFORMS get}{false}ifelse not + %% [CTM] <<Form>> PaintProc .beginform - + { + %% First,, check to see if we have no /Implementation already defined (see above) + 1 index /Implementation get //null eq + { + %% We don't, so copy the form dictionary + 1 index 4 1 roll + %% tell devices we're starting a form, run the PaintProc, and then tell the devices we've finished + 3 -1 roll 2 index + .beginform exec + + %% This is all horrible code to deal with illegal forms which leave junk on the operand stack + %% Starting from 1 (not 0, we don't want to look at the loop count) and going up to the + %% number of objects on the stack, check each object to see if its the Form dict (it is + %% *supposed* to be the top object after executing the PaintProc). I don't currently check to see if + %% the PaintProc ate the dict, but if there are extra objects, remove them and tell + %% the user. + %% + count 1 1 3 -1 roll { + dup index + dup type /dicttype eq { + /Implementation known { + 2 sub 0 1 3 -1 roll { + QUIET not { + (\n WARNING - Form PaintProc left operands on the stack after execution.\n This is technically illegal and these have been removed, \n if output is incorrect run again with -dUNROLLFORMS.\n) = + } if + pop pop + } for + exit + }if + } { + pop pop + }ifelse + } for + + .endform + %% Ask devices if they have cached the form, and what ID to use if so + %% returning -1 means 'no ID' + .get_form_id dup -1 eq + {pop pop} + { + %% The form is cached with a specific ID. Make a dictionary (which we'll store in the + %% Form dictioanry using the /Implementation key). + 1 dict dup /FormID 4 -1 roll put + 1 index exch /Implementation exch .forceput readonly pop + } + ifelse + } + { + %% We have a (non-null) Implementation, get the dictionary and pull the + %% FormID key from it, then tell the device to use the stored form with the + %% specified key. + pop dup /Implementation get /FormID get .repeatform + }ifelse + } + {exec} ifelse +} .bind odef % must bind .forceput + +/.formtypes 5 dict + dup 1 /.execform1 load put +def + +/execform { % <form> execform - + gsave { + dup /FormType get //.formtypes exch get exec + } stopped grestore { stop } if +} odef + +/.patterntypes 5 dict + dup 1 /.buildpattern1 load put +def + +/makepattern { % <proto_dict> <matrix> makepattern <pattern> + dup type /dicttype eq { + % "<dict> makepattern" reports /typecheck on Adobe + /makepattern .systemvar /typecheck signalerror + } if + //.patterntypes 2 .argindex /PatternType get .knownget not { + /makepattern .systemvar /rangecheck signalerror + } if + .currentglobal //false .setglobal exch + % Stack: proto matrix global buildproc + 3 index dup length 1 add dict .copydict + % Stack: proto matrix global buildproc newdict + 3 index 3 -1 roll exec + % Stack: proto matrix global newdict instance + % Create an 'Implementation' entry for the pattern dict. The PRLM 3rd says + % this about the contents of Implementation: "The type and value of this + % entry are implementation-dependent." The CET (page 2 of 18-02f) expects + % that this entry be an array and that the second element of the array be a + % gstate. We put our pattern instance struct into the first element of the + % array. + 1 index /Implementation 3 -1 roll + .getCPSImode { gstate } { //null } ifelse 2 array astore + put % put Implementation into the pattern dict. + % Stack: proto matrix global newdict + readonly exch .setglobal exch pop exch pop +} odef + +/setpattern { % [<comp1> ...] <pattern> setpattern - + { currentcolorspace 0 get /Pattern ne { + [ /Pattern currentcolorspace ] setcolorspace + } if setcolor + } stopped { + /setpattern .systemvar $error /errorname get signalerror + } if +} odef + +% The following functions emulate the actions of findcmykcustomcolor and +% setcustomcolor. These functions are described in Adobe's TN 5044. That +% same document also says "The following "operators" are not defined in the +% PostScript Language Reference Manual, but should be used as pseudo-operators +% in your PostScript language output. Separation applications from Adobe +% Systems and other vendors will redefine these convention operators to +% separate your documents. Your application should conditionally define +% procedures with these special names, as shown later in this document." +% +% We are providing these functions because we have found files created by +% "QuarkXPress: pictwpstops filter 1.0" which produce bad shading dictionaries +% if these operators are not defined. + +% Also we add a findrgbcustomcolor that was discovered in Adobe Illustrator +% AI5 (Adobe Illustrator (R) Version 7.0 Full Prolog) ProcSet that allows +% us to create Separation colorspace with a /DeviceRGB tint transform. + +% Conditionally disable the TN 5044 psuedo-ops if NO_TN5044 specified +/NO_TN5044 where { pop (%END TN 5044 psuedo-ops) .skipeof } if + +% TN 5044 does not define the contents of the array. We are simply putting +% the values given into an array. This is consistent with what we see when +% testing with Adobe Distiller 6.0. +% <cyan> <magenta> <yellow> <black> <key> findcmykcustomcolor <array> +/findcmykcustomcolor { 5 array astore } bind def +% The following isn't documented by Adobe, but was found in Adobe Illustrator (R) +% Version 7.0 Full Prolog +/findrgbcustomcolor { 4 array astore } bind def + +% Build a tint transform function for use by setcustomcolor. This function +% is for a Separation color space which has either a DeviceCMYK base color space +% (i.e. 1 input and 4 outputs) or a DeviceRGB colorspace (1 in, 3 out). +% The input to buildcustomtinttransform is the array created by findcmykcustomcolor +% and the length of the array is used to determine the alternate colorspace. +% The resulting function for CMYK is: +% { dup cyan mul exch dup magenta mul exch dup yellow mul exch black mul } +% Where cyan, magenta, yellow, and black are values from the array. +% For RGB, since the resulting function is: +% { dup red mul exch dup green mul exch blue mul } +/buildcustomtinttransform % <array> buildcustomtinttransform <function> +{ + dup length 5 eq { + % CMYK + [ /dup load 2 index 0 get /mul load + /exch load /dup load 6 index 1 get /mul load + /exch load /dup load 10 index 2 get /mul load + /exch load 13 index 3 get /mul load + ] + } { + % RGB is assumed + [ /dup load 2 index 0 get /mul load + /exch load /dup load 6 index 1 get /mul load + /exch load 9 index 2 get /mul load + ] + } ifelse + cvx bind exch pop % Make executable and remove the input array +} bind def + +% Construct the colorspace array to be used by setcolorspace from the array +% result of either findcmykcustomcolor or findrgbcustomcolor. +/buildcolorspacearray % <array> buildcustomtinttransform <colorspace_array> +{ % as with buildcustomtinttransform, the length of the array is used to + % determine the alternate colorspace + dup length 5 eq { + % Start building Separation colorspace with CMYK alternate + [ /Separation 2 index 4 get % Get separation name from array's key + /DeviceCMYK + 4 index //buildcustomtinttransform exec % build the tint transform function + ] + } { + [ /Separation 2 index 3 get % Get separation name from array's key + /DeviceRGB + 4 index //buildcustomtinttransform exec % build the tint transform function + ] + } ifelse + exch pop % remove the input array +} bind def + +% Set a custom color based upon a tint and array which describes the custom +% color. See findcmykcustomcolor. First we create and then set a Separation +% colorspace. Then we set the specified color. +% Note that older Adobe ProcSets apparently allow for 'null' as the tint +% for some reason, so an alternate operational mode is tolerated: +% null setcustomcolor - +/setcustomcolor % <array> <tint> setcustomcolor - +{ dup //null ne { + exch //buildcolorspacearray exec + setcolorspace % Set the Separation color space as current + setcolor % Set the tint as the current color + } + { pop pop } % 'null' as the tint is ignored. pop tint and array + ifelse +} bind def + +% This proc is supposed to implement a version of overprinting. TN 5044 says +% that this proc is not used by any shipping host-based application. We have +% only found it being used in a proc set in files by Canvas from Deneba Systems. +% Even their proc set does not actually do any overprinting. However their +% files crash if this is not defined. Thus we have a copy of this proc but +% we are simply checking for inputs being -1 and if so then we set the value +% to 0. +/setcmykoverprint { + 4 { dup -1 eq { pop 0 } if 4 1 roll } repeat setcmykcolor +} bind def + +/separation_all [/Separation /All /DeviceCMYK { dup dup dup } bind ] readonly def + +% Collect the arguments into the image dictionary +% <width> <height> <bits/sample> <matrix> <proc> args2dict <dict> +/args2dict { + 10 dict begin + {1 0} 1 + { /ImageType /Decode /DataSource /ImageMatrix /BitsPerComponent /Height /Width + } { exch def } forall + currentdict end +} bind def + +% Prints (1-gray) on all separations. +% <gray> setseparationgray - +/setseparationgray { + //separation_all setcolorspace + 1 exch sub setcolor +} bind def + +% Renders an image whose sample values specify the amount of the custom color. +% <width> <height> <bits/sample> <matrix> <proc> <array> customcolorimage - +/customcolorimage { + gsave + //buildcolorspacearray exec setcolorspace + //args2dict exec image + grestore +} bind def + +% Renders an image on all process and custom color plates. +% <width> <height> <bits/sample> <matrix> <proc> +/separationimage { + gsave + //separation_all setcolorspace + //args2dict exec image + grestore +} bind def + +{ /buildcustomtinttransform /buildcolorspacearray /separation_all /args2dict } +{ currentdict exch undef } forall + +%END TN 5044 psuedo-ops + +end % level2dict diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps b/Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps new file mode 100644 index 00000000000..a1deb5891a4 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps @@ -0,0 +1,499 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Initialization file for PostScript LanguageLevel 3 functions. +% This file must be loaded after gs_lev2.ps and gs_res.ps. +% These definitions go into ll3dict or various ProcSets. +% NOTE: the interpreter creates ll3dict. + +ll3dict begin + +% We need LanguageLevel 2 or higher in order to have setuserparams and +% defineresource. +languagelevel dup 2 .max .setlanguagelevel + +% ------ Idiom recognition ------ % + +/IdiomRecognition //false .definepsuserparam + +% Modify `bind' to apply idiom recognition afterwards. +/.bindscratch 128 string def +% Note that since this definition of `bind' may get bound in, +% it has to function properly even at lower language levels, +% where IdiomRecognition may not be defined. +/.bind_ { % <proc> .bind <proc'> + //.bind currentuserparams /IdiomRecognition + .knownget not { //false } if { + (*) { + /IdiomSet findresource + //false exch { + % Stack: proc //false dummykey [template substitute] + exch pop dup 1 get exch 0 get + % Stack: proc //false substitute template + 3 index .eqproc { + 2 index gcheck 1 index gcheck not and { + pop + } { + 3 -1 roll pop exch not exit + } ifelse + } { + pop + } ifelse + } forall { exit } if + } //.bindscratch /IdiomSet resourceforall + } if +} def +/.bind /.bind_ load odef % note that .bind_ will get bound +currentdict /.bindscratch .undef + +DELAYBIND NOBIND or not { +% We can't just do +% /bind /.bind load def +% because then /bind load == prints --.bind-- . + /bind {//.bind_ exec} odef +} if +currentdict /.bind_ undef + +% ------ HalftoneTypes 6, 10, 16 and HalftoneMode ------ % + +% This code depends on an internal HalftoneType 7 with the following keys: +% Width, Height, Width2, Height2, TransferFunction: +% as for HalftoneType 16. +% Thresholds: a string or bytestring holding the thresholds, +% (Width x Height + Width2 x Height2) x BitsPerSample / 8 bytes, +% as for HalftoneType 16 except that the samples may be either +% 8 or 16 bits wide. +% BitsPerSample: 8 or 16. + +% Note that this HalftoneType never appears in halftone dictionaries given +% to sethalftone, only as a component in those given to .sethalftone5, +% so its numeric value can be chosen ad lib as long as it differs from the +% other values that are legal in component dictionaries for .sethalftone5 +% (currently only 1 and 3). + +/.makehalftone7 { % <dict> <dict> <source> <Width> <Height> + % (<Width2> <Height2> | null) <BPS> .makehalftone7 + % <setdict> <dict5> { .sethalftone5 } + 8 dict begin + /HalftoneType 7 def + /BitsPerSample exch def + dup //null eq { + pop 0 + } { + /Height2 1 index def /Width2 2 index def mul + } ifelse 3 1 roll + /Height 1 index def + /Width 2 index def + mul add BitsPerSample 8 idiv mul .bigstring + % Stack: dict dict source str + dup type /stringtype eq { readstring } { .readbytestring } ifelse + not { /sethalftone .systemvar /rangecheck signalerror exit } if + readonly /Thresholds exch def + /TransferFunction .knownget { /TransferFunction exch def } if + % If the original Thresholds was a file, replace it with + % a new one. + dup /Thresholds get type /filetype eq { + dup /Thresholds [ Thresholds ] cvx 0 () .subfiledecode put + } if + mark /HalftoneType 5 /Default currentdict end .dicttomark + { .sethalftone5 } +} bind def + +/.bigstring { % <size> .bigstring <string|bytestring> + dup 65400 gt { .bytestring } { string } ifelse +} bind def + +/.readbytestring { % <source> <bytestring> .readbytestring + % <bytestring> <filled> + % Note that since bytestrings don't implement getinterval, + % if filled is false, there is no way to tell how much + % was read. + //true exch 0 1 2 index length 1 sub { + % Stack: source true str index + 3 index read not { pop exch not exch exit } if + 3 copy put pop pop + } for 3 -1 roll pop exch +} bind def + +/.sethalftone6 { % <dict> <dict> .sethalftone6 <setdict> <dict5> + % { .sethalftone5 } + % Keys: Width, Height, Thresholds, T'Function + dup /Thresholds get + 1 index /Width get 2 index /Height get + //null 8 .makehalftone7 +} bind def + +/.sethalftone10 { % <dict> <dict> .sethalftone10 <setdict> <dict5> + % { .sethalftone5 } + % Keys: Xsquare, Ysquare, Thresholds, T'Function + % Note that this is the only one of these three HalftoneTypes + % that allows either a file or a string for Thresholds. + dup /Thresholds get dup type /stringtype eq { 0 () .subfiledecode } if + 1 index /Xsquare get dup 3 index /Ysquare get dup + 8 .makehalftone7 +} bind def + +/.sethalftone16 { % <dict> <dict> .sethalftone16 <setdict> <dict5> + % { .sethalftone5 } + % Keys: Width, Height, Width2, Height2, + % Thresholds, T'Function + dup /Thresholds get + 1 index /Width get 2 index /Height get + 3 index /Width2 .knownget { % 2-rectangle case + 4 index /Height2 get + } { % 1-rectangle case + //null + } ifelse 16 .makehalftone7 +} bind def + +.halftonetypes begin + 6 /.sethalftone6 load def + 10 /.sethalftone10 load def + 16 /.sethalftone16 load def +end + +% Redefine the halftone-setting operators to honor HalftoneMode. +/setcolorscreen { + /HalftoneMode getuserparam 0 eq { + //setcolorscreen + } { + 12 { pop } repeat .getdefaulthalftone + { //sethalftone } + { .setdefaulthalftone } + ifelse + } ifelse +} odef +/setscreen { + /HalftoneMode getuserparam 0 eq { + //setscreen + } { + pop pop pop .getdefaulthalftone + { //sethalftone } + { .setdefaulthalftone } + ifelse + } ifelse +} odef +/sethalftone { + /HalftoneMode getuserparam 0 eq { + //sethalftone + } { + gsave //sethalftone grestore + .getdefaulthalftone + { //sethalftone } + { .setdefaulthalftone } + ifelse + } ifelse +} odef + +% ------ ImageTypes 3 and 4 (masked images) ------ % + +% Put the new data source in the requested dictionary. +% Copy the updated dictionary because it nay be used elsewhere. +% <dict> <data> <name> update_image3 <dict'> +/update_image3 { + 3 -1 roll dup length dict copy dup % [data] /name <<image>> <<image>> + 2 index get % [data] /name <<image>> <<sub-image>> + dup length dict copy dup % [data] /name <<image>> <<sub-image>> <<sub-image>> + /DataSource 6 -1 roll put % /name <<image>> <<sub-image>> + exch dup % /name <<sub-image>> <<image>> <<image>> + 4 2 roll % <<image>> <<image>> /name <<sub-image>> + put % <<image>> +} bind def + +% Copy mask data source to a reusable stream +% <dict> <source> buffer_mask <dict> <file> +/buffer_mask { + 1 index /MaskDict get + dup /Width get + 1 index /BitsPerComponent get mul 7 add 8 idiv + exch /Height get mul () /SubFileDecode filter + /ReusableStreamDecode filter +} bind def + +% Data type vs. mask type decission table. +% All procedures have the signature: +% <image dict> <data DataSource> <mask DataSource> proc <image dict'> +/data_mask_dict mark + /stringtype mark % data is a string + /stringtype { pop pop } bind + /arraytype { % convert data to proc, don't buffer mask + pop + dup type dup /arraytype eq exch /packedarraytype eq or { + [ exch { 1 array astore cvx } forall ] + } { + 1 array astore cvx + } ifelse + /DataDict //update_image3 exec + } bind + /packedarraytype 1 index + /filetype { % convert data to file, don't buffer mask + pop + dup type dup /arraytype eq exch /packedarraytype eq or { + [ exch { 1 array astore cvx 0 () /SubFileDecode filter } forall ] + } { + 1 array astore cvx 0 () /SubFileDecode filter + } ifelse + /DataDict //update_image3 exec + } bind + .dicttomark readonly + /arraytype mark % data is a proc + /stringtype { % convert mask to proc + exch pop + 1 array astore cvx + /MaskDict //update_image3 exec + } bind + /arraytype { % buffer mask in reusable stream and convert back to proc + exch pop + //buffer_mask exec + 500 string + { readstring pop } aload pop + 4 packedarray cvx + /MaskDict //update_image3 exec + } bind + /packedarraytype 1 index + /filetype 1 index + .dicttomark readonly + /packedarraytype 1 index + /filetype mark % data is a file + /stringtype { % convert mask to file + exch pop + 1 array astore cvx 0 () /SubFileDecode filter + /MaskDict //update_image3 exec + } bind + /arraytype { % buffer the mask and convert to file + exch pop + //buffer_mask exec + /MaskDict //update_image3 exec + } bind + /packedarraytype 1 index + /filetype { + //systemdict /userdict get /PDFTopSave known { + pop pop % mask is already buffered by PDF interpreter + } { + exch pop % buffer the mask + //buffer_mask exec + /MaskDict //update_image3 exec + } ifelse + } bind + .dicttomark readonly +.dicttomark readonly def + +.imagetypes + dup 3 { + dup /InterleaveType get 3 eq { + % .image3 requires data sources of the image and mask to be of the + % same type. Work around this restriction here. + dup /DataDict get /DataSource get + 1 index /MaskDict get /DataSource get % <<>> data mask + dup type % <<>> data mask mask_type + 2 index + 4 index /DataDict get /MultipleDataSources .knownget { + { 0 get } if + } if + type % <<>> data mask mask_type data_type + //data_mask_dict exch .knownget { + exch .knownget { + exec + } { + pop pop % pass wrong type as is to .image3 + } ifelse + } { + pop pop pop % pass wrong type as is to .image3 + } ifelse + } if + .image3 + } bind put + dup 4 /.image4 load put +% We also detect ImageType 103 here: it isn't worth making a separate file +% just for this. + /.image3x where { pop dup 103 /.image3x load put } if +pop + +currentdict /data_mask_dict undef +currentdict /update_image3 undef +currentdict /buffer_mask undef + +% ------ Functions ------ % + +% Define the FunctionType resource category. +/Generic /Category findresource dup maxlength 3 add dict .copydict begin + /InstanceType /integertype def +/FunctionType currentdict end /Category defineresource pop + +{0 2 3} { dup /FunctionType defineresource pop } forall + +% ------ Smooth shading ------ % + +% Define the ShadingType resource category. +/Generic /Category findresource dup maxlength 3 add dict .copydict begin + /InstanceType /integertype def +/ShadingType currentdict end /Category defineresource pop + +systemdict /.shadingtypes mark % not ll3dict + 1 /.buildshading1 load + 2 /.buildshading2 load + 3 /.buildshading3 load + 4 /.buildshading4 load + 5 /.buildshading5 load + 6 /.buildshading6 load + 7 /.buildshading7 load +.dicttomark put + +systemdict /.reuseparamdict mark + /Intent 2 + /AsyncRead //false + /CloseSource //true +.dicttomark readonly put +/.buildshading { % <shadingdict> .buildshading <shading> + dup rcheck not { + % Adobe seems to access ColorSpace first and CET 12-14c checks this. + /$error .systemvar /errorinfo [ /ColorSpace //null ] put + /shfill .systemvar /invalidaccess signalerror + } if + % Unfortunately, we always need to make the DataSource reusable, + % because if clipping is involved, even shfill may need to read + % the source data multiple times. If it weren't for this, + % we would only need to create a reusable stream if the ultimate + % source of the data is a procedure (since the library can't + % suspend shading to do a procedure callout). + dup /DataSource .knownget { + dup type /filetype eq { + //.reuseparamdict /ReusableStreamDecode filter + % Copy the dictionary to replace the DataSource, but make sure the + % copy is in the same VM as the original. + .currentglobal 2 index gcheck .setglobal + % Stack: shdict rsdfile saveglobal + 2 index dup length dict copy exch .setglobal + dup /DataSource 4 -1 roll put exch pop + } { + pop + } ifelse + } if + % The .buildshading operators use the current color space + % for ColorSpace. + dup /ShadingType .knownget not { % error handling for CET 12-14b conformance + /$error .systemvar /errorinfo [ /ShadingType //null ] put + /shfill .systemvar /undefined signalerror + } if + dup type /integertype ne { + /$error .systemvar /errorinfo [ /ShadingType 4 index ] put + /shfill .systemvar /typecheck signalerror + } if + //.shadingtypes 1 index .knownget not { + /$error .systemvar /errorinfo [ /ShadingType 4 index ] put + /shfill .systemvar /rangecheck signalerror + } if + exch pop 1 index /ColorSpace .knownget { + { setcolorspace } stopped { + /$error .systemvar /errorinfo [ /ColorSpace 4 index ] put + /shfill .systemvar /$error .systemvar /errorname get signalerror + } if + exec + } { + /$error .systemvar /errorinfo [ /ColorSpace //null ] put + /shfill .systemvar /undefined signalerror + } ifelse +} bind def +systemdict /.reuseparamdict undef + +/.buildpattern2 { % <template> <matrix> .buildpattern2 + % <template> <pattern> + % We want to build the pattern without doing gsave/grestore, + % since we want it to load the CIE caches. + 1 index /Shading get + mark currentcolor currentcolorspace + counttomark 4 add -3 roll mark 4 1 roll + % Stack: -mark- ..color.. cspace -mark- template matrix shadingdict + { .buildshading } stopped { + cleartomark setcolorspace setcolor pop stop + } if + .buildshadingpattern + 3 -1 roll pop counttomark 1 add 2 roll setcolorspace setcolor pop +} bind def + +.patterntypes + 2 /.buildpattern2 load put + +/shfill { % <shadingdict> shfill - + % Currently, .shfill requires that the color space + % in the pattern be the current color space. + % Disable overprintmode for shfill + { dup gsave 0 .setoverprintmode .buildshading .shfill } stopped + grestore { + /$error .systemvar /errorinfo 2 copy known { + pop pop + } { + //null put % CET 12-14c + } ifelse + stop + } if + pop +} odef + +% Establish an initial smoothness value that matches Adobe RIPs. +0.02 setsmoothness + +% ------ DeviceN color space ------ % +% gs_res.ps uses these entries in colorspacedict +% to populate the ColorSpaceFamily resource, so we need +% to add the supported spaces. +% +systemdict /colorspacedict get begin +/CIEBasedDEF [] def +/CIEBasedDEFG [] def +/DeviceN [] def +end + +% ------ Miscellaneous ------ % + +% Make the setoverprintmode and currentoverprintmode operators visible (3015) +% Because of the requirements of PDF, the .currentoverprintmode and +% .setoverprintmode operators have integer parameters. Thus we need to +% convert the Postscript bool parameters to integers. +% +/setoverprintmode % bool setoverprint - +{ + { 1 } { 0 } ifelse % convert bool to integer + //.setoverprintmode +} odef + +/currentoverprintmode % - currentoverprintmode bool +{ + //.currentoverprintmode + 0 ne % convert integers to bool +} odef + +% Define additional user and system parameters. +/HalftoneMode 0 .definepsuserparam +/MaxSuperScreen 1016 .definepsuserparam +pssystemparams begin % read-only, so use .forcedef + /MaxDisplayAndSourceList 160000 .forcedef +end + +% Define the IdiomSet resource category. +{ /IdiomSet } { + /Generic /Category findresource dup maxlength 3 add dict .copydict begin + /InstanceType /dicttype def + currentdict end /Category defineresource pop +} forall + +/languagelevel 3 def +% When running in LanguageLevel 3 mode, this interpreter is supposed to be +% compatible with Adobe version 3010. +/version (3010) readonly def + +.setlanguagelevel + +end % ll3dict diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_mex_e.ps b/Master/tlpkg/tlgs/Resource/Init/gs_mex_e.ps new file mode 100644 index 00000000000..7b080eaa6e9 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_mex_e.ps @@ -0,0 +1,65 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Define the MacExpert encoding vector. +/currentglobal where + { pop currentglobal { setglobal } //true setglobal } + { { } } +ifelse +/MacExpertEncoding +% \00x + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +% \04x + /space /exclamsmall /Hungarumlautsmall /centoldstyle /dollaroldstyle /dollarsuperior /ampersandsmall /Acutesmall + /parenleftsuperior /parenrightsuperior /twodotenleader /onedotenleader /comma /hyphen /period /fraction + /zerooldstyle /oneoldstyle /twooldstyle /threeoldstyle /fouroldstyle /fiveoldstyle /sixoldstyle /sevenoldstyle + /eightoldstyle /nineoldstyle /colon /semicolon /.notdef /threequartersemdash /.notdef /questionsmall +% \10x + /.notdef /.notdef /.notdef /.notdef /Ethsmall /.notdef /.notdef /onequarter + /onehalf /threequarters /oneeighth /threeeighths /fiveeighths /seveneighths /onethird /twothirds + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /ff /fi + /fl /ffi /ffl /parenleftinferior /.notdef /parenrightinferior /Circumflexsmall /hypheninferior +% \14x + /Gravesmall /Asmall /Bsmall /Csmall /Dsmall /Esmall /Fsmall /Gsmall + /Hsmall /Ismall /Jsmall /Ksmall /Lsmall /Msmall /Nsmall /Osmall + /Psmall /Qsmall /Rsmall /Ssmall /Tsmall /Usmall /Vsmall /Wsmall + /Xsmall /Ysmall /Zsmall /colonmonetary /onefitted /rupiah /Tildesmall /.notdef +% \20x + /.notdef /asuperior /centsuperior /.notdef /.notdef /.notdef /.notdef /Aacutesmall + /Agravesmall /Acircumflexsmall /Adieresissmall /Atildesmall /Aringsmall /Ccedillasmall /Eacutesmall /Egravesmall + /Ecircumflexsmall /Edieresissmall /Iacutesmall /Igravesmall /Icircumflexsmall /Idieresissmall /Ntildesmall /Oacutesmall + /Ogravesmall /Ocircumflexsmall /Odieresissmall /Otildesmall /Uacutesmall /Ugravesmall /Ucircumflexsmall /Udieresissmall +% \24x + /.notdef /eightsuperior /fourinferior /threeinferior /sixinferior /eightinferior /seveninferior /Scaronsmall + /.notdef /centinferior /twoinferior /.notdef /Dieresissmall /.notdef /Caronsmall /osuperior + /fiveinferior /.notdef /commainferior /periodinferior /Yacutesmall /.notdef /dollarinferior /.notdef + /.notdef /Thornsmall /.notdef /nineinferior /zeroinferior /Zcaronsmall /AEsmall /Oslashsmall +% \30x + /questiondownsmall /oneinferior /Lslashsmall /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /Cedillasmall /.notdef /.notdef /.notdef /.notdef /.notdef /OEsmall + /figuredash /hyphensuperior /.notdef /.notdef /.notdef /.notdef /exclamdownsmall /.notdef + /Ydieresissmall /.notdef /onesuperior /twosuperior /threesuperior /foursuperior /fivesuperior /sixsuperior +% \34x + /sevensuperior /ninesuperior /zerosuperior /.notdef /esuperior /rsuperior /tsuperior /.notdef + /.notdef /isuperior /ssuperior /dsuperior /.notdef /.notdef /.notdef /.notdef + /.notdef /lsuperior /Ogoneksmall /Brevesmall /Macronsmall /bsuperior /nsuperior /msuperior + /commasuperior /periodsuperior /Dotaccentsmall /Ringsmall /.notdef /.notdef /.notdef /.notdef +256 packedarray +6 1 index .registerencoding +.defineencoding +exec diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_mgl_e.ps b/Master/tlpkg/tlgs/Resource/Init/gs_mgl_e.ps new file mode 100644 index 00000000000..64cadd18ce8 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_mgl_e.ps @@ -0,0 +1,64 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% $Id: gs_mgl_e.ps 8954 2008-08-08 04:22:38Z ray $ +% Define the Macintosh standard glyph encoding vector. +% This is not an Encoding strictly speaking, but we treat it like one. +/currentglobal where + { pop currentglobal { setglobal } //true setglobal } + { { } } +ifelse +/MacRomanEncoding .findencoding +/MacGlyphEncoding + /.notdef /.null /CR +% 3 +4 index 32 95 getinterval aload pop +% 98 +99 index 128 45 getinterval aload pop +% 143 + /notequal /AE + /Oslash /infinity /plusminus /lessequal /greaterequal + /yen /mu1 /partialdiff /summation /product + /pi /integral /ordfeminine /ordmasculine /Ohm + /ae /oslash /questiondown /exclamdown /logicalnot + /radical /florin /approxequal /increment /guillemotleft + /guillemotright /ellipsis /nbspace +% 173 +174 index 203 12 getinterval aload pop + /lozenge +% 186 +187 index 216 24 getinterval aload pop + /applelogo +% 211 +212 index 241 7 getinterval aload pop + /overscore +% 219 +220 index 249 7 getinterval aload pop +% 226 + /Lslash /lslash /Scaron /scaron + /Zcaron /zcaron /brokenbar /Eth /eth + /Yacute /yacute /Thorn /thorn /minus + /multiply /onesuperior /twosuperior /threesuperior /onehalf + /onequarter /threequarters /franc /Gbreve /gbreve + % The TrueType documentation says the next glyph is named + % Idot, but the Adobe standard name for this glyph is + % Idotaccent. + /Idotaccent /Scedilla /scedilla /Cacute /cacute + /Ccaron /ccaron /dmacron +260 -1 roll pop % delete MacRomanEncoding +258 packedarray +7 1 index .registerencoding +.defineencoding +exec diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_mro_e.ps b/Master/tlpkg/tlgs/Resource/Init/gs_mro_e.ps new file mode 100644 index 00000000000..a90df4e9440 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_mro_e.ps @@ -0,0 +1,61 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% $Id: gs_mro_e.ps 8954 2008-08-08 04:22:38Z ray $ +% Define the MacRoman encoding vector. +/currentglobal where + { pop currentglobal { setglobal } //true setglobal } + { { } } +ifelse +/MacRomanEncoding +StandardEncoding 0 39 getinterval aload pop + /quotesingle +StandardEncoding 40 56 getinterval aload pop + /grave +StandardEncoding 97 31 getinterval aload pop +% \20x + /Adieresis /Aring /Ccedilla /Eacute /Ntilde /Odieresis /Udieresis /aacute + /agrave /acircumflex /adieresis /atilde /aring /ccedilla /eacute /egrave + /ecircumflex /edieresis /iacute /igrave + /icircumflex /idieresis /ntilde /oacute + /ograve /ocircumflex /odieresis /otilde + /uacute /ugrave /ucircumflex /udieresis +% \24x + /dagger /degree /cent /sterling /section /bullet /paragraph /germandbls + /registered /copyright /trademark /acute /dieresis /.notdef /AE /Oslash + /.notdef /plusminus /.notdef /.notdef /yen /mu /.notdef /.notdef + /.notdef /.notdef /.notdef /ordfeminine /ordmasculine /.notdef /ae /oslash +% \30x + /questiondown /exclamdown /logicalnot /.notdef + /florin /.notdef /.notdef /guillemotleft + /guillemotright /ellipsis /space /Agrave /Atilde /Otilde /OE /oe + /endash /emdash /quotedblleft /quotedblright + /quoteleft /quoteright /divide /.notdef + % NOTE: Euro should replace currency, but the PDF 1.3 documentation + % explicitly says it does not. + /ydieresis /Ydieresis /fraction /currency + /guilsinglleft /guilsinglright /fi /fl +% \34x + /daggerdbl /periodcentered /quotesinglbase /quotedblbase + /perthousand /Acircumflex /Ecircumflex /Aacute + /Edieresis /Egrave /Iacute /Icircumflex + /Idieresis /Igrave /Oacute /Ocircumflex + /.notdef /Ograve /Uacute /Ucircumflex + /Ugrave /dotlessi /circumflex /tilde + /macron /breve /dotaccent /ring /cedilla /hungarumlaut /ogonek /caron +256 packedarray +5 1 index .registerencoding +.defineencoding +exec diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_pdf_e.ps b/Master/tlpkg/tlgs/Resource/Init/gs_pdf_e.ps new file mode 100644 index 00000000000..be596585939 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_pdf_e.ps @@ -0,0 +1,43 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Define the PDFDoc encoding vector. +/currentglobal where + { pop currentglobal { setglobal } //true setglobal } + { { } } +ifelse +/PDFDocEncoding +ISOLatin1Encoding 0 24 getinterval aload pop + /breve /caron /circumflex /dotaccent /hungarumlaut /ogonek /ring /tilde +ISOLatin1Encoding 32 7 getinterval aload pop + /quotesingle +ISOLatin1Encoding 40 5 getinterval aload pop + /hyphen +ISOLatin1Encoding 46 50 getinterval aload pop + /grave +ISOLatin1Encoding 97 31 getinterval aload pop +% \20x + /bullet /dagger /daggerdbl /ellipsis /emdash /endash /florin /fraction + /guilsinglleft /guilsinglright /minus /perthousand + /quotedblbase /quotedblleft /quotedblright /quoteleft + /quoteright /quotesinglbase /trademark /fi /fl /Lslash /OE /Scaron + /Ydieresis /Zcaron /dotlessi /lslash /oe /scaron /zcaron /.notdef +% \24x + /Euro +ISOLatin1Encoding 161 12 getinterval aload pop + /.notdef +ISOLatin1Encoding 174 82 getinterval aload pop +256 packedarray .defineencoding +exec diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_pdfwr.ps b/Master/tlpkg/tlgs/Resource/Init/gs_pdfwr.ps new file mode 100644 index 00000000000..b49eec43f9b --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_pdfwr.ps @@ -0,0 +1,1054 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% PDF writer additions to systemdict. + +% This file should be included iff the pdfwrite "device" is included +% in the executable. + +% ---------------- Predefined configurations ---------------- % + +% These correspond to the 4 predefined settings in Acrobat Distiller 5, +% plus a "default" setting that doesn't downsample images. + +{ /pdfwrite finddevice pop } .internalstopped +{pop pop (%END PDFWR) .skipeof} if + +languagelevel 2 .setlanguagelevel + +/.a2112 [2 1 1 2] readonly def +/.a1111 [1 1 1 1] readonly def +/.standardfonts [ + /Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique + /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique + /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic + /Symbol /ZapfDingbats +] readonly def + +% Parameters common to all non-default configurations. +% Note that the default configuration overrides a few of these. +/.defaultImageDict mark + /QFactor 0.9 /Blend 1 + /HSamples .a2112 /VSamples .a2112 +.dicttomark readonly def +/.distillercommon mark + /AlwaysEmbed [] + /AntiAliasColorImages //false + /AntiAliasGrayImages //false + /AntiAliasMonoImages //false + /ASCII85EncodePages //false + /AutoFilterColorImages //true + /AutoFilterGrayImages //true + /AutoPositionEPSFiles //true + /Binding /Left + /CalCMYKProfile (None) % (U.S. Web Coated (SWOP) v2) + /CalGrayProfile (None) % (Dot Gain 20%) + /CalRGBProfile (None) % (sRGB IEC61966-2.1) + /ColorImageDepth -1 + /ColorImageDict .defaultImageDict + /ColorImageDownsampleThreshold 1.5 + /ColorImageFilter /DCTEncode + /CompressPages //true + /ConvertImagesToIndexed //true + /DefaultRenderingIntent /Default + /DetectBlends //true + /DownsampleColorImages //true + /DownsampleGrayImages //true + /DownsampleMonoImages //true + /EmitDSCWarnings //false + /EncodeColorImages //true + /EncodeGrayImages //true + /EncodeMonoImages //true + /EndPage -1 + /GrayImageDepth -1 + /GrayImageDict .defaultImageDict + /GrayImageDownsampleThreshold 1.5 + /GrayImageFilter /DCTEncode + /ImageMemory 524288 + /LockDistillerParams //false + /MaxSubsetPct 100 + /MonoImageDepth -1 + /MonoImageDict mark + /K -1 + .dicttomark readonly + /MonoImageDownsampleThreshold 1.5 + /MonoImageFilter /CCITTFaxEncode + /OffOptimizations 0 + /OPM 1 + /Optimize //true + /ParseDSCComments //true + /ParseDSCCommentsForDocInfo //true + /PDFXTrimBoxToMediaBoxOffset [0 0 0 0] + /PDFXSetBleedBoxToMediaBox //true + /PDFXBleedBoxToTrimBoxOffset [0 0 0 0] + /PreserveCopyPage //true + /PreserveHalftoneInfo //false + /sRGBProfile (None) % (sRGB IEC61966-2.1) + /StartPage 1 + /SubsetFonts //true + /TransferFunctionInfo /Preserve + /UseFlateCompression //true + /UsePrologue //false +.dicttomark readonly def + +/.distillersettings mark + +/default mark + /AutoRotatePages /PageByPage + /CannotEmbedFontPolicy /Warning + /ColorACSImageDict .defaultImageDict + /ColorConversionStrategy /LeaveColorUnchanged +% /ColorImageDownsampleType +% /ColorImageResolution +% /CompatibilityLevel + /CreateJobTicket //false + /DoThumbnails //false + /DownsampleColorImages //false % override + /DownsampleGrayImages //false % override + /DownsampleMonoImages //false % override + /EmbedAllFonts //true + /GrayACSImageDict .defaultImageDict +% /GrayImageDownsampleType +% /GrayImageResolution +% /MonoImageDownsampleType +% /MonoImageResolution + /NeverEmbed .standardfonts + /Optimize //false % override + /PreserveEPSInfo //true + /PreserveOPIComments //true + /PreserveOverprintSettings //true + /UCRandBGInfo /Preserve +.dicttomark readonly + +/.screenACSImageDict mark + /QFactor 0.76 /Blend 1 /ColorTransform 1 + /HSamples .a2112 /VSamples .a2112 +.dicttomark readonly def +/screen mark + /AutoRotatePages /PageByPage +% /CalGrayProfile (None) + /CannotEmbedFontPolicy /Warning + /ColorACSImageDict .screenACSImageDict + /ColorConversionStrategy /sRGB + /ColorImageDownsampleType /Average + /ColorImageResolution 72 + /CompatibilityLevel 1.5 + /CreateJobTicket //false + /DoThumbnails //false + /EmbedAllFonts //true + /GrayACSImageDict .screenACSImageDict + /GrayImageDownsampleType /Average + /GrayImageResolution 72 + /MonoImageDownsampleType /Subsample + /MonoImageResolution 300 + /NeverEmbed .standardfonts + /PreserveEPSInfo //false + /PreserveOPIComments //false + /PreserveOverprintSettings //false + /UCRandBGInfo /Remove +.dicttomark readonly + +/ebook mark + /AutoRotatePages /All +% /CalGrayProfile (None) + /CannotEmbedFontPolicy /Warning + /ColorACSImageDict .screenACSImageDict + /ColorConversionStrategy /sRGB + /ColorImageDownsampleType /Average + /ColorImageResolution 150 + /CompatibilityLevel 1.5 + /CreateJobTicket //false + /DoThumbnails //false + /EmbedAllFonts //true + /GrayACSImageDict .screenACSImageDict + /GrayImageDownsampleType /Average + /GrayImageResolution 150 + /MonoImageDownsampleType /Subsample + /MonoImageResolution 300 + /NeverEmbed .standardfonts + /PreserveEPSInfo //false + /PreserveOPIComments //false + /PreserveOverprintSettings //false + /UCRandBGInfo /Remove +.dicttomark readonly + +/.printerACSImageDict mark + /QFactor 0.4 /Blend 1 /ColorTransform 1 + /HSamples .a1111 /VSamples .a1111 +.dicttomark readonly def +/printer mark + /AutoRotatePages /None +% /CalGrayProfile (None) + /CannotEmbedFontPolicy /Warning + /ColorACSImageDict .printerACSImageDict + /ColorConversionStrategy /UseDeviceIndependentColor + /ColorImageDownsampleType /Average + /ColorImageResolution 300 + /CompatibilityLevel 1.5 + /CreateJobTicket //true + /DoThumbnails //false + /EmbedAllFonts //true + /GrayACSImageDict .printerACSImageDict + /GrayImageDownsampleType /Average + /GrayImageResolution 300 + /MonoImageDownsampleType /Subsample + /MonoImageResolution 1200 + /NeverEmbed [] + /PreserveEPSInfo //true + /PreserveOPIComments //true + /PreserveOverprintSettings //true + /UCRandBGInfo /Preserve +.dicttomark readonly + +/.prepressACSImageDict mark + /QFactor 0.15 /Blend 1 /ColorTransform 1 + /HSamples .a1111 /VSamples .a1111 +.dicttomark readonly def +/prepress mark + /AutoRotatePages /None + /CannotEmbedFontPolicy /Error + /ColorACSImageDict .prepressACSImageDict + /ColorConversionStrategy /LeaveColorUnchanged + /ColorImageDownsampleType /Bicubic + /ColorImageResolution 300 + /CompatibilityLevel 1.5 + /CreateJobTicket //true + /DoThumbnails //true + /EmbedAllFonts //true + /GrayACSImageDict .prepressACSImageDict + /GrayImageDownsampleType /Bicubic + /GrayImageResolution 300 + /MonoImageDownsampleType /Subsample + /MonoImageResolution 1200 + /NeverEmbed [] + /PreserveEPSInfo //true + /PreserveOPIComments //true + /PreserveOverprintSettings //true + /UCRandBGInfo /Preserve +.dicttomark readonly + +% Define distiller settings for the ps2write device and for the ps2ps2 script : +/PSL2Printer mark + /AutoRotatePages /None + /CannotEmbedFontPolicy /Error + /ColorACSImageDict .prepressACSImageDict + /ColorConversionStrategy /LeaveColorUnchanged + /ColorImageDownsampleType /Subsample + /ColorImageResolution 600 + /DownsampleColorImages false + /CompatibilityLevel 1.2 % Always 1.2 with ps2write. + % /CreateJobTicket //true % Not sure + /DoThumbnails //false + /EmbedAllFonts //true + /GrayACSImageDict .prepressACSImageDict + /GrayImageDownsampleType /Subsample + /GrayImageResolution 600 + /DownsampleGrayImages false + /MonoImageDownsampleType /Subsample + /MonoImageResolution 1200 + /DownsampleMonoImages false + /NeverEmbed [] + /PreserveEPSInfo //true + /PreserveOPIComments //true + /PreserveOverprintSettings //true + /UCRandBGInfo /Preserve + /PreserveHalftoneInfo //true + /TransferFunctionInfo /Preserve +%% Deprecated in 9.06 +%% /MaxViewerMemorySize 8000000 + /CompressPages //false + /CompressFonts //true + /ASCII85EncodePages //true +.dicttomark readonly + +.dicttomark readonly def + +% ---------------- End of predefined configurations ---------------- % + +% Set optimizations for converting PostScript to PDF. +% The ps2pdf* scripts invoke this. +/.setpdfwrite { % - .setpdfwrite - + % Set a large VM threshold to reduce garbage collection. + currentuserparams /VMThreshold get 3000000 .max setvmthreshold +} bind def + +% ---------------- pdfmark and DSC processing ---------------- % + +/.write_small_positive_real % <file> <real> .write_small_positive_real - +{ % The argument must be grater than 0 and must be strongly samller than 0.1. + % The conversion isn't simple due to the low (24 bits) precision + % of the floating point arithmetics in Postscript. + % For best result we first use the 1e8 factor since its binary + % representation 101111101011110000100000000 well rounds into 14 significant + % bits : 101111101011110000000000000 . + 1 index (.) writestring + { dup 100000000 mul + dup 10 mul 1 ge { + % Will need not greater than 0.1 due to a rounding below. + pop exit + } if + exch pop + 1 index (00000000) writestring + } loop + % Now it is not smaller than 1e-9, use simple digitizing. + { dup 10 mul + dup 10 mul 1 ge { + pop exit + } if + exch pop + 1 index (0) writestring + } loop + % Now 0.01 <= n < 0.1, but rounding may give 0.1 . + % Convert to integer with 7 digits precision : + 100000000 % precision factor 1e8 % f n r + dup 10 idiv 3 1 roll mul 0.5 add cvi % f r' N + 2 copy le { + % The rounding overflows, suppress it. + % Note it carries out an additional digit, + % that's why we needed <0.1 above. + pop pop (1) writestring + } { + % Didn't cary out, put 0. + 2 index (0) writestring + exch % f N r + % Continue the simple digitizing : + { 10 idiv dup % f N r' r' + 2 index exch idiv % f N r' d + (0123456789) exch 1 getinterval % f N r' (d) + 3 index exch writestring % f N r' + dup 3 2 roll exch mod % f r' N' + dup 0 eq { + % Don't write trailing zeros. + exit + } if + exch % f N' r' + } loop + pop pop pop + } ifelse +} bind def + +% Encode values to pass for the /pdfmark or /DSC pseudo-parameter. +/.pdf===dict mark + /arraytype + { dup xcheck { ({) (}) } { ([) (]) } ifelse + % Stack: file obj left right + 4 1 roll 2 index exch writestring () exch + { exch 2 index exch writestring + 1 index exch pdf===only ( ) + } + forall pop exch writestring + } bind + /packedarraytype 1 index + /dicttype + { 1 index (<<\n) writestring + { 2 index 3 -1 roll pdf===only 1 index ( ) writestring + 1 index exch pdf===only dup (\n) writestring + } + forall (>>) writestring + } bind + /nametype { + % If the name string includes any non-regular characters, + % write it with two preceding and one following null character(s). + % (Null characters in the name itself are not allowed.) + % This non-standard escape convention is required for passing names + % that include non-regular characters, because PostScript provides + % no way to do this. The pdf_scan_token procedure in the C code of + % the pdfwrite driver is currently the only place that recognizes + % this convention. + % Note that \004 may be self-delimiting in gs, but is not in standard PS. + dup .namestring (\000\004\011\012\014\015 %()/<>[]{}) .stringbreak //null ne { + dup .namestring (\000) .stringbreak //null ne { + 1 index <000000> writestring 1 index exch write===only 1 index exch 0 write 0 write + }{ + 1 index <0000> writestring 1 index exch write===only 0 write + }ifelse + } { + write===only + } ifelse + } bind + /realtype { + % Prevent using floating point format - see Bug 688167. + dup dup 0 lt { neg } if 0.01 lt { + dup 0 eq { + pop (0) writestring + } { + dup 0 lt { + 1 index (-) writestring neg + } if + .write_small_positive_real + } ifelse + } { + write===only + } ifelse + } bind +.dicttomark readonly def +/pdf===only { % <file> <obj> pdf===only - + .pdf===dict 1 index type .knownget { exec } { write===only } ifelse +} bind def +/.pdfcvbuf 30 string def % enough for most arguments +userdict /.pdfcvstring () put +/.pdfcvs { % <obj> .pdfcvs <string> + currentglobal exch //false .setglobal + /.pdfcvstring () store + % We can't handle long values yet. + { pop dup length 0 eq { pop } { + /.pdfcvstring .pdfcvstring 3 -1 roll concatstrings store + } ifelse //.pdfcvbuf + } /NullEncode filter dup 3 -1 roll pdf===only + closefile + .setglobal .pdfcvstring +} bind def + +% Redefine pdfmark to pass the data to the driver. +% We use a pseudo-parameter named /pdfmark whose value is an array: +% /key1 (value1) ... (CTM) /type +/.pdfputparams { % -mark- <key1> <value1> ... .pdfputparams <result...> + currentdevice //null //false counttomark 1 add 3 roll + % Don't allow the page device to get cleared.... + {.putdeviceparams} .currentpagedevice pop {.setpagedevice} 3 .execn +} bind def +% Convert relevant operands to strings in an array. +/.pdfcvsloop { % -mark- values ... markname start step .pdfcvsloop + % [values ... ctm markname] + matrix currentmatrix .pdfcvs 4 1 roll + counttomark 1 add 2 roll + counttomark .localvmarray astore exch pop + 3 1 roll + % Stack: values start step + 2 index length 3 sub { 2 copy 2 copy get .pdfcvs put pop } for +} bind def +/.pdfcvsall { % -mark- values ... markname .pdfcvsall <<same>> + 0 1 .pdfcvsloop +} bind def +/.pdfcvseven { % -mark- key value ... markname .pdfcvseven <<same>> + 1 2 .pdfcvsloop +} bind def +/.pdfcvsnone { % -mark- values ... markname .pdfcvsnone <<same>> + 100000 1 .pdfcvsloop +} bind def +/.pdfcvsfirst { % -mark- first values ... markname .pdfcvsfirst<<same>> + .pdfcvsnone + dup 0 2 copy get .pdfcvs put +} bind def +% The procedures in the following dictionary are called with the entire +% pdfmark operand list (including the pdfmark name) on the stack; +% they may modify this ad lib. They must call .pdfcvsxxx. +/.pdfmarkparams mark + % Unpack a dictionary for PUT, and don't convert stream data. + /PUT { + counttomark 3 eq { + 1 index type /dicttype eq { + pop { } forall /.PUTDICT .pdfcvsall + } { + pop dup type /filetype eq { + % Read the file into a sequence of strings. + % This isn't great, but it's simple. + { + dup 64000 string readstring not { exch exit } if + exch + } loop closefile + } if + /.PUTSTREAM .pdfcvsfirst + } ifelse + } { + .pdfcvsall + } ifelse + } bind + % Unpack the array for PUTINTERVAL. + /PUTINTERVAL { + pop aload pop /.PUTINTERVAL .pdfcvsall + } bind +.dicttomark readonly def +/.pdfparamerror { % ? ? ? -mark- ... <errname> <opname> .pdfparamerror - + counttomark 4 add 2 roll cleartomark pop pop pop + .systemvar exch signalerror +} bind def + +/.CountLeafs { + 0 exch + { + oforce dup type /dicttype eq { + /Limits knownoget { + dup type /arraytype eq { + 1 get 2 copy lt { + exch pop + }{ + pop + }ifelse + }{ + (invalid number tree, /Limits not an array\n) print + pop pop 0 exit + } ifelse + }{ + (invalid number tree, /Limits not defined in intermediate or leaf node\n) print + pop pop 0 exit + }ifelse + } { + (invalid number tree, /Kids entry not a dictionary\n) print + pop pop 0 exit + } ifelse + } forall +} bind def + +/.ExtractLeafs +{ + { + oforce dup /Nums knownoget { + exch pop + dup length 1 sub 0 2 3 -1 roll { + %% dict array index + dup %% dict array index index + 2 index exch get %% dict array index + 20 string cvs cvn %% dict array index name + exch 1 add %% dict array name index+1 + 2 index exch oget %% dict array name object + 3 index %% dict array name object dict + 3 1 roll %% dict array dict name object + put %% dict array + } for + pop %% array + }{ + /Kids knownoget { + .ExtractLeafs + } if + } ifelse + } forall +} bind def + +/.pdfpagelabels { + dup type /dicttype eq { + dup /Nums knownoget { + exch pop + mark exch + 0 1 2 index length 1 sub { + 1 index exch oget + exch + } for + pop + counttomark array astore + 1 dict dup begin exch /Nums exch def end + .pdfcvs + mark /pdfpagelabels 3 -1 roll .pdfputparams + dup type /booleantype ne { + /pdfpagelabels .pdfparamerror + } if cleartomark + }{ + /Kids knownoget { + dup .CountLeafs dup 1000 ge { + (PageLabel tree too complex, ignoring PageLabels\n) print flush + pop pop + }{ + dict exch .ExtractLeafs mark exch dup length 0 1 3 -1 roll { + dup 20 string cvs cvn %% mark dict index name + 2 index exch .knownget{ + %% mark ... dict index object + 3 -1 roll %% mark ... index object dict + }{ + pop + }ifelse + } for + pop + counttomark array astore + 1 dict dup begin exch /Nums exch def end + .pdfcvs + mark /pdfpagelabels 3 -1 roll .pdfputparams + dup type /booleantype ne { + /pdfpagelabels .pdfparamerror + } if cleartomark + }ifelse + }{ + (Invalid number tree in PageLabels, ignoring PageLabels\n) print flush + }ifelse + }ifelse + }{ + /pdfpagelabels .pdfparamerror + } ifelse +} bind def + +/pdfmark { % -mark- <key> <value> ... <markname> pdfmark - + counttomark 0 eq { + /pdfmark /stackunderflow signalerror + } if + dup type /nametype eq not { + /pdfmark /typecheck signalerror + } if + dup /SP eq { + % A hack for synchronizing the clipping path. + gsave + [1 0 0 1 0 0] setmatrix 0 setlinewidth + newpath -3 -3 moveto closepath stroke % Paints outside the device bbox. + grestore + } if + dup /PS eq systemdict /PDFX .knownget not { //false } if + systemdict /PDFA .knownget not { //false }{0 eq {//false}{//true} ifelse} ifelse or and { + % Execute it since PDF/X doesn't allow to embed it. + pop + { dup mark eq { + pop exit + } if + 1 index /DataSource eq { + exch pop + cvx exec + } { + pop pop + } ifelse + } loop + } { + counttomark 1 add copy + //.pdfmarkparams 1 index .knownget { exec } { .pdfcvsall } ifelse + mark /pdfmark 3 -1 roll .pdfputparams + dup type /booleantype ne { + /pdfmark .pdfparamerror + } if cleartomark + } ifelse +} odef +userdict /pdfmark .undef +currentdict /.pdfmarkparams .undef + +% <dict> .hook_DSC_Creator - +/.pdf_hook_DSC_Creator +{ + % If the Creator is PScript5.dll, disable the 32 /FontType resource for + % handling GlyphNames2Unicode. Since /FontType category can't redefine, + % we can do only with redefining the operator 'resourcestatus'. + systemdict /.pdf_hooked_DSC_Creator .knownget + { + {//false}{//true} ifelse + } + { + //true + } ifelse + + { + /WantsToUnicode /GetDeviceParam .special_op { + exch pop + }{ + //true + }ifelse + { + /Creator .knownget { + (PScript5.dll) search { + pop pop + systemdict /resourcestatus dup + { dup /FontType eq 2 index 32 eq and { + pop pop //false + } { + resourcestatus + } ifelse + } bind .makeoperator .forceput + systemdict /.pdf_hooked_DSC_Creator //true .forceput + } if + pop + } if + } { + pop + } ifelse + } + { + pop + } ifelse +} +bind def + +% Use the DSC processing hook to pass DSC comments to the driver. +% We use a pseudo-parameter named DSC whose value is an array: +% /key1 (value1) ... /type +/.pdfdsc_dict 2 dict def +/.pdfdsc { % <file> <DSC string> <dsc dict> [<prev proc>] .pdfdsc - + 0 get dup //null ne { 4 copy exch pop exec pop } { pop } ifelse 3 -1 roll pop + % Stack: <dsc string> <dsc dict> + 20 .localvmdict 1 index { 3 copy put pop pop } forall + 3 -1 roll .parse_dsc_comments % <dsc dict> <dict> <type> + 1 index //.pdf_hook_DSC_Creator exec + dup /NOP ne 2 index length 1 gt or { % Skip unparsed comments + PDFWRDEBUG { (**** DSC comment: ) print dup //== exec 1 index === flush } if + exch mark 4 1 roll { + % mark <key1> <value1> ... <dsc dict> <type> <key> <value> + 3 index 2 index known { % Skip the DSC_struct entry + pop pop + } { + .pdfcvs 4 -2 roll + } ifelse + } forall exch pop counttomark .localvmarray astore + mark /DSC 3 -1 roll .pdfputparams + dup type /booleantype ne { + /DSC .pdfparamerror + } { + cleartomark + } ifelse + } { + pop pop pop + } ifelse +} bind def +currentdict /.pdf_hook_DSC_Creator undef +/.initialize_dsc_parser where { + pop + 3000 % priority + { + currentglobal //true setglobal + 2 dict dup .initialize_dsc_parser readonly + currentuserparams /ProcessDSCComment get + 1 array astore % in case the value is executable + //.pdfdsc /exec load 4 array astore cvx readonly + << /ProcessDSCComment 3 -1 roll >> setuserparams + setglobal + } bind .schedule_init +} if + +% ---------------- {set,current}distillerparams ---------------- % + +% Define setdistillerparams / currentdistillerparams. +% Distiller parameters are currently treated as device parameters. +/.distillerparamkeys mark + % General parameters -- all distillers + /ASCII85EncodePages { } + /AutoRotatePages { } + /Binding { } + /CompressPages { } + /DefaultRenderingIntent { } + /DetectBlends { } + /DoThumbnails { } + /ImageMemory { } + /LockDistillerParams { } + /LZWEncodePages { } + /OPM { } + /PreserveHalftoneInfo { } + /PreserveOPIComments { } + /PreserveOverprintSettings { } + /TransferFunctionInfo { } + /UCRandBGInfo { } + /UseFlateCompression { } + % General parameters -- PDF writer + % StartPage and EndPage are renamed because EndPage + % clashes with a page device parameter. + /CoreDistVersion { } + /CompatibilityLevel { } + % ****** NOTE: StartPage and EndPage are disabled because + % ****** EndPage clashes with a page device parameter. +% /EndPage { exch pop /PDFEndPage exch } + /PDFEndPage { pop pop } +% /StartPage { exch pop /PDFStartPage exch } + /PDFStartPage { pop pop } + /Optimize { } + /ParseDSCCommentsForDocInfo { } + /ParseDSCComments { } + /EmitDSCWarnings { } + /CreateJobTicket { } + /PreserveEPSInfo { } + /AutoPositionEPSFiles { } + /PreserveCopyPage { } + /UsePrologue { } + /OffOptimizations { } + % PDF/X parameters + /PDFXTrimBoxToMediaBoxOffset { } + /PDFXSetBleedBoxToMediaBox { } + /PDFXBleedBoxToTrimBoxOffset { } + % Color sampled image parameters + /ColorACSImageDict { } + /AntiAliasColorImages { } + /AutoFilterColorImages { } + /ColorImageDepth { } + /ColorImageDict { } + /DownsampleColorImages { } + /ColorImageDownsampleThreshold { } + /ColorImageDownsampleType { } + /ColorImageAutoFilterStrategy { } + /EncodeColorImages { } + /ColorImageFilter { } + /ColorImageResolution { } + % Color processing parameters + /CalCMYKProfile { } + /CalGrayProfile { } + /CalRGBProfile { } + /sRGBProfile { } + /ColorConversionStrategy { } + /ConvertCMYKImagesToRGB { } + /ConvertImagesToIndexed { } + % Grayscale sampled image parameters + /GrayACSImageDict { } + /AntiAliasGrayImages { } + /AutoFilterGrayImages { } + /GrayImageDepth { } + /GrayImageDict { } + /DownsampleGrayImages { } + /GrayImageDownsampleThreshold { } + /GrayImageDownsampleType { } + /GrayImageAutoFilterStrategy { } + /EncodeGrayImages { } + /GrayImageFilter { } + /GrayImageResolution { } + % Monochrome sampled image parameters + /AntiAliasMonoImages { } + /MonoImageDepth { } + /MonoImageDict { } + /DownsampleMonoImages { } + /MonoImageDownsampleThreshold { } + /MonoImageDownsampleType { } + /EncodeMonoImages { } + /MonoImageFilter { } + /MonoImageResolution { } + % Font embedding parameters + /AlwaysEmbed + { dup length 0 gt + { dup 0 get type /booleantype eq } { //false } ifelse + { dup 0 get + { dup length 1 sub 1 exch getinterval + } + { dup length 1 sub 1 exch getinterval exch pop /~AlwaysEmbed exch + } ifelse + } + { exch pop /.AlwaysEmbed exch + } ifelse + } + /NeverEmbed + { dup length 0 gt + { dup 0 get type /booleantype eq } { //false } ifelse + { dup 0 get + { dup length 1 sub 1 exch getinterval + } + { dup length 1 sub 1 exch getinterval exch pop /~NeverEmbed exch + } ifelse + } + { exch pop /.NeverEmbed exch + } ifelse + } + /CannotEmbedFontPolicy { } + /EmbedAllFonts { } + /MaxSubsetPct { } + /SubsetFonts { } + /DSCEncodingToUnicode { } + /PSDocOptions { } + /PSPageOptions { } +.dicttomark readonly def +/.distillerdevice + { + % Check to see if the current device is a Distiller + % and return it if so. + /IsDistiller /GetDeviceParam .special_op { + exch pop + }{ + //false + }ifelse + { currentdevice } + { /pdfwrite finddevice } + ifelse + } bind def + +% Some badly designed PostScript files only expect the current/set +% distillerparams operators to exist in a distiller. Since we have +% this as a runtime option, we enable these operators IFF the +% currentdevice is pdfwrite. Also, we mask their existence in +% systemdict so that 'where' and 'known' don't show them unless +% the currentdevice is pdfwrite. +/.setdistillerparams { % <dict> setdistillerparams - + .distillerdevice //null //false mark 4 index { + //.distillerparamkeys 2 index .knownget { exec } { pop pop } ifelse + } forall .putdeviceparamsonly + dup type /booleantype ne { + /setdistillerparams .pdfparamerror + } { + pop pop pop + } ifelse +} odef +/.currentdistillerparams { % - currentdistillerparams <dict> + .distillerdevice //.distillerparamkeys .getdeviceparams .dicttomark + % Patch StartPage and EndPage + % ****** NOTE: StartPage and EndPage are disabled because + % ****** EndPage clashes with a page device parameter. +% begin /StartPage PDFStartPage /EndPage PDFEndPage +% currentdict dup /PDFStartPage undef /PDFEndPage undef +% def def currentdict end +} odef +/setdistillerparams { + % Check to see if the current device is a Distiller + /IsDistiller /GetDeviceParam .special_op { + exch pop not + }{ + //true + }ifelse + { + /setdistillerparams /undefined signalerror + } if + .setdistillerparams +} bind odef +/currentdistillerparams { + % Check to see if the current device is a Distiller + /IsDistiller /GetDeviceParam .special_op { + exch pop not + }{ + //true + }ifelse + { + /currentdistillerparams /undefined signalerror + } if + .currentdistillerparams +} bind odef + +% Patch 'where' so that the distiller operators are only visible +% if the pdfwrite device is the current one. +{ + % Check to see if the current device is a Distiller + /IsDistiller /GetDeviceParam .special_op { + exch pop + }{ + //false + }ifelse + { + .where + } { + .where pop dup //systemdict eq { pop //false } { //true } ifelse + } ifelse +} bind +{ /currentdistillerparams /setdistillerparams /pdfmark } +{ .wheredict exch 2 index put } forall pop + +% Patch 'known' to hide the systemdict version of distiller operators +% unless the currentdevice is pdfwrite. +/known { + /currentdistillerparams 1 index eq /setdistillerparams 2 index eq or + /pdfmark 2 index eq or { + systemdict 2 index eq { % only mask the operator in systemdict + known + % Check to see if the current device is a Distiller + /IsDistiller /GetDeviceParam .special_op { + exch pop not + }{ + //true + }ifelse + { pop false } if + } { + known + } ifelse + } { + known + } ifelse +} .bind odef + +% Create a table for translation DSC comments into Unicode UTF-16 +/.make_DSC_translation_table { % <encoding> .make_DSC_translation_table <array> + dup type /stringtype eq { + cvn + } if + dup type /nametype eq { + /Encoding findresource + } if + dup length array exch % [out] [in] + 0 1 2 index length 1 sub { % [out] [in] i + dup 2 index exch get % [out] [in] i n + dup dup //null eq exch /.notdef eq or { + pop -1 + } { + dup //AdobeGlyphList exch .knownget { % [out] [in] i n c + dup type dup /arraytype eq exch /packedarraytype eq or { + 0 get % fixme: using the 1st char + } if + exch pop % [out] [in] i c + } { % [out] [in] i n + (DSCEncoding defines a character that is not in AdobeGlyphList : ) + exch .namestring concatstrings = + /.make_DSC_translation_table cvx /undefined signalerror + } ifelse + } ifelse + 3 index % [out] [in] i c [out] + 3 1 roll put % [out] [in] + } for + pop % [out] +} bind def + +1000 % priority +{ + % Note, this may not work if the initial device is not pdfwrite + % and may require the use of -dProvideUnicode on the command line. + % Check to see if the current device wants ToUnicode info + /WantsToUnicode /GetDeviceParam .special_op { + exch pop + }{ + //false + }ifelse + systemdict /ProvideUnicode .knownget not { //false } if or + { + currentglobal true setglobal + systemdict /.setupUnicodeDecoder known { + /Unicode /Decoding resourcestatus { + pop pop + /Unicode /Decoding findresource + .setupUnicodeDecoder + } { + QUIET not { + (WARNING: /Unicode /Decoding resource is not accessible but it is useful for generating ToUnicode CMap.) = + } if + } ifelse + } if + setglobal + } if +} bind .schedule_init + +1010 % priority +{ + % Set a predefined configuration in the distiller device (pdfwrite) + /PDFSETTINGS where { + pop /PDFSETTINGS load + } { + % We use the presence of the OPDFRead key as a proxy for a pdfwrite-family device + /ForOPDFRead /GetDeviceParam .special_op { + % Get rid of the OPDFRead key + exch pop + % and then check the value to see if its pdfwrite or ps2write + { /PSL2Printer } { /default } ifelse + } { + /default + } ifelse + } ifelse + .distillersettings exch get + % Don't override parameters defined on the command line. + dup length .distillercommon length add dict begin + .distillercommon 2 { + { + systemdict 2 index known { pop pop } { def } ifelse + } forall + } repeat + % We use the presence of the OPDFRead key as a proxy for a pdfwrite-family device + /ForOPDFRead /GetDeviceParam .special_op { + % Get rid of the OPDFRead key + exch pop + % Then check to see if OPDFRead is true or not + not { + systemdict /PDFX known systemdict /PDFA known or { + /DSCEncoding where { + /DSCEncoding get .make_DSC_translation_table + /DSCEncodingToUnicode exch def + } if + } if + } if + } if + currentdict end .setdistillerparams + .distillerdevice //null //false mark .putdeviceparams + dup type /booleantype eq not { cleartomark pop } if pop pop +} bind .schedule_init + +2000 % priority +{ % Note, this may not work if the initial device is not pdfwrite + % We use the presence of the OPDFRead key as a proxy for a pdfwrite-family device + /ForOPDFRead /GetDeviceParam .special_op { + % Get rid of the OPDFRead key and value + pop pop + % Inform the device with initial graphic state. See gdev_pdf_fill_path. + newpath fill + } if +} bind .schedule_init + +.setlanguagelevel + +%END PDFWR diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_res.ps b/Master/tlpkg/tlgs/Resource/Init/gs_res.ps new file mode 100644 index 00000000000..db2ff269868 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_res.ps @@ -0,0 +1,1161 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Initialization file for Level 2 resource machinery. +% When this is run, systemdict is still writable, +% but (almost) everything defined here goes into level2dict. + +level2dict begin + +(BEGIN RESOURCES) VMDEBUG + +% We keep track of (global) instances with another entry in the resource +% dictionary, an .Instances dictionary. For categories with implicit +% instances, the values in .Instances are the same as the keys; +% for other categories, the values are [instance status size]. + +% Note that the dictionary that defines a resource category is stored +% in global VM. The PostScript manual says that each category must +% manage global and local instances separately. However, objects in +% global VM other than systemdict can't reference objects in local VM. +% This means that the resource category dictionary, which would otherwise be +% the obvious place to keep track of the instances, can't be used to keep +% track of local instances. Instead, we define a dictionary in local VM +% called localinstancedict, in which the key is the category name and +% the value is the analogue of .Instances for local instances. + +% We don't currently implement automatic resource unloading. +% When and if we do, it should be hooked to the garbage collector. +% However, Ed Taft of Adobe says their interpreters don't implement this +% either, so we aren't going to worry about it for a while. + +currentglobal //false setglobal systemdict begin + /localinstancedict 5 dict + .forcedef % localinstancedict is local, systemdict is global +end //true setglobal +/.emptydict 0 dict readonly def +setglobal + +% Resource category dictionaries have the following keys (those marked with +% * are optional): +% Standard, defined in the Red Book: +% Category (name) +% *InstanceType (name) +% DefineResource +% <key> <instance> DefineResource <instance> +% UndefineResource +% <key> UndefineResource - +% FindResource +% <key> FindResource <instance> +% ResourceStatus +% <key> ResourceStatus <status> <size> true +% <key> ResourceStatus false +% ResourceForAll +% <template> <proc> <scratch> ResourceForAll - +% *ResourceFileName +% <key> <scratch> ResourceFileName <filename> +% Additional, specific to our implementation: +% .Instances (dictionary) +% .LocalInstances +% - .LocalInstances <dict> +% .GetInstance +% <key> .GetInstance <instance> -true- +% <key> .GetInstance -false- +% .CheckResource +% <key> <value> .CheckResource <key> <value> <ok> +% (or may give an error if not OK) +% .DoLoadResource +% <key> .DoLoadResource <key> (may give an error) +% .LoadResource +% <key> .LoadResource - (may give an error) +% .ResourceFile +% <key> .ResourceFile <file> -true- +% <key> .ResourceFile <key> -false- +% .ResourceFileStatus +% <key> .ResourceFileStatus 2 <vmusage> -true- +% <key> .ResourceFileStatus -false- +% All the above procedures expect that the top dictionary on the d-stack +% is the resource dictionary. + +% Define enough of the Category category so we can define other categories. +% The dictionary we're about to create will become the Category +% category definition dictionary. + +% .findcategory and .resourceexec are only called from within the +% implementation of the resource 'operators', so they don't have to worry +% about cleaning up the stack if they fail (the interpreter's stack +% protection machinery for pseudo-operators takes care of this). +% Note that all places that look up categories must use .findcategory +% so that the command in case of error will be correct rather than an +% internal invocation of findresource. +/.findcategory { % <name> .findcategory - + % (pushes the category on the dstack) + /Category .findresource begin % note: *not* findresource +} bind def + +% If an error occurs within the logic of a resource operator (after operand +% acquisition and checking), the Adobe interpreters report the operator name, +% not the operator object, as the command in $error. For this reason, and +% this reason only, all resource operators must wrap their logic code in +% /<opername> cvx { ...logic... } .errorexec + +% The Category resource signals /undefined rather than /undefinedresource, +% both when referenced implicitly (to look up the category for a general +% resource operation) and when it is accessed directly (/Category /xxx +% findresource). Because of this, all resource operators must use +% .undefinedresource rather than signalling undefinedresource directly. +/.undefinedresource { % <command> .undefinedresource - + /Category dup load eq { /undefined } { /undefinedresource } ifelse + signaloperror +} bind def + +/.resourceexec { % <key> /xxxResource .resourceexec - + % (also pops the category from the dstack) + load exec end +} bind def + +% .getvminstance treats instances on disk as undefined. +/.getvminstance { % <key> .getvminstance <instance> -true- + % <key> .getvminstance -false- + .GetInstance { + dup 1 get 2 ne { //true } { pop //false } ifelse + } { + //false + } ifelse +} bind def + +20 dict begin + + % Standard entries + +/Category /Category def +/InstanceType /dicttype def + +/DefineResource { + .CheckResource { + dup /Category 3 index cvlit .growput + dup [ exch 0 -1 ] exch + .Instances 4 2 roll put + % Make the Category dictionary read-only. We will have to + % use .forceput / .forcedef later to replace the dummy, + % empty .Instances dictionary with the real one later. + readonly + } { + /defineresource cvx /typecheck signaloperror + } ifelse +} bind def +/FindResource % (redefined below) + { .Instances exch get 0 get + } bind def + + % Additional entries + +/.Instances 30 dict def +.Instances /Category [currentdict 0 -1] put + +/.LocalInstances 0 dict def +/.GetInstance + { .Instances exch .knownget + } bind def +/.CheckResource + { dup gcheck currentglobal and + { /DefineResource /FindResource /ResourceForAll /ResourceStatus + /UndefineResource } + { 2 index exch known and } + forall + not { /defineresource cvx /invalidaccess signaloperror } if + //true + } bind def + +.Instances end begin % for the base case of findresource + +(END CATEGORY) VMDEBUG + +% Define the resource operators. We use the "stack protection" feature of +% odef to make sure the stacks are restored properly on an error. +% This requires that the operators not pop anything from the stack until +% they have executed their logic successfully. We can't make this +% work for resourceforall, because the procedure it executes mustn't see +% the operands of resourceforall on the stack, but we can make it work for +% the others. + +% findresource is the only operator that needs to bind //Category. +% We define its contents as a separate procedure so that .findcategory +% can use it without entering another level of pseudo-operator. +/.findresource { % <key> <category> findresource <instance> + 2 copy dup /Category eq + { pop //Category 0 get begin } { .findcategory } ifelse + /FindResource .resourceexec exch pop exch pop +} bind +end % .Instances of Category +def +/findresource { + % See above re .errorexec. + 1 .argindex % also catch stackunderflow + dup type /stringtype eq { cvn } if % for CET 23-13-04 + 3 1 roll exch pop + dup type /nametype ne { + /findresource .systemvar /typecheck signalerror + } if + /findresource cvx //.findresource .errorexec +} odef + +/defineresource { % <key> <instance> <category> defineresource <instance> + 2 .argindex 2 index 2 index % catch stackunderflow + % See above re .errorexec. + /defineresource cvx { + .findcategory + currentdict /InstanceType known { + dup type InstanceType ne { + dup type /packedarraytype eq InstanceType /arraytype eq and + not { /defineresource cvx /typecheck signaloperror } if + } if + } if + /DefineResource .resourceexec + 4 1 roll pop pop pop + } .errorexec +} bind odef +% We must prevent resourceforall from automatically restoring the stacks, +% because we don't want the stacks restored if proc causes an error or +% executes a 'stop'. On the other hand, resourceforall is defined in the +% PLRM as an operator, so it must have type /operatortype. We hack this +% by taking advantage of the fact that the interpreter optimizes tail +% calls, so stack protection doesn't apply to the very last token of an +% operator procedure. +/resourceforall1 { % <template> <proc> <scratch> <category> resourceforall1 - + dup .findcategory + /ResourceForAll load + % Stack: <template> <proc> <scratch> <category> proc + exch pop % pop the category + exec end +} bind def +/resourceforall { % <template> <proc> <scratch> <category> resourceforall1 - + //resourceforall1 exec % see above +} bind odef +/resourcestatus { % <key> <category> resourcestatus <status> <size> true + % <key> <category> resourcestatus false + { + 0 .argindex type /nametype ne { + % CET 23-26 wants typecheck here, not undefineresource that happens + % without the check. + /resourcestatus cvx /typecheck signalerror + } if + 2 copy .findcategory /ResourceStatus .resourceexec + { 4 2 roll pop pop //true } { pop pop //false } ifelse + } stopped { + % Although resourcestatus is an operator, Adobe uses executable name + % for error reporting. CET 23-26 + /resourcestatus cvx $error /errorname get signalerror + } if +} bind odef +/undefineresource { % <key> <category> undefineresource - + 0 .argindex type /nametype ne { + /undefinedresource cvx /typecheck signaloperror + } if + 1 .argindex 1 index % catch stackunderflow + + { .findcategory /UndefineResource .resourceexec pop pop + } stopped { + % Although undefineresource is an operator, Adobe uses executable name + % here but uses operator for the errors above. CET 23-33 + /undefineresource cvx $error /errorname get signalerror + } if +} bind odef + +% Define the system parameters used for the Generic implementation of +% ResourceFileName. +systemdict begin + +% - .default_resource_dir <string> +/.default_resource_dir { + /LIBPATH .systemvar { + dup .file_name_current eq { + pop + } { + (Resource) search { + exch concatstrings + exch pop + .file_name_separator concatstrings exit + } { + pop + } ifelse + } ifelse + } forall +} bind def + +% <path> <name> <string> .resource_dir_name <path> <name> <string> +/.resource_dir_name +{ systemdict 2 index .knownget { + exch pop + systemdict 1 index undef + } { + dup () ne { + .file_name_directory_separator concatstrings + } if + 2 index exch //false .file_name_combine not { + (Error: .default_resource_dir returned ) print exch print ( that can't combine with ) print = + /.default_resource_dir cvx /configurationerror signalerror + } if + } ifelse +} bind def + +currentdict /pssystemparams known not { + /pssystemparams 10 dict readonly def +} if +pssystemparams begin + .default_resource_dir + /FontResourceDir (Font) .resource_dir_name + readonly .forcedef % pssys'params is r-o + /GenericResourceDir () .resource_dir_name + readonly .forcedef % pssys'params is r-o + pop % .default_resource_dir + /GenericResourcePathSep + .file_name_separator readonly .forcedef % pssys'params is r-o + (%diskFontResourceDir) cvn (/Resource/Font/) readonly .forcedef % pssys'params is r-o + (%diskGenericResourceDir) cvn (/Resource/) readonly .forcedef % pssys'params is r-o +end +end + +% Check if GenericResourceDir presents in LIBPATH. + +% The value of GenericResourceDir must end with directory separator. +% We use .file_name_combine to check it. +% Comments use OpenVMS syntax, because it is the most complicated case. +(x) pssystemparams /GenericResourcePathSep get +(y) concatstrings concatstrings dup length % (x]y) l1 +pssystemparams /GenericResourceDir get dup length exch % (x]y) l1 l2 (dir) +3 index //true .file_name_combine not { + exch + (File name ) print print ( cant combine with ) print = + /GenericResourceDir cvx /configurationerror signaloperror +} if +dup length % (x]y) l1 l2 (dir.x]y) l +4 2 roll add % (x]y) (dir.x]y) l ll +ne { + (GenericResourceDir value does not end with directory separator.\n) = + /GenericResourceDir cvx /configurationerror signaloperror +} if +pop pop + +pssystemparams dup /GenericResourceDir get exch /GenericResourcePathSep get +(Init) exch (gs_init.ps) concatstrings concatstrings concatstrings +status { + pop pop pop pop +} { + (\n*** Warning: GenericResourceDir doesn't point to a valid resource directory.) = + ( the -sGenericResourceDir=... option can be used to set this.\n) = + flush +} ifelse + +% Define the generic algorithm for computing resource file names. +/.rfnstring 8192 string def +/.genericrfn % <key> <scratch> <prefix> .genericrfn <filename> + { 3 -1 roll //.rfnstring cvs concatstrings exch copy + } bind def + +% Define the Generic category. + +/Generic mark + + % Standard entries + +% We're still running in Level 1 mode, so dictionaries won't expand. +% Leave room for the /Category entry. +/Category //null + +% Implement the body of Generic resourceforall for local, global, and +% external cases. 'args' is [template proc scratch resdict]. +/.enumerateresource { % <key> [- <proc> <scratch>] .enumerateresource - + 1 index type dup /stringtype eq exch /nametype eq or { + exch 1 index 2 get cvs exch + } if + % Use .setstackprotect to prevent the stacks from being restored if + % an error occurs during execution of proc. + 1 get //false .setstackprotect exec //true .setstackprotect +} bind def +/.localresourceforall { % <key> <value> <args> .localr'forall - + exch pop + 2 copy 0 get .stringmatch { .enumerateresource } { pop pop } ifelse +} bind def +/.globalresourceforall { % <key> <value> <args> .globalr'forall - + exch pop + 2 copy 0 get .stringmatch { + dup 3 get begin .LocalInstances end 2 index known not { + .enumerateresource + } { + pop pop + } ifelse + } { + pop pop + } ifelse +} bind def +/.externalresourceforall { % <filename> <len> <args> .externalr'forall - + 3 1 roll 1 index length 1 index sub getinterval exch + dup 3 get begin .Instances .LocalInstances end + % Stack: key args insts localinsts + 3 index known { + pop pop pop + } { + 2 index known { pop pop } { .enumerateresource } ifelse + } ifelse +} bind def + +/DefineResource { + .CheckResource + { dup [ exch 0 -1 ] + % Stack: key value instance + currentglobal + { //false setglobal 2 index UndefineResource % remove local def if any + //true setglobal + .Instances dup //.emptydict eq { + pop 3 dict + % As noted above, Category dictionaries are read-only, + % so we have to use .forcedef here. + /.Instances 1 index .forcedef % Category dict is read-only + } if + } + { .LocalInstances dup //.emptydict eq + { pop 3 dict localinstancedict Category 2 index put + } + if + } + ifelse + % Stack: key value instance instancedict + 3 index 2 index .growput + % Now make the resource value read-only. + 0 2 copy get { readonly } .internalstopped pop + dup 4 1 roll put exch pop exch pop + } + { /defineresource cvx /typecheck signaloperror + } + ifelse +} .bind executeonly % executeonly to prevent access to .forcedef +/UndefineResource + { { dup 2 index .knownget + { dup 1 get 1 ge + { dup 0 //null put 1 2 put pop pop } + { pop exch .undef } + ifelse + } + { pop pop + } + ifelse + } + currentglobal + { 2 copy .Instances exch exec + } + if .LocalInstances exch exec + } bind +% Because of some badly designed code in Adobe's CID font downloader that +% makes findresource and resourcestatus deliberately inconsistent with each +% other, the default FindResource must not call ResourceStatus if there is +% an instance of the desired name already defined in VM. +/FindResource { + dup //null eq { + % CET 13-06 wants /typecheck for "null findencoding" but + % .knownget doesn't fail on null + /findresource cvx /typecheck signaloperror + } if + dup .getvminstance { + exch pop 0 get + } { + dup ResourceStatus { + pop 1 gt { + .DoLoadResource .getvminstance not { + /findresource cvx .undefinedresource + } if 0 get + } { + .GetInstance pop 0 get + } ifelse + } { + /findresource cvx .undefinedresource + } ifelse + } ifelse +} bind +% Because of some badly designed code in Adobe's CID font downloader, the +% definition of ResourceStatus for Generic and Font must be the same (!). +% We patch around this by using an intermediate .ResourceFileStatus procedure. +/ResourceStatus { + dup .GetInstance { + exch pop dup 1 get exch 2 get //true + } { + .ResourceFileStatus + } ifelse +} bind +/.ResourceFileStatus { + .ResourceFile { closefile 2 -1 //true } { pop //false } ifelse +} bind +/ResourceForAll { + % Construct a new procedure to hold the arguments. + % All objects constructed here must be in local VM to avoid + % a possible invalidaccess. + currentdict 4 .localvmpackedarray % [template proc scratch resdict] + % We must pop the resource dictionary off the dict stack + % when doing the actual iteration, and restore it afterwards. + .currentglobal not { + .LocalInstances length 0 ne { + % We must do local instances, and do them first. + //.localresourceforall {exec} 0 get 3 .localvmpackedarray cvx + .LocalInstances exch {forall} 0 get 1 index 0 get + currentdict end 3 .execn begin + } if + } if + % Do global instances next. + //.globalresourceforall {exec} 0 get 3 .localvmpackedarray cvx + .Instances exch cvx {forall} 0 get 1 index 0 get + currentdict end 3 .execn begin + mark % args [ + Category .namestring .file_name_separator concatstrings + 2 index 0 get % args [ (c/) (t) + 1 index length 3 1 roll % args [ l (c/) (t) + concatstrings % args [ l (c/t) + [ + //true /LIBPATH .systemvar 3 index + .generate_dir_list_templates_with_length % args (t) [ l [(pt) Lp ...] + % also add on the Resources as specified by the GenericResourceDir + //true [ currentsystemparams /GenericResourceDir get] + counttomark 1 add index .generate_dir_list_templates_with_length + ] exch pop + dup length 1 sub 0 exch 2 exch { % args [ l [] i + 2 copy get % args [ l [] i (pt) + exch 2 index exch 1 add get % args [ l [] (pt) Lp + 3 index add + exch % args [ l [] Lp (pt) + + { % args [ l [] Lp (pf) + dup length % args [ l [] Lp (pf) Lpf + 2 index sub % args [ l [] Lp (pf) Lf + 2 index exch % args [ l [] Lp (pf) Lp Lf + getinterval cvn dup % args [ l [] Lp /n /n + 5 2 roll % args [ /n /n l [] Lp + } //.rfnstring filenameforall + pop % args [ /n1 /n1 ... /nN /nN l [] + } for % args [ /n1 /n1 ... /nN /nN l [] + pop pop + .dicttomark % An easy way to exclude duplicates. % args <</n/n>> + % { + { pop } 0 get + 2 index 2 get { cvs 0 } aload pop 5 index + //.externalresourceforall {exec} 0 get + % } + 7 .localvmpackedarray cvx + 3 2 roll pop % args + { forall } 0 get + currentdict end 2 .execn begin +} bind + +/ResourceFileName { % /in (scr) --> (p/c/n) + exch //.rfnstring cvs % (scr) (n) + /GenericResourcePathSep getsystemparam exch % (scr) (/) (n) + Category .namestring % (scr) (/) (n) (c) + 3 1 roll % (scr) (c) (/) (n) + concatstrings concatstrings % (scr) (c/n) + /GenericResourceDir getsystemparam 1 index % (scr) (c/n) (p/) (c/n) + concatstrings % (scr) (c/n) (p/c/n) + dup status { + pop pop pop pop exch pop % (scr) (p/c/n) + } { + exch + .libfile + {//true} + { + pop dup .libfile + {//true} + {//false} + ifelse + } ifelse + + { + dup .filename pop + exch closefile + exch pop + } + {pop} + ifelse + } ifelse + exch copy % (p/c/n) +} bind + + % Additional entries + +% Unfortunately, we can't create the real .Instances dictionary now, +% because if someone copies the Generic category (which pp. 95-96 of the +% 2nd Edition Red Book says is legitimate), they'll wind up sharing +% the .Instances. Instead, we have to create .Instances on demand, +% just like the entry in localinstancedict. +% We also have to prevent anyone from creating instances of Generic itself. +/.Instances //.emptydict + +/.LocalInstances + { localinstancedict Category .knownget not { //.emptydict } if + } bind +/.GetInstance + { currentglobal + { .Instances exch .knownget } + { .LocalInstances 1 index .knownget + { exch pop //true } + { .Instances exch .knownget } + ifelse + } + ifelse + } bind +/.CheckResource + { //true + } bind +/.vmused { + % - .vmused <usedvalue> + % usedvalue = vmstatus in global + vmstatus in local. + 0 2 { + .currentglobal not .setglobal + vmstatus pop exch pop add + } repeat +} bind def +/.DoLoadResource { + % .LoadResource may push entries on the operand stack. + % It is an undocumented feature of Adobe implementations, + % which we must match for the sake of some badly written + % font downloading code, that such entries are popped + % automatically. + count 1 index cvlit .vmused + % Stack: key count litkey memused + {.LoadResource} 4 1 roll 4 .execn + % Stack: ... count key memused + .vmused exch sub + 1 index .getvminstance not { + pop dup .undefinedresource % didn't load + } if + dup 1 1 put + 2 3 -1 roll put + % Stack: ... count key + exch count 1 sub exch sub {exch pop} repeat +} bind +/.LoadResource + { dup .ResourceFile + { exch pop currentglobal + { .runresource } + { //true setglobal { .runresource } stopped //false setglobal { stop } if } + ifelse + } + { dup .undefinedresource + } + ifelse + } bind +/.ResourceFile + { + Category //.rfnstring cvs length % key l + dup //.rfnstring dup length 2 index sub % key l l (buf) L-l + 3 2 roll exch getinterval % key l () + .file_name_directory_separator exch copy length add % key l1 + dup //.rfnstring dup length 2 index sub % key l1 l1 (buf) L-l + 3 2 roll exch getinterval % key l1 () + 2 index exch cvs length add % key l2 + //.rfnstring exch 0 exch getinterval % key (relative_path) + .libfile { + exch pop //true + } { + pop + currentdict /ResourceFileName known { + mark 1 index //.rfnstring { ResourceFileName } .internalstopped { + cleartomark //false + } { + (r) { file } .internalstopped { + cleartomark //false + } { + exch pop exch pop //true + } ifelse + } ifelse + } { + pop //false + } ifelse + } ifelse + } bind + +.dicttomark +/Category defineresource pop + +% Fill in the rest of the Category category. +/Category /Category findresource dup +/Generic /Category findresource begin { + /FindResource /ResourceForAll /ResourceStatus /.ResourceFileStatus + /UndefineResource /ResourceFileName + /.ResourceFile /.LoadResource /.DoLoadResource +} { dup load put dup } forall +pop readonly pop end + +(END GENERIC) VMDEBUG + +% Define the fixed categories. + +mark + % Non-Type categories with existing entries. + /ColorSpaceFamily + { } % These must be deferred, because optional features may add some. + /Emulator + mark EMULATORS { <00> search { exch pop cvn exch }{ cvn exit } ifelse } .bind loop .packtomark + /Filter + { } % These must be deferred, because optional features may add some. + /IODevice + % Loop until the .getiodevice gets a rangecheck. + errordict /rangecheck 2 copy get + errordict /rangecheck { pop stop } put % pop the command + mark 0 { { + dup .getiodevice dup //null eq { pop } { exch } ifelse 1 add + } loop} .internalstopped + pop pop pop .packtomark + 4 1 roll put + .clearerror + % Type categories listed in the Red Book. + /ColorRenderingType + { } % These must be deferred, because optional features may add some. + /FMapType + { } % These must be deferred, because optional features may add some. + /FontType + { } % These must be deferred, because optional features may add some. + /FormType + { } % These must be deferred, because optional features may add some. + /HalftoneType + { } % These must be deferred, because optional features may add some. + /ImageType + { } % Deferred, optional features may add some. + /PatternType + { } % Deferred, optional features may add some. + % Type categories added since the Red Book. + /setsmoothness where { + pop /ShadingType { } % Deferred, optional features may add some. + } if +counttomark 2 idiv + { mark + + % Standard entries + + % We'd like to prohibit defineresource, + % but because optional features may add entries, we can't. + % We can at least require that the key and value match. + /DefineResource + { currentglobal not + { /defineresource cvx /invalidaccess signaloperror } + { 2 copy ne + { /defineresource cvx /rangecheck signaloperror } + { dup .Instances 4 -2 roll .growput } + ifelse + } + ifelse + } bind + /UndefineResource + { /undefineresource cvx /invalidaccess signaloperror } bind + /FindResource + { .Instances 1 index .knownget + { exch pop } + { /findresource cvx .undefinedresource } + ifelse + } bind + /ResourceStatus + { .Instances exch known { 0 0 //true } { //false } ifelse } bind + /ResourceForAll + /Generic .findcategory /ResourceForAll load end + + % Additional entries + + counttomark 2 add -1 roll + dup length dict dup begin exch { dup def } forall end + % We'd like to make the .Instances readonly here, + % but because optional features may add entries, we can't. + /.Instances exch + /.LocalInstances % used by ResourceForAll + 0 dict def + + .dicttomark /Category defineresource pop + } repeat pop + +(END FIXED) VMDEBUG + +% Define the other built-in categories. + +/.definecategory % <name> -mark- <key1> ... <valuen> .definecategory - + { counttomark 2 idiv 2 add % .Instances, Category + /Generic /Category findresource dup maxlength 3 -1 roll add + dict .copydict begin + counttomark 2 idiv { def } repeat pop % pop the mark + currentdict end /Category defineresource pop + } bind def + +/ColorRendering mark /InstanceType /dicttype .definecategory +% ColorSpace is defined below +% Encoding is defined below +% Font is defined below +/Form mark /InstanceType /dicttype .definecategory +/Halftone mark /InstanceType /dicttype .definecategory +/Pattern mark /InstanceType /dicttype .definecategory +/ProcSet mark /InstanceType /dicttype .definecategory +% Added since the Red Book: +/ControlLanguage mark /InstanceType /dicttype .definecategory +/HWOptions mark /InstanceType /dicttype .definecategory +/Localization mark /InstanceType /dicttype .definecategory +/PDL mark /InstanceType /dicttype .definecategory +% CIDFont, CIDMap, and CMap are defined in gs_cidfn.ps +% FontSet is defined in gs_cff.ps +% IdiomSet is defined in gs_ll3.ps +% InkParams and TrapParams are defined in gs_trap.ps + +(END MISC) VMDEBUG + +% Define the OutputDevice category. +/OutputDevice mark +/InstanceType /dicttype +/.Instances mark +%% devicedict is not created yet so here we employ a technique similar to +%% that used to create it, in order to get the device names. We run a loop +%% executing .getdevice with incremental numbers until we get an error. +%% The devicedict creation only stops on a rangecheck, we stop on any error. +%% We need to use .internalstopped, not stopped or we get an invalidacces +%% later in this file. Instances of /OutputDevice are dictionaries, and the +%% only required key is a /PageSize. The array of 4 numbers are minimum to +%% maximum and are matches for the Adobe Acrobat Distiller values. +0 +{ + {dup .getdevice .devicename cvn 1 dict dup /PageSize [1 1 14400 14400] put [exch readonly 0 -1] 3 -1 roll 1 add} loop +} .internalstopped pop +%% Remove the count, and the duplicate, from the stack +pop pop +.dicttomark +.definecategory + +% Define the ColorSpace category. + +/.defaultcsnames mark + /DefaultGray 0 + /DefaultRGB 1 + /DefaultCMYK 2 +.dicttomark readonly def + +% The "hooks" are no-ops here, redefined in LL3. +/.definedefaultcs { % <index> <value> .definedefaultcs - + pop pop +} bind def +/.undefinedefaultcs { % <index> .undefinedefaultcs - + pop +} bind def + +/ColorSpace mark + +/InstanceType /arraytype + +% We keep track of whether there are any local definitions for any of +% the Default keys. This information must get saved and restored in +% parallel with the local instance dictionary, so it must be stored in +% local VM. +userdict /.localcsdefaults //false put + +/DefineResource { + 2 copy /Generic /Category findresource /DefineResource get exec + exch pop + exch //.defaultcsnames exch .knownget { + 1 index .definedefaultcs + currentglobal not { .userdict /.localcsdefaults //true put } if + } if +} bind + +/UndefineResource { + dup /Generic /Category findresource /UndefineResource get exec + //.defaultcsnames 1 index .knownget { + % Stack: resname index + currentglobal { + .undefinedefaultcs pop + } { + % We removed the local definition, but there might be a global one. + exch .GetInstance { + 0 get .definedefaultcs + } { + .undefinedefaultcs + } ifelse + % Recompute .localcsdefaults by scanning. This is rarely needed. + .userdict /.localcsdefaults //false //.defaultcsnames { + pop .LocalInstances exch known { pop //true exit } if + } forall put + } ifelse + } { + pop + } ifelse +} bind + +.definecategory % ColorSpace + +% Define the Encoding category. + +/Encoding mark + +/InstanceType /arraytype + +% Handle already-registered encodings, including lazily loaded encodings +% that aren't loaded yet. + +/.Instances mark + EncodingDirectory + { dup length 256 eq { [ exch readonly 0 -1 ] } { pop [//null 2 -1] } ifelse + } forall +.dicttomark + +/.ResourceFileDict mark + EncodingDirectory + { dup length 256 eq { pop pop } { 0 get } ifelse + } forall +.dicttomark + +/ResourceFileName + { .ResourceFileDict 2 index .knownget + { exch copy exch pop } + { /Generic /Category findresource /ResourceFileName get exec } + ifelse + } bind + +.definecategory % Encoding + +% Make placeholders in level2dict for the redefined Encoding operators, +% so that they will be swapped properly when we switch language levels. + +/.findencoding /.findencoding load def +/findencoding /findencoding load def +/.defineencoding /.defineencoding load def + +(END ENCODING) VMDEBUG + +% Define the Font category. + +/.fontstatusaux { % <fontname> .fontstatusaux <fontname> <found> + { % Create a loop context just so we can exit it early. + % Check Fontmap. + Fontmap 1 index .knownget + { //true } + { .nativeFontmap 1 index .knownget } ifelse + + { + { + dup type /nametype eq { + .fontstatus { pop //null exit } if + } { + dup type /stringtype eq { + findlibfile { closefile pop //null exit } if pop + } { + % Procedure, assume success. + pop //null exit + } ifelse + } ifelse + } forall dup //null eq { pop //true exit } if + } if + + + dup / eq { //false exit } if % / throws an error from findlibfile + % Convert names to strings; give up on other types. + dup type /nametype eq { .namestring } if + dup type /stringtype ne { //false exit } if + % Check the resource directory. + dup .fonttempstring /FontResourceDir getsystemparam .genericrfn + status { + pop pop pop pop //true exit + } if + % Check for a file on the search path with the same name + % as the font. + findlibfile { closefile //true exit } if + % Scan a FONTPATH directory and try again. + .scannextfontdir not { //false exit } if + } loop +} bind def + +/.fontstatus { % <fontname> .fontstatus <fontname> <found> + //.fontstatusaux exec + { //true } + { + .buildnativefontmap + { //.fontstatusaux exec } + { //false } ifelse + } ifelse +} bind def +currentdict /.fontstatusaux .undef + +/Font mark + +/InstanceType /dicttype + +/DefineResource + { 2 copy //definefont exch pop + /Generic /Category findresource /DefineResource get exec + } bind +/UndefineResource + { dup //undefinefont + /Generic /Category findresource /UndefineResource get exec + } bind +/FindResource { + dup .getvminstance { + exch pop 0 get + } { + dup ResourceStatus { + pop 1 gt { .loadfontresource } { .GetInstance pop 0 get } ifelse + } { + .loadfontresource + } ifelse + } ifelse +} bind +/ResourceForAll { + { .scannextfontdir not { exit } if } loop + /Generic /Category findresource /ResourceForAll get exec +} bind +/.ResourceFileStatus { + .fontstatus { pop 2 -1 //true } { pop //false } ifelse +} bind + +/.loadfontresource { + dup .vmused exch + % Hack: rebind .currentresourcefile so that all calls of + % definefont will know these are built-in fonts. + currentfile {pop //findfont exec} .execasresource % (findfont is a procedure) + exch .vmused exch sub + % stack: name font vmused + % findfont has the prerogative of not calling definefont + % in certain obscure cases of font substitution. + 2 index .getvminstance { + dup 1 1 put + 2 3 -1 roll put + } { + pop + } ifelse exch pop +} bind + +/.Instances FontDirectory length 2 mul dict + +.definecategory % Font + +% Redefine font "operators". +/.definefontmap + { /Font /Category findresource /.Instances get + dup 3 index known + { pop + } + { 2 index + % Make sure we create the array in global VM. + .currentglobal //true .setglobal + [//null 2 -1] exch .setglobal + .growput + } + ifelse + //.definefontmap exec + } bind def + +% Make sure the old definitions are still in systemdict so that +% they will get bound properly. +systemdict begin + /.origdefinefont /definefont load def + /.origundefinefont /undefinefont load def + /.origfindfont /findfont load def +end +/definefont { + { /Font defineresource } stopped { + /definefont cvx $error /errorname get signalerror + } if +} bind odef +/undefinefont { + /Font undefineresource +} bind odef +% The Red Book requires that findfont be a procedure, not an operator, +% but it still needs to restore the stacks reliably if it fails. +/.findfontop { + { /Font findresource } stopped { + pop /findfont $error /errorname get signalerror + } if +} bind odef +/findfont { + .findfontop +} bind def % Must be a procedure, not an operator + +% Remove initialization utilities. +currentdict /.definecategory .undef +currentdict /.emptydict .undef + +end % level2dict + +% Convert deferred resources after we finally switch to Level 2. + +/.fixresources { + % Encoding resources + EncodingDirectory + { dup length 256 eq + { /Encoding defineresource pop } + { pop pop } + ifelse + } forall + /.findencoding { + { /Encoding findresource } stopped { + pop /findencoding $error /errorname get signalerror + } if + } bind def + /findencoding /.findencoding load def % must be a procedure + /.defineencoding { /Encoding defineresource pop } bind def + % ColorRendering resources and ProcSet + systemdict /ColorRendering .knownget { + /ColorRendering exch /ProcSet defineresource pop + systemdict /ColorRendering undef + /DefaultColorRendering currentcolorrendering /ColorRendering defineresource pop + } if + % ColorSpace resources + systemdict /CIEsRGB .knownget { + /sRGB exch /ColorSpace defineresource pop + systemdict /CIEsRGB undef + } if + systemdict /CIEsRGBICC .knownget { + /sRGBICC exch /ColorSpace defineresource pop + systemdict /CIEsRGBICC undef + } if + systemdict /CIEsGRAYICC .knownget { + /sGrayICC exch /ColorSpace defineresource pop + systemdict /CIEsGRAYICC undef + } if + % ColorSpaceFamily resources + colorspacedict { pop dup /ColorSpaceFamily defineresource pop } forall + % Filter resources + filterdict { pop dup /Filter defineresource pop } forall + % FontType and FMapType resources + buildfontdict { pop dup /FontType defineresource pop } forall + mark + buildfontdict 0 known { 2 3 4 5 6 7 8 } if + buildfontdict 9 known { 9 } if + counttomark { dup /FMapType defineresource pop } repeat pop + % FormType resources + .formtypes { pop dup /FormType defineresource pop } forall + % HalftoneType resources + .halftonetypes { pop dup /HalftoneType defineresource pop } forall + % ColorRenderingType resources + .colorrenderingtypes {pop dup /ColorRenderingType defineresource pop} forall + % ImageType resources + .imagetypes { pop dup /ImageType defineresource pop } forall + % PatternType resources + .patterntypes { pop dup /PatternType defineresource pop } forall + % Make the fixed resource categories immutable. + /.shadingtypes where { + pop .shadingtypes { pop dup /ShadingType defineresource pop } forall + } if + [ /ColorSpaceFamily /Emulator /Filter /IODevice /ColorRenderingType + /FMapType /FontType /FormType /HalftoneType /ImageType /PatternType + /.shadingtypes where { pop /ShadingType } if + ] { + /Category findresource + dup /.Instances get readonly pop + .LocalInstances readonly pop + readonly pop + } forall + % clean up + systemdict /.fixresources undef +} bind def + +%% Replace 1 (gs_resmp.ps) +(gs_resmp.ps) dup runlibfile VMDEBUG diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_resmp.ps b/Master/tlpkg/tlgs/Resource/Init/gs_resmp.ps new file mode 100644 index 00000000000..96bc67da16c --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_resmp.ps @@ -0,0 +1,529 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% A procset to redefine a resource category with a resource map. + +% Public entries : + +% Redefine - a procedure for redefining a resource category with a map. +% Methods for interpreting the resource map to be provided by client +% in the argument dictionary. +% +% Note that the procedure Redefine is idempotential : +% consequtive calls to it will not replace the category methods, +% but will merge resource maps. If an interleaving redefinition +% needs to cancel the idempotentity, it must remove the entry +% /.IsRedefinedWithMap from the category dictionary. + +% MakeResourceEnumerator - this procedure is useful for +% redefining any category. It provides a proper order of instances +% and proper stacks during resourceforall. + +% BindWithCurrentdict - a procedure for generating temporary procedures +% from templates, binding them with a local dictionary. + +% execstack_lookup - a procedure for communicating through the execution stack. +% It allows for a callee to get an information from an indirect caller. + +% The procedures are designed for exeution witout putting +% the procset instance onto the dictionary stack. + +languagelevel 2 .setlanguagelevel +currentglobal //true setglobal + +/MappedCategoryRedefiner 10 dict begin % The procset. + +currentpacking //false setpacking + +/InstanceEnumeratorPattern % - InstanceEnumeratorPattern ... +{ + % This is a pattern for enumeration procedure to be built dynamically, + % applying BindWithCurrentdict with a temporary dictionary. + % The following names will be replaced with specific objects + % during BindWithCurrentdict : + % en_local_dict - a dictionary for storing the local integer variable 'status'. + % scr - the scratch string argument of resourceforall; + % proc - the procedure argument of resourceforall; + % InstancesStatus - a dictionary that maps resource instance names to their status value; + % Category - the category to be enumerated. + + % When this procedure is called from ResourceForAll, the category is the current dictionary. + % We remove it from the dictionary stack before performing the enumeration + % to provide the <proc> to write to the underlying dictionary, + % and put it back after the enumeration is completed. + end + { + 0 1 2 { + en_local_dict exch /status exch put + InstancesStatus { + en_local_dict /status get eq { + scr cvs % ... (Font) + proc exec % + } { + pop + } ifelse % ... + } forall + } for % ... + } stopped + Category begin + { stop } if +} bind def + +% An auxiliary proc for BindWithCurrentdict : +/.BindAux % <proc> BindAux <proc> +{ 0 exec +} bind def + +setpacking + +/BindWithCurrentdict % <proc> BindWithCurrentdict <proc> +{ + % Make a copy of the given procedure, binding in the values of all names + % defined in currentdict. + % Caution1 : this code cannot handle procedures that were already + % bound recursively. + % Caution2 : this code don't bind packedarrays. This was done + % intentionally for a termination of the procedure tree. + + dup length array copy + dup length 1 sub -1 0 { + 2 copy get % {precopy} i {elem} + dup dup type /arraytype eq exch xcheck and { + % {precopy} i {elem} + //.BindAux exec % {precopy} i {elem_copy} + 2 index 3 1 roll put % {precopy} + } { + dup dup type /nametype eq exch xcheck and { + % {precopy} i {elem} + currentdict exch .knownget { + 2 index 3 1 roll put % {precopy} + } { + pop + } ifelse + } { + pop pop + } ifelse + } ifelse % {precopy} + } for % {copy} + cvx +} bind def + +//.BindAux 0 //BindWithCurrentdict put % bind the recursive call in 'Bind'. + +/MakeResourceEnumerator % <proc> <scr> <InstancesStatus> MakeResourceEnumerator <Enumerator> +{ + % Build the enumeration procedure : + + % Since the resourceforall procedure may leave values on the operand stack, + % we cannot simply store the enumerator's local data on the stack. + % We also cannot use a static dictionary to store local variables, + % because of possible recursion in the resourceforall procedure. + % To work around this, we create a copy of the enumeration procedure and + % bind it dynamically with a temporary dictionary, which contains + % local variables for the currently executing instance of resourceforall. + + % Always place the enumerator in local VM, + % because its elements may be in local VM. + + currentglobal 4 1 roll + //false setglobal + currentdict % Category + 6 dict begin % the temporary dictionary + /Category exch def + /InstancesStatus exch def + /scr exch def + /proc exch def + /en_local_dict currentdict def + //InstanceEnumeratorPattern //BindWithCurrentdict exec % Enumerator + /status 0 def % variable for the current status to enumerate - do not bind with it ! + end + exch setglobal +} bind def + +/execstack_lookup % <object> execstack_lookup <object1> + % <object> execstack_lookup null +{ % Checks whether execution stack contains a procedure starting with <object>, + % and retrives the 2nd element of the procedure, + % or null if the procedure was not found. + % + % Since 'execstack' actually renders subarrays of procedures, + % the pattern for recognition must be like this : + % + % { <object> <object1> + % CallSomething + % } loop + % + % The solution with 'loop' depends on how GS implements cycles, + % so it must not appear in documents, which are required to be interpreter independent. + % Any other type of cycles are also acceptable. + % If no repitition is really needed, just insert 'exit' into its body. + % If <object> <object1> are not needed for the caller, insert "pop pop" after them. + % If <object1> is really unuseful, the pattern may be simplified : + % + % { <object> pop + % CallSomething + % exit + % } loop + % + % It will retrieve 'pop' or 'null'. + % + % Note that 2 topmost execstack elements are the execstack_lookup procedure and its caller. + % We don't check them. + + currentglobal //false setglobal % <object> bGlobal + countexecstack array execstack % <object> bGlobal [execstack] + dup //null exch % <object> bGlobal [execstack] null [execstack] + length 3 sub -1 0 { % <object> bGlobal [execstack] null i + 2 index exch get % <object> bGlobal [execstack] null proc + dup type dup /packedarraytype eq exch /arraytype eq or { + dup rcheck { + dup length 1 gt { % <object> bGlobal [execstack] null proc + dup 0 get % <object> bGlobal [execstack] null proc elem0 + 5 index eq { % <object> bGlobal [execstack] null proc + 1 get % <object> bGlobal [execstack] null object1 + exch pop exit % <object> bGlobal [execstack] object1 + } { + pop + } ifelse + } { + pop % <object> bGlobal [execstack] false + } ifelse + } { + pop % <object> bGlobal [execstack] false + } ifelse + } { + pop % <object> bGlobal [execstack] false + } ifelse + } for % <object> bGlobal [execstack] bResult + exch pop exch setglobal exch pop % bResult +} bind def + +currentpacking //false setpacking +/MethodsToRedefine 5 dict begin + + % Procedures in this dictionary really are patterns for new category methods. + % The following names will be replaced with specific objects during BindWithCurrentdict : + % .map - the map dictionary; + % DefineResource, ResourceStatus, ResourceFileName, FindResource, ResourceForAll + % - procedures from the original resource category. + + /FindResource % <Name> FindResource <dict> + { RESMPDEBUG { (resmp FindResource beg ) print dup = } if + dup ResourceStatus exec { + pop 2 lt + } { + //false + } ifelse % bInVirtualMemory + { FindResource exec + } { + dup dup .map exch .knownget { % /Name /Name <<record>> + dup dup /RecordVirtualMethods get /IsActive get exec { + 1 index .getvminstance { % /Name /Name <<record>> holder + 1 get 1 eq + } { + //true + } ifelse % /Name /Name <<record>> bStatusIs1 + 4 1 roll % bStatusIs1 /Name /Name <<record>> + dup /RecordVirtualMethods get /MakeInstance get exec + % bStatusIs1 /Name /Name Instance size + 5 1 roll % size bStatusIs1 /Name /Name Instance + DefineResource exec % size bStatusIs1 /Name Instance + % Make ResourceStatus to return correct values for this instance : + % Hack: we replace status values in the instance holder : + exch .getvminstance pop % size bStatusIs1 Instance holder + dup 5 -1 roll 2 exch put % bStatusIs1 Instance holder + 3 2 roll { % Instance holder + 1 1 put % Instance + } { + pop + } ifelse % Instance + } { % /Name /Name <<record>> + pop pop FindResource exec + } ifelse + } { % /Name /Name + pop FindResource exec + } ifelse + } ifelse + RESMPDEBUG { (resmp FindResource end) = } if + } bind def + + /ResourceStatus % <Name> ResourceStatus <status> <size> true + % <Name> ResourceStatus false + { RESMPDEBUG { (resmp ResourceStatus beg ) print dup //== exec } if + dup ResourceStatus exec { % /Name status size + 1 index 2 lt { + % In VM - return with it. + 3 2 roll pop //true + } { + % Not in VM. + exch pop exch % size /Name + dup .map exch .knownget { % size /Name <<record>> + dup dup /RecordVirtualMethods get /IsActive get exec { + 3 2 roll pop % /Name <<record>> + dup /RecordVirtualMethods get /GetSize get exec 2 exch //true + } { % size /Name <<record>> + pop pop 2 exch //true + } ifelse + } { % size /Name + pop 2 exch //true + } ifelse + } ifelse + } { % /Name + dup .map exch .knownget { % /Name <<record>> + dup dup /RecordVirtualMethods get /IsActive get exec { + dup /RecordVirtualMethods get /GetSize get exec 2 exch //true + } { % /Name <<record>> + pop pop //false + } ifelse + } { % /Name + pop //false + } ifelse + } ifelse + RESMPDEBUG { (resmp ResourceStatus end) = } if + } bind def + + /ResourceFileName % <Name> <scratch> ResourceFileName <string> + { RESMPDEBUG { (resmp ResourceFileName beg ) print 1 index = } if + exch % (scratch) /Name + .map 1 index .knownget { % (scratch) /Name <<record>> + RESMPDEBUG { (resmp ResourceFileName : have a map record.) = } if + dup dup /RecordVirtualMethods get /IsActive get exec { + RESMPDEBUG { (resmp ResourceFileName : record is active.) = } if + dup /RecordVirtualMethods get /GetFilePath get exec % (string) + RESMPDEBUG { (resmp ResourceFileName : retrieving ) print dup = } if + } { % (scratch) /Name <<record>> + RESMPDEBUG { (resmp ResourceFileName : record is NOT active.) = } if + pop exch ResourceFileName exec + RESMPDEBUG { (resmp ResourceFileName : retrieving ) print dup = } if + } ifelse + } { + RESMPDEBUG { (resmp ResourceFileName : have NO map record.) = } if + exch ResourceFileName exec + RESMPDEBUG { (resmp ResourceFileName : retrieving ) print dup = } if + } ifelse + RESMPDEBUG { (resmp ResourceFileName end) = } if + } bind def + + /ResourceForAll % <template> <proc> <scratch> ResourceForAll - + { RESMPDEBUG { (resmp ResourceForAll beg ) print CategoryName =string cvs print ( ) print 2 index = } if + % Create InstancesStatus dictionary : + 20 dict % IS - Instances Status + 4 1 roll % <<IS>> (templ) {proc} (sctarch) + % Check if we are under another ResourceForAll : + /.DisableResourceOrdering //execstack_lookup exec //null eq 4 1 roll + % <<IS>> bOrder (templ) {proc} (sctarch) + + % Put underlying resources to the InstancesStatus dictionary : + currentdict % the category + begin % ResourceForAll removes it locally. + 2 index + { cvn % <<IS>> bOrder (templ) {proc} (sctarch) /Name + 4 index { + dup ResourceStatus exec {pop 6 index 3 1 roll put} {pop} ifelse + } { + 5 index exch 2 put % Don't need the ordering, put '2' as a scratch. + } ifelse + } + 2 index ResourceForAll exec % <<IS>> bOrder (templ) {proc} (sctarch) + 4 3 roll pop % <<IS>> (templ) {proc} (sctarch) + end + + % Put .map entries to the InstancesStatus dictionary : + 4 -1 roll begin % (templ) {proc} (sctarch) + .map { % (templ) {proc} (sctarch) /Name record + dup dup /RecordVirtualMethods get /IsActive get exec { + pop % (templ) {proc} (sctarch) /Name + dup currentdict exch known { + pop + } { + dup 2 index cvs % (templ) {proc} (sctarch) /Name (Name) + 4 index .stringmatch { % (templ) {proc} (sctarch) /Name + 2 def % It is not in VM. + } { + pop + } ifelse + } ifelse + } { % (templ) {proc} (sctarch) /Name record + pop pop + } ifelse + } forall % (templ) {proc} (sctarch) + + % prepare stacks for the enumeration : + 3 2 roll pop % {proc} (sctarch) + currentdict end % {proc} (scratch) <<IS>> + + % Make the enumerator and apply it : + //MakeResourceEnumerator exec exec + RESMPDEBUG { (resmp ResourceForAll end)= } if + } bind def + + /GetCIDSystemInfoFromMap % <Name> GetCIDSystemInfoFromMap <Name> + % <Name> GetCIDSystemInfoFromMap <dict> + { RESMPDEBUG { (resmp GetCIDSystemInfoFromMap beg ) print dup = } if + % This is a special function for communicating with GetCIDSystemInfo in gs_cidcm.ps . + dup .map exch .knownget { + RESMPDEBUG { (resmp GetCIDSystemInfoFromMap : have a map record.) = } if + dup /RecordVirtualMethods get /GetCSI get exec + dup //null ne { + RESMPDEBUG { (resmp GetCIDSystemInfoFromMap : retrieving a dict.) = } if + exch + } if + pop + } if + RESMPDEBUG { (resmp GetCIDSystemInfoFromMap end) = } if + } bind def + +currentdict end def +setpacking + +/Redefine % <OptionsDict> Redefine - +{ % Before calling this proc, the OptionsDict must specify options for + % the catregory to be redefined : + % CategoryName - a name of category to redefine; + % MapFileName - a string for the resource map file name; + % VerifyMap - a procedure : + % <raw_map> VerifyMap - + % - checks the map for consistency + % PreprocessRecord - a procedure : + % <map> <Name> <raw_record> PreprocessRecord <map> <Name> <record> true + % <map> <Name> <raw_record> PreprocessRecord <map> <Name> <raw_record> false + % - converts a map record into a dictionary; + % It must add RecordVirtualMethods dictionary to the record : + % MakeInstance - a procedure : + % <Name> <record> MakeInstance <Name> <Instance> <size> + % - converts the record to resource instance; + % GetFilePath - a procedure for ResourceFileName : + % <scratch> <Name> <record> GetFilePath <filepath> + % GetSize - a procedure for ResourceStatus : + % <Name> <record> GetSize <size> + % GetCSI - a procedure for obtaining CIDSystemInfo dictionary from the record : + % <record> GetCSI <CSI> + % <record> GetCSI null + % IsActive - a procedure for skipping records depending on the current device : + % <record> IsActive <bool> + % Also it is allowed to contain additional entries for client's needs. + % The OptionsDict is also used for storing some local variables. + + % If a category is being redefined several times with this function, + % each redefinition must either use an unique map file, + % or the map file should be scanned by the last redefinition + % (and must be defined in the last one with /MapFileName). + % This happens so because we must accumulate all variants of + % methods before scanning the map. We would like to delay + % the scanning until all redefinitions are done, but it requires + % to implement a queue of "refinish" methods and execute it + % at very end of the prelude. + + begin % OptionsDict + CategoryName /Category findresource /OldCategory exch def + OldCategory /.IsRedefinedWithMap known { + % Already redefined with map - don't redefine, but enhance the map. + OldCategory /NewCategory exch def + } { + % Redefine with a new category instance. + OldCategory dup length dict + dup /.PreprocessRecord 4 dict put + copy /NewCategory exch def + } ifelse + + % Provide the 'or' logic for PreprocessRecord, + % to allow different record types to be mixed in a single map file. + % We do this with building a dictionary of PreprocessRecord procedures, + % which come from different calls to Redefine : + NewCategory /.PreprocessRecord get dup length % <<pr>> l + currentdict /PreprocessRecord get .growput + + currentdict /MapFileName known { + MapFileName .libfile { + 1 dict begin + /; {} def + mark exch cvx exec .dicttomark % <<map>> + end + dup VerifyMap % <<map>> + } { + QUIET not { + currentdict /IsMapFileOptional .knownget not { //false } if not { + (Warning: the map file ) print dup =string cvs print ( was not found.) = + } if + } if + pop 0 dict % <<map>> + } ifelse + } { + currentdict /.map .knownget not { + 0 dict % <<map>> + } if + } ifelse + + % Preprocess entries : + dup NewCategory /.PreprocessRecord get % <<map>> <<map>> <<pr>> + 3 1 roll { % <<pr>> <<map>> /Name raw_record + //false 3 1 roll % <<pr>> <<map>> false /Name raw_record + 4 index { % <<pr>> <<map>> false /Name raw_record i {pr} + exch pop % <<pr>> <<map>> false /Name raw_record {pr} + exec { % <<pr>> <<map>> false /Name record + 3 -1 roll pop //true 3 1 roll % <<pr>> <<map>> true /Name record + exit + } if % <<pr>> <<map>> false /Name raw_record + } forall + 3 2 roll { % <<pr>> <<map>> /Name record + 2 index 3 1 roll put % <<pr>> <<map>> + } { + exch % <<pr>> <<map>> raw_record /Name + (Incorrect record ) print =string cvs print ( of the map file ) print MapFileName =string cvs print (.) = + end % Pops OptionsDict from dstack. + pop pop pop % + /Redefine cvx /undefinedresource signalerror + } ifelse + } forall % <<pr>> <<map>> + exch pop % <<map>> + + % Add the map : + OldCategory /.IsRedefinedWithMap known { % <<map>> + % Just add to the old map : + OldCategory /.map get copy pop % + } { % <<map>> + % Store the map to both the category and OptionsDict : + dup NewCategory exch /.map exch put + /.map exch def % + } ifelse + OldCategory /.IsRedefinedWithMap known not { + % Copy old methods to OptionsDict : + [ /DefineResource /ResourceStatus /ResourceFileName + /FindResource /ResourceForAll + ] { + dup OldCategory exch get def + } forall + + % Build new methods : + //MethodsToRedefine { + //BindWithCurrentdict exec NewCategory 3 1 roll put + } forall + CategoryName /CIDFont ne { + NewCategory /GetCIDSystemInfoFromMap undef + % This is some ugly, sorry. + } if + % Redefine the category : + NewCategory /.IsRedefinedWithMap //true put + CategoryName NewCategory /Category defineresource pop + } if + end % OptionsDict +} bind executeonly def + +currentdict /PutPreprocessRecord .undef + +currentdict end +/ProcSet defineresource pop + +setglobal .setlanguagelevel diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_setpd.ps b/Master/tlpkg/tlgs/Resource/Init/gs_setpd.ps new file mode 100644 index 00000000000..6c4a221b315 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_setpd.ps @@ -0,0 +1,1031 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% The current implementation of setpagedevice has the following limitations: +% - It doesn't attempt to "interact with the user" for Policy = 2. + +languagelevel 1 .setlanguagelevel +level2dict begin + +% ---------------- Redefinitions ---------------- % + +% Redefine .beginpage and .endpage so that they call BeginPage and +% EndPage respectively if appropriate. + +% We have to guard against the BeginPage procedure not popping its operand. +% This is really stupid, but the Genoa CET does it. +/.beginpage { % - .beginpage - + .currentshowpagecount { + .currentpagedevice pop + dup //null ne { /BeginPage .knownget } { pop //false } ifelse { + % Stack: ... pagecount proc + count 2 .execn + % Stack: ... ..???.. oldcount + count 1 add exch sub { pop } repeat + } { + pop + } ifelse + } if +} bind odef + +% Guard similarly against EndPage not popping its operand. +/.endpage { % <reason> .endpage <print_bool> + .currentshowpagecount { + 1 index .currentpagedevice pop + dup //null ne { /EndPage .knownget } { pop //false } ifelse { + % Stack: ... reason pagecount reason proc + count 2 .execn + % Stack: ... ..???.. print oldcount + count 2 add exch sub { exch pop } repeat + } { + pop pop 2 ne + } ifelse + } { + 2 ne + } ifelse +} bind odef + +% Define interpreter callouts for handling gstate-saving operators, +% to make sure that they create a page device dictionary for use by +% the corresponding gstate-restoring operator. +% We'd really like to avoid the cost of doing this, but we don't see how. +% The names %gsavepagedevice, %savepagedevice, %gstatepagedevice, +% %copygstatepagedevice, and %currentgstatepagedevice are known to the +% interpreter. + +(%gsavepagedevice) cvn + { currentpagedevice pop gsave + } bind def + +(%savepagedevice) cvn + { currentpagedevice pop save + } bind def + +(%gstatepagedevice) cvn + { currentpagedevice pop gstate + } bind def + +(%copygstatepagedevice) cvn + { currentpagedevice pop copy + } bind def + +(%currentgstatepagedevice) cvn + { currentpagedevice pop currentgstate + } bind def + +% Define interpreter callouts for handling gstate-restoring operators +% when the current page device needs to be changed. +% The names %grestorepagedevice, %grestoreallpagedevice, +% %restorepagedevice, %restore1pagedevice, and %setgstatepagedevice +% are known to the interpreter. + +/.installpagedevice + { % Since setpagedevice doesn't create new device objects, + % we must (carefully) reinstall the old parameters in + % the same device. + .currentpagedevice pop //null currentdevice //null .trysetparams + dup type /booleantype eq + { pop pop } + { % This should never happen! + SETPDDEBUG { (Error in .trysetparams!) = pstack flush } if + cleartomark pop pop pop + /.installpagedevice cvx /rangecheck signalerror + } + ifelse pop pop + % A careful reading of the Red Book reveals that an erasepage + % should occur, but *not* an initgraphics. + erasepage .beginpage + } bind def + +/.uninstallpagedevice + { 2 .endpage { .currentnumcopies //false .outputpage } if + nulldevice + } bind def + +(%grestorepagedevice) cvn + { .uninstallpagedevice grestore .installpagedevice + } bind def + +(%grestoreallpagedevice) cvn + { .uninstallpagedevice grestore .installpagedevice grestoreall + } bind def + +(%restore1pagedevice) cvn + { .uninstallpagedevice grestore .installpagedevice restore + } bind def + +(%restorepagedevice) cvn + { .uninstallpagedevice restore .installpagedevice + } bind def + +(%setgstatepagedevice) cvn + { .uninstallpagedevice setgstate .installpagedevice + } bind def + +% Redefine .currentnumcopies so it consults the NumCopies device parameter. +/.numcopiesdict mark + /NumCopies dup +.dicttomark readonly def + +/.currentnumcopies + { currentdevice //.numcopiesdict .getdeviceparams + dup type /integertype eq + { exch pop exch pop } + { cleartomark #copies } + ifelse + } bind odef + +% Redefine .currentpagedevice and .setpagedevice so they convert between +% null and a fixed empty directionary. +/.nullpagedevice 0 dict readonly def +/.currentpagedevice { + //.currentpagedevice exch dup //null eq { pop //.nullpagedevice } if exch +} bind odef +/.setpagedevice { + dup //.nullpagedevice eq { pop //null } if //.setpagedevice +} bind odef + +% ---------------- Auxiliary definitions ---------------- % + +% Define the required attributes of all page devices, and their default values. +% We don't include attributes such as .MediaSize, which all devices +% are guaranteed to supply on their own. +/.defaultpolicies mark + % M. Sweet, Easy Software Products + % + % Due to the fact that it is not possible to properly implement + % the selection policies from a Ghostscript driver, we have changed + % the default policy to "7" (impose) to avoid numerous problems with + % printing within CUPS... + % + % If NOMEDIAATTRS is false, the set the default depending on whether + % PSFitPage is true. Policy 13 does best fit with page scaling up or down + % so it is only useful if FIXEDMEDIA is also specified, or if the set of + % media in the InputAttributes dictionary is the actual available choices + % and does not include any "range" page sizes. + /PageSize NOMEDIAATTRS { 7 } { //systemdict /PSFitPage known { 13 } { 0 } ifelse } ifelse + /PolicyNotFound 1 + /PolicyReport { + dup /.LockSafetyParams known { + % Only possible error is invalidaccess + /setpagedevice .systemvar /invalidaccess signalerror + } + if + pop + } bind +.dicttomark readonly def +% Note that the values of .requiredattrs are executed, not just fetched. +/.requiredattrs mark + /PageDeviceName //null + /PageOffset [0 0] readonly +% We populate InputAttributes with all of the known page sizes +% followed by a dummy media type that handles pages of any size. +% This will create some duplicates, but that only slightly slows +% down the media selection (loop is in zmedia2.c). +% +% Some PostScript creators assume that slot 0 is the default media +% size and some can't handle a non-standard 4-element array which +% is a 'range' type page size (always put last). +% +% Real Devices that can only handle specific page sizes will override this. + /InputAttributes { + mark + % First put the device's default page size in slot 0 + % This satifies those that have devices built with a4 as the default + 0 mark /PageSize currentdevice /PageSize gsgetdeviceprop .dicttomark + + % Only populate the other entries if we aren't FIXEDMEDIA + FIXEDMEDIA not { + statusdict /.pagetypenames get { + statusdict /.pagetypeprocs get + exch get 0 2 getinterval cvlit + counttomark 1 sub 2 idiv exch mark exch /PageSize exch + % stack: mark --dict-- --dict-- ... key mark /PageSize [x y] + % see note above about pagetype executable array contents. + .dicttomark + } forall + % If NORANGEPAGESIZE is defined, (-dNORANGEPAGESIZE), then don't add + % the 'match any' PageSize entry + systemdict /NORANGEPAGESIZE known not { + % Add one last entry which is the 4 element range array (non-standard) + counttomark 2 idiv + % PageSize with either dimension 0 will be detected in + % match_page_size, so we can allow it here + mark /PageSize [0 dup 16#7ffff dup] .dicttomark + } if + } if % FIXEDMEDIA false + .dicttomark + } + (%MediaSource) 0 + /OutputAttributes { + mark 0 mark .dicttomark readonly .dicttomark + } + (%MediaDestination) 0 + /Install {{.callinstall}} bind + /BeginPage {{.callbeginpage}} bind + /EndPage {{.callendpage}} bind + /Policies .defaultpolicies + /ImagingBBox //null % default value + /UseCIEColor /.getuseciecolor load +.dicttomark readonly def + +% Define currentpagedevice so it creates the dictionary on demand if needed, +% adding all the required entries defined just above. + +% We have to deal specially with entries that the driver may change +% on its own. We also have to deal specially with parameters which the device may +% change on its own but which we *also* want to transmit to the device. Previously +% any parameter which was 'dynamic' would not be sent to the device, making it +% impossible to set a parameter, and later have the device change it. Currently +% only OutputICCProfile fits this category. +% This whole area is broken its completely the wrong way round from the way the spec says it should work. + +% This dictionary contains the keys we never want to set. +/.readonlypdkeys mark + /.MediaSize dup % because it changes when PageSize is set + /PageCount dup + /Colors dup + /BitsPerPixel dup + /ColorValues dup +.dicttomark readonly def + +% Bonkers, but needed by our ridiculous setpagedevice implementation. There are +% some keys (at the moment, RedValues, GreenValues and BlueValues are known) which +% only exist in the page device dictionary under some conditions (ProcessColorModel == DeviceRGB) +% If we change the conditions, so that these keys are no longer present in the params +% returned by the device, sending these keys to the device can trigger a fault. +% This is a problem because of our stored dictionary: +% +% 1) Set up the inital dictioanry by retrieving the params from the device +% 2) Change the conditions (ProcessColorModel == DeviceGray) +% 3) merge any volatile keys from the device. Note that RedValues etc no longer defined. +% 4) Call .installpagdevice, use the stored dicitonary to set the params +% 5) The stored RedValues etc, cause an error. +% +% The stored dictioanry is readonly (we use forceput to wedge new keys into it) so +% we can't 'undef' keys from it. (the dictionary is made readonly by the action of zsetpagedevice +% '.setpagedevice' in PostScrfipt) +% +% So the only solution is to have 'write only' keys. These can be written to the device +% but are not stored in the saved page device dictionary. This means PostScript programs +% can't interrogate and take action on these, but there's no solution to that except to +% rewrite this stuff completely so that it actually works properly. + +/.writeonlykeys mark + /RedValues dup % Set by the device when ProcessColorModel changes + /GreenValues dup % Set by the device when ProcessColorModel changes + /BlueValues dup % Set by the device when ProcessColorModel changes + /GrayValues dup % Set by the device when ProcessColorModel changes +.dicttomark readonly def + +% This dictionary contains the keys we always want to read back from the device. +/.volatilepdkeys mark + /.MediaSize dup % because it changes when PageSize is set + /RedValues dup % Set by the device when ProcessColorModel changes + /GreenValues dup % Set by the device when ProcessColorModel changes + /BlueValues dup % Set by the device when ProcessColorModel changes + /GrayValues dup % Set by the device when ProcessColorModel changes + /PageCount dup + /Colors dup + /BitsPerPixel dup + /ColorValues dup + /OutputICCProfile dup % ColorConversionStrategy can change this +.dicttomark readonly def + +/.makecurrentpagedevice { % - .makecurrentpagedevice <dict> + currentdevice //null .getdeviceparams + % Make the dictionary large enough to add defaulted entries. + counttomark 2 idiv .requiredattrs length add dict + counttomark 2 idiv { dup 4 2 roll put } repeat exch pop + % Add any missing required attributes. + % Make a writable and (if possible) local copy of any default + % dictionaries, to work around a bug in the output of WordPerfect, + % which assumes that these dictionaries are writable and local. + .currentglobal exch dup gcheck .setglobal + .requiredattrs { + 2 index 2 index known { + 1 index /Policies eq { + % Merge policies from the device driver with defaults + 2 index % <<>> /key value <<>> + 3 2 roll get % <<>> value <<policies>> + exch { + 2 index 2 index known { + pop pop + } { + 2 index 3 1 roll put + } ifelse + } forall + pop + } { + pop pop + } ifelse + } { + exec 2 index 3 1 roll put + } ifelse + } forall exch .setglobal + + % Remove any keys we don't want to be stored, before .setpagedevice + % makes the dictionary read only + .writeonlykeys {2 index exch undef pop} forall + dup .setpagedevice +} bind def +/currentpagedevice { + .currentpagedevice { + dup length 0 eq { + pop .makecurrentpagedevice + } { + % If any of the dynamic keys have changed, + % we must update the page device dictionary. + currentdevice //.volatilepdkeys .getdeviceparams .dicttomark { + % Stack: current key value + 2 index 2 index .knownget { 1 index ne } { //true } ifelse + { 2 index wcheck not + { % This is the first entry being updated. + % Copy the dictionary to make it writable. + 3 -1 roll + currentglobal 1 index dup gcheck currentglobal and setglobal + length dict + exch setglobal + .copydict + 3 1 roll + } + if + 2 index 3 1 roll put + } + { pop pop + } + ifelse + } forall + % If the device is the distiller device, update distillerparams that + % may have been changed by setdistillerparams + /IsDistiller /GetDeviceParam .special_op { + exch pop + }{ + //false + }ifelse + { + currentdistillerparams { + % Stack: current key value + 2 index 2 index .knownget { 1 index ne } { //true } ifelse + { 2 index 3 1 roll put } { pop pop } ifelse + } forall + } if + % If the dictionary was global and is now local, copy + % any global subsidiary dictionaries to local VM. This + % too is to work around the Word Perfect bug (see above). + dup gcheck not { + dup { + dup type /dicttype eq { dup gcheck } { //false } ifelse { + % Copy-on-write, see above. + 2 index wcheck not { + 3 -1 roll dup length dict .copydict + 3 1 roll + } if + .copytree 2 index 3 1 roll put + } { + pop pop + } ifelse + } forall + } if + % We would like to do a .setpagedevice so we don't keep + % re-creating the dictionary. Unfortunately, the effect + % of this is that if any dynamic key changes (PageCount + % in particular), we will do the equivalent of a + % setpagedevice at the next restore or grestore. + % Therefore, we make the dictionary read-only, but + % we don't store it away. I.e., NOT: + % dup wcheck { .setpagedevice .currentpagedevice pop } if + readonly + } ifelse + } if +} bind odef + +% Copy a dictionary recursively. +/.copytree { % <dict> .copytree <dict'> + dup length dict exch { + dup type /dicttype eq { .copytree } if 2 index 3 1 roll put + } forall +} bind def + +% The implementation of setpagedevice is quite complex. Currently, +% everything but the media matching algorithm is implemented here. + +% By default, we only present the requested changes to the device, +% but there are some parameters that require special merging action. +% Define those parameters here, with the procedures that do the merging. +% The procedures are called as follows: +% <merged> <key> <new_value> -proc- <merged> <key> <new_value'> +/.mergespecial mark + /InputAttributes + { dup //null eq + { pop //null + } + { 3 copy pop .knownget + { dup //null eq + { pop dup length dict } + { dup length 2 index length add dict .copydict } + ifelse + } + { dup length dict + } + ifelse .copydict readonly + } + ifelse + } bind + /OutputAttributes 1 index + /Policies + { 3 copy pop .knownget + { dup length 2 index length add dict .copydict } + { dup length dict } + ifelse copy readonly + } bind +.dicttomark readonly def + +% M. Sweet, Easy Software Products: +% +% Define NOMEDIAATTRS to turn off the default (but unimplementable) media +% selection policies for setpagedevice. This is used by CUPS to support +% the standard Adobe media attributes. +NOMEDIAATTRS { + % Define only PageSize for input attribute matching. + /.inputattrkeys [ + /PageSize + ] readonly def + % Define no other keys used in media selection. + /.inputselectionkeys [ + /noInputSelectionsKeys + ] readonly def + + % Define no keys used in output attribute matching. + /.outputattrkeys [ + /noOutputAttrKeys + ] readonly def +} { + % Define the keys used in input attribute matching. + /.inputattrkeys [ + /PageSize /MediaColor /MediaWeight /MediaType /InsertSheet /ManualFeed + % The following are documented in Adobe's supplement for v2017. + /LeadingEdge /MediaClass + ] readonly def + % Define other keys used in media selection. + /.inputselectionkeys [ + /MediaPosition /Orientation + ] readonly def + + % Define the keys used in output attribute matching. + /.outputattrkeys [ + /OutputType + ] readonly def +} ifelse + +% Define all the parameters that should always be copied to the merged +% dictionary. +/.copiedkeys [ + /OutputDevice + .mergespecial { pop } forall + .inputattrkeys aload pop + .inputselectionkeys aload pop + .outputattrkeys aload pop +] readonly def + +% Define the parameters that should not be presented to the device. +% The procedures are called as follows: +% <merged> <key> <value> -proc- +% The procedure leaves all its operands on the stack and returns +% true iff the key/value pair should be presented to .putdeviceparams. +/.presentspecial mark + .readonlypdkeys + { pop //false } + forall + % We must ignore an explicit request for .MediaSize, + % because media matching always handles this. + /.MediaSize //false + /Name //false + /OutputDevice //false + /PageDeviceName //false + /PageOffset //false + /PageSize //false % obsolete alias for .MediaSize + /InputAttributes //false + .inputattrkeys + { dup dup /PageSize eq exch /LeadingEdge eq or + { pop } + { { 2 index /InputAttributes .knownget { //null eq } { //true } ifelse } } + ifelse + } + forall + .inputselectionkeys { //false } forall + /OutputAttributes //false + .outputattrkeys + { { 2 index /OutputAttributes .knownget { //null eq } { //true } ifelse } } + forall + /Install //false + /BeginPage //false + /EndPage //false + /Policies //false + % Our extensions: + /HWColorMap + { % HACK: don't transmit the color map, because + % window systems can change the color map on their own + % incrementally. Someday we'll have a better + % solution for this.... + //false + } + /ViewerPreProcess //false + /ImagingBBox //false % This prevents the ImagingBBox value in the setpagedevice + % from affecting the device's ImagingBBox parameter, but + % does retain a 'shadow' copy at the PostScript level. + % This is done for Adobe compatibility since Adobe does + % render marks outside the ImagingBBox (and QuarkXpress + % relies on it). +.dicttomark readonly def + +% Define access to device defaults. +/.defaultdeviceparams + { finddevice //null .getdeviceparams + } bind def + +% Select media (input or output). The hard work is done in an operator: +% <pagedict> <attrdict> <policydict> <keys> .matchmedia <key> true +% <pagedict> <attrdict> <policydict> <keys> .matchmedia false +% <pagedict> null <policydict> <keys> .matchmedia null true +/.selectmedia % <orig> <request> <merged> <failed> <-- retained + % <attrdict> <policydict> <attrkeys> <mediakey> + % .selectmedia + { 5 index 5 -2 roll 4 index .matchmedia + % Stack: orig request merged failed attrkeys mediakey + % (key true | false) + { 4 index 3 1 roll put pop + } + { % Adobe's implementations have a "big hairy heuristic" + % to choose the set of keys to report as having failed the match. + % For the moment, we report any keys that are in the request + % and don't have the same value as in the original dictionary. + 5 index 1 index .knownget + { 4 index 3 1 roll put } + { 3 index exch .undef } + ifelse + { % Stack: <orig> <request> <merged> <failed> <attrkey> + 3 index 1 index .knownget + { 5 index 2 index .knownget { ne } { pop //true } ifelse } + { //false } + ifelse % Stack: ... <failed> <attrkey> <report> + { 2 copy /rangecheck put } + if pop + } + forall + } + ifelse + } bind def + +% Apply Policies to any unprocessed failed requests. +% As we process each request entry, we replace the error name +% in the <failed> dictionary with the policy value, +% and we replace the key in the <merged> dictionary with its prior value +% (or remove it if it had no prior value). +/.policyprocs mark +% These procedures are called with the following on the stack: +% <orig> <merged> <failed> <Policies> <key> <policy> +% They are expected to consume the top 2 operands. +% NOTE: we currently treat all values other than 0, 1, or 7 (for PageSize) +% the same as 0, i.e., we signal an error. +% +% M. Sweet, Easy Software Products: +% +% Define NOMEDIAATTRS to turn off the default (but unimplementable) media +% selection policies for setpagedevice. This is used by CUPS to support +% the standard Adobe media attributes. + 0 { % Set errorinfo and signal a configurationerror. + NOMEDIAATTRS { + % NOMEDIAATTRS means that the default policy is 7... + pop 2 index exch 7 put + } { + pop dup 4 index exch get 2 array astore + $error /errorinfo 3 -1 roll put + cleartomark + /setpagedevice .systemvar /configurationerror signalerror + } ifelse + } bind + 1 { % Roll back the failed request to its previous status. +SETPDDEBUG { (Rolling back.) = pstack flush } if + 3 index 2 index 3 -1 roll .forceput + 4 index 1 index .knownget + { 4 index 3 1 roll .forceput } + { 3 index exch .undef } + ifelse + } .bind + 7 { % For PageSize only, just impose the request. + 1 index /PageSize eq + { pop pop 1 index /PageSize 7 put } + { .policyprocs 0 get exec } + ifelse + } bind +.dicttomark readonly def +/.applypolicies % <orig> <merged> <failed> .applypolicies + % <orig> <merged'> <failed'> + { 1 index /Policies get 1 index + { type /integertype eq + { pop % already processed + } + { 2 copy .knownget not { 1 index /PolicyNotFound get } if + % Stack: <orig> <merged> <failed> <Policies> <key> + % <policy> + .policyprocs 1 index .knownget not { .policyprocs 0 get } if exec + } + ifelse + } + forall pop + } bind def + +% Prepare to present parameters to the device, by spreading them onto the +% operand stack and removing any that shouldn't be presented. +/.prepareparams % <params> .prepareparams -mark- <key1> <value1> ... + { mark exch dup + { % Stack: -mark- key1 value1 ... merged key value + .presentspecial 2 index .knownget + { exec { 3 -1 roll } { pop pop } ifelse } + { 3 -1 roll } + ifelse + } + forall pop + } bind def + +% Put device parameters without resetting currentpagedevice. +% (.putdeviceparams clears the current page device.) +/.putdeviceparamsonly % <device> <Policies|null> <require_all> -mark- + % <key1> <value1> ... .putdeviceparamsonly + % On success: <device> <eraseflag> + % On failure: <device> <Policies|null> <req_all> -mark- + % <key1> <error1> ... + { .currentpagedevice + { counttomark 4 add 1 roll .putdeviceparams + dup type /booleantype eq { 3 } { counttomark 5 add } ifelse -1 roll + .setpagedevice + } + { pop .putdeviceparams + } + ifelse + } bind def + +% Try setting the device parameters from the merged request. +/.trysetparams % <merged> <(ignored)> <device> <Policies> + % .trysetparams + { //true 4 index .prepareparams + % Add the computed .MediaSize. + % Stack: merged (ignored) device Policies -true- + % -mark- key1 value1 ... + counttomark 5 add index .computemediasize + exch pop exch pop /.MediaSize exch +SETPDDEBUG { (Putting.) = pstack flush } if + .putdeviceparamsonly +SETPDDEBUG { (Result of putting.) = pstack flush } if + } bind def + +% Compute the media size and initial matrix from a merged request (after +% media selection). +/.computemediasize % <request> .computemediasize + % <request> <matrix> <[width height]> + { dup /PageSize get % requested page size + 1 index /InputAttributes get + 2 index (%MediaSource) get get /PageSize get % media size + % (may be a range) + 2 index /Policies get + dup /PageSize .knownget + { exch pop } { /PolicyNotFound get } ifelse % PageSize policy, + % affects scaling + 3 index /Orientation .knownget not { //null } if + 4 index /RollFedMedia .knownget not { //false } if + matrix .matchpagesize not { + % This is a "can't happen" condition! + /setpagedevice .systemvar /rangecheck signalerror + } if + 2 array astore + } bind def + +% ---------------- setpagedevice itself ---------------- % + +/setpagedevice + { + % To avoid VM mismatches caused by copying subsidiary + % dictionaries to local VM (see WorPerfect bug in + % .makecurrentpagedevice) we want to make the dict + % returned by currentpagedevice local. However, if we + % run with -dSAFER we get a call to setpagedevice from + % .setsafe in gs_init.ps during startup. The dict returned + % by currentpagdevice is stored to the graphics state by + % .setpagedevice below, and returned by currentpagdevice. + % The Display PostScript code insists that the savedinitialgstate + % not have any pointers to local VM objects, so if we simply + % make the dict local then we fail in gs_dps.ps. The only + % solution is to make sure the VM mode is global during + % startup (to satisfy gs_dps.ps) and local thereafter + % (to satisfy the WordPerfect bug). + dup /..StartupGlobal known + { + currentglobal exch true setglobal + dup /..StartupGlobal undef + } { + % ensure that we are always in local VM mode to avoid + % mismatches. This is because we always create child + % dictionaries in local VM, regardless of the current VM state, + % (see .makecurrentpagdevice) and we can't store local objects + % in a global object, so we must ensure teh dictionary returned + % from currentpagedevice is in local VM. + currentglobal exch false setglobal + } ifelse + + %% We used to execute endpage after .tsrysetparams, but that actually alters + %% the page device dictionary (in particular /PageSize) this is not correct. + %% Testing with Adobe Acrobat Distiller shows that EndPage is ececuted if the + %% page device dictionary is empty, and indeed even if setpagedevice returns + %% an error (caught by stopped), so it seems pretty clear that we should + %% run any required EndPage very early in the setpagedevice process. + %% Bug 690667. + 2 .endpage + { 1 //true .outputpage + (>>setpagedevice, press <return> to continue<<\n) .confirm + } + if + % We mustn't pop the argument until the very end, + % so that the pseudo-operator machinery can restore the stack + % if an error occurs. + mark 1 index currentpagedevice + + % Check whether we are changing OutputDevice; + % also handle the case where the current device + % is not a page device. + % Stack: mark <request> <current> +SETPDDEBUG { (Checking.) = pstack flush } if + + dup /OutputDevice .knownget + { % Current device is a page device. + 2 index /OutputDevice .knownget + { % A specific OutputDevice was requested. + 2 copy eq + { pop pop //null } + { exch pop } + ifelse + } + { pop //null + } + ifelse + } + { % Current device is not a page device. + % Use the default device. + 1 index /OutputDevice .knownget not { .defaultdevicename } if + } + ifelse + dup //null eq + { pop + } + { exch pop .defaultdeviceparams + % In case of duplicate keys, .dicttomark takes the entry + % lower on the stack, so we can just append the defaults here. + .requiredattrs { exec } forall .dicttomark + } + ifelse + + % Check whether a viewer wants to intervene. + % We must check both the request (which takes precedence) + % and the current dictionary. + % Stack: mark <request> <orig> + exch dup /ViewerPreProcess .knownget + { exec } + { 1 index /ViewerPreProcess .knownget { exec } if } + ifelse exch + + % Construct a merged request from the actual request plus + % any keys that should always be propagated. + % Stack: mark <request> <orig> +SETPDDEBUG { (Merging.) = pstack flush } if + + exch 1 index length 1 index length add dict + .copiedkeys + { % Stack: <orig> <request> <merged> <key> + 3 index 1 index .knownget { 3 copy put pop } if pop + } + forall + % Stack: <orig> <request> <merged> + dup 2 index + { % stack: <orig> <request> <merged> <merged> <rkey> <rvalue> + .mergespecial 2 index .knownget { exec } if + put dup + } + forall pop + % Hack: if FIXEDRESOLUTION is true, discard any attempt to + % change HWResolution. + FIXEDRESOLUTION { dup /HWResolution .undef } if + % Hack: if FIXEDMEDIA is true, discard any attempt to change + % PageSize or HWSize unless the PageSize Policy 13 (for FitPage). + dup /Policies get /PageSize get 13 ne FIXEDMEDIA and + { dup /PageSize 4 index /PageSize get put + dup /HWSize 4 index /HWSize get put + } if + % Hack: to work around some files that take a PageSize + % from InputAttributes and impose it, discard any attempt + % to set PageSize to a 4-element value. + % Stack: mark <orig> <request> <merged> + dup /PageSize .knownget { + length 2 ne { + dup /PageSize 4 index /PageSize get put + } if + } if + + % Select input and output media. + % Stack: mark <orig> <request> <merged> +SETPDDEBUG { (Selecting.) = pstack flush } if + + 0 dict % <failed> + 1 index /InputAttributes .knownget + { 2 index /Policies get + .inputattrkeys (%MediaSource) cvn .selectmedia + } if + 1 index /OutputAttributes .knownget + { 2 index /Policies get + .outputattrkeys (%MediaDestination) cvn .selectmedia + } if + 3 -1 roll 4 1 roll % temporarily swap orig & request + .applypolicies + 3 -1 roll 4 1 roll % swap back + + % Construct the new device, and attempt to set its attributes. + % Stack: mark <orig> <request> <merged> <failed> +SETPDDEBUG { (Constructing.) = pstack flush } if + + currentdevice .devicename 2 index /OutputDevice get eq + { currentdevice } + { 1 index /OutputDevice get finddevice } + ifelse + %**************** We should copy the device here, + %**************** but since we can't close the old device, + %**************** we don't. This is WRONG. + %****************copydevice + 2 index /Policies get + .trysetparams + dup type /booleantype ne + { % The request failed. + % Stack: ... <orig> <request> <merged> <failed> <device> + % <Policies> true mark <name> <errorname> ... +SETPDDEBUG { (Recovering.) = pstack flush } if + counttomark 4 add index + counttomark 2 idiv { dup 4 -2 roll put } repeat + pop pop pop + % Stack: mark ... <orig> <request> <merged> <failed> <device> + % <Policies> + 6 2 roll 3 -1 roll 4 1 roll + .applypolicies + 3 -1 roll 4 1 roll 6 -2 roll + .trysetparams % shouldn't fail! + dup type /booleantype ne + { 2 { counttomark 1 add 1 roll cleartomark } repeat + /setpagedevice .systemvar exch signalerror + } + if + } + if + + % The attempt succeeded. Install the new device. + % Stack: mark ... <merged> <failed> <device> <eraseflag> +SETPDDEBUG { (Installing.) = pstack flush } if + + pop + % .setdevice clears the current page device! + .currentpagedevice pop exch + .setdevice pop + .setpagedevice + + % Implement UseCIEColor directly if this is a LL3 system. + % The color substitution feature is now implemented in + % the interpreter, and this is used as an optimization. + % + % NB: This shoud be the only use of the .setuseciecolor + % operator anywhere. + % + % Set some color space other than /DeviceGray, to insure + % that initgraphics will actually perform a setcolorspace + % operation (there is an optimization in setcolorspace + % that does nothing if the operand and current color + % spaces are the same) + + /.setuseciecolor where + { + pop 1 index /UseCIEColor .knownget + { + .setuseciecolor /DeviceRGB setcolorspace + } + if + } + if + + % Merge the request into the current page device, + % unless we're changing the OutputDevice. + % Stack: mark ... <merged> <failed> + exch currentpagedevice dup length 2 index length add dict + % Stack: mark ... <failed> <merged> <current> <newdict> + 2 index /OutputDevice .knownget { + 2 index /OutputDevice .knownget not { //null } if eq + } { + //true + } ifelse { + % Same OutputDevice, merge the dictionaries. + .copydict + } { + % Different OutputDevice, discard the old dictionary. + exch pop + } ifelse .copydict + % Initialize the default matrix, taking media matching + % into account. + .computemediasize pop initmatrix concat + dup /PageOffset .knownget + { % Translate by the given number of 1/72" units in device X/Y. + dup 0 get exch 1 get + 2 index /HWResolution get dup 1 get exch 0 get + 4 -1 roll mul 72 div 3 1 roll mul 72 div + idtransform translate + } + if + % We must install the new page device dictionary + % before calling the Install procedure. + dup .setpagedevice + /HighLevelDevice /GetDeviceParam .special_op { + exch pop not + }{ + //true + }ifelse + { + .setdefaulthalftone % Set the default screen before calling Install. + } if + dup /Install .knownget { + { .execinstall } stopped { + pop % Install procedure failed. One element will have been left on the stack. + % stack: mark <orig> <request> <failed> <merged> + 1 index /Install $error /errorname get put % Put it in the "failed" dict + % .applypolicies needs stack: <orig> <merged> <failed> + exch 4 2 roll exch 4 2 roll .applypolicies exch 4 2 roll exch 4 2 roll + % Now execute the old Install -- failures after this are not handled + dup /Install .knownget { { .execinstall } stopped { pop } if } if + .postinstall stop + } { + .postinstall + } ifelse + } { + .postinstall + } ifelse + setglobal % return to original VM allocation mode +} odef + +% We break out the code after calling the Install procedure into a +% separate procedure, since it is executed even if Install causes an error. +% By making .execinstall a separate operator procedure, we get the stacks +% mostly restored if it fails, except for one element (the operand). +% Thus if it fails, there will be one element left on the op stack. + +/.execinstall { % <proc> .execinstall - + dup % element left on the stack if the exec fails. + + % Because the interpreter optimizes tail calls, we can't just let + % the body of this procedure be 'exec', because that would lose + % the stack protection that is the whole reason for having the + % procedure in the first place. The 'pop' for the dummy element + % on the op stack suffices. + exec + pop % See above. +} odef + +/.postinstall { % mark ... <failed> <merged> .postinstall - + matrix currentmatrix .setdefaultmatrix + % Erase and initialize the page. + initgraphics + currentoverprint //false setoverprint 1 setcolor + .fillpage + 0 setcolor setoverprint + .beginpage + + % Clean up, calling PolicyReport if needed. + % Stack: mark ... <failed> <merged> +SETPDDEBUG { (Finishing.) = pstack flush } if + + exch dup length 0 ne + { 1 index /Policies get /PolicyReport get + counttomark 1 add 2 roll cleartomark + exec + } + { cleartomark + } + ifelse pop + +} odef + +end % level2dict +.setlanguagelevel diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_statd.ps b/Master/tlpkg/tlgs/Resource/Init/gs_statd.ps new file mode 100644 index 00000000000..18dfced1499 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_statd.ps @@ -0,0 +1,373 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% This file provides statusdict, serverdict, and assorted LaserWriter +% operators, mostly for the benefit of poorly designed PostScript programs +% that 'know' they are running on a LaserWriter. + +systemdict begin + % We make statusdict a little larger for Level 2 stuff. + % Note that it must be allocated in local VM. + .currentglobal //false .setglobal + /statusdict 91 dict .forcedef % statusdict is local, sys'dict global + % To support the Level 2 job control features, + % serverdict must also be in local VM. + /serverdict 10 dict .forcedef % serverdict is local, sys'dict global + .setglobal +end + +statusdict begin + +% Keep the table of named paper sizes as procedures. Reuse them later +% as compatibility operators. +/.pagetypeprocs 70 dict begin + +% Define various paper formats. The Adobe documentation defines only these: +% 11x17, a3, a4, a4small, b5, ledger, legal, letter, lettersmall, note. +% These procedures are also accessed as data structures during initialization, +% so the page dimensions must be the first two elements of the procedure. + +/.setpagesize { /statusdict .systemvar begin .setpagesize end } bind def + + % Page sizes defined by Adobe documentation + % Note: these executable arrays should all begin with two + % integers which are the width and height (see gs_setpd.ps). + /11x17 {792 1224 //.setpagesize exec} bind def % 11x17 portrait + /a3 {842 1191 //.setpagesize exec} bind def + /a4 {595 842 //.setpagesize exec} bind def +% a4small should be a4 with an ImagingBBox of [25 25 570 817]. + /a4small /a4 load def +% b5 see below. + /ledger {1224 792 //.setpagesize exec} bind def % 11x17 landscape + /legal {612 1008 //.setpagesize exec} bind def + /letter {612 792 //.setpagesize exec} bind def +% lettersmall should be letter with an ImagingBBox of [25 25 587 767]. + /lettersmall /letter load def +% note should be letter (or some other size) with the ImagingBBox +% shrunk by 25 units on all 4 sides. + /note /letter load def + % End of Adobe-defined page sizes +STRICT { (%END SIZES) .skipeof } if + % Other page sizes + % ISO standard paper sizes + /a0 {2384 3370 //.setpagesize exec} bind def + /a1 {1684 2384 //.setpagesize exec} bind def + /a2 {1191 1684 //.setpagesize exec} bind def +% /a3 {842 1191 //.setpagesize exec} bind def % defined by Adobe +% /a4 {595 842 //.setpagesize exec} bind def % defined by Adobe + /a5 {420 595 //.setpagesize exec} bind def + /a6 {297 420 //.setpagesize exec} bind def + /a7 {210 297 //.setpagesize exec} bind def + /a8 {148 210 //.setpagesize exec} bind def + /a9 {105 148 //.setpagesize exec} bind def + /a10 {73 105 //.setpagesize exec} bind def +% ISO and JIS B sizes are different.... + /isob0 {2835 4008 //.setpagesize exec} bind def + /b0 /isob0 load def + /isob1 {2004 2835 //.setpagesize exec} bind def + /b1 /isob1 load def + /isob2 {1417 2004 //.setpagesize exec} bind def + /b2 /isob2 load def + /isob3 {1001 1417 //.setpagesize exec} bind def + /b3 /isob3 load def + /isob4 {709 1001 //.setpagesize exec} bind def + /b4 /isob4 load def + /isob5 {499 709 //.setpagesize exec} bind def + /b5 /isob5 load def + /isob6 {354 499 //.setpagesize exec} bind def + /b6 /isob6 load def + /jisb0 {2920 4127 //.setpagesize exec} bind def + /jisb1 {2064 2920 //.setpagesize exec} bind def + /jisb2 {1460 2064 //.setpagesize exec} bind def + /jisb3 {1032 1460 //.setpagesize exec} bind def + /jisb4 {729 1032 //.setpagesize exec} bind def + /jisb5 {516 729 //.setpagesize exec} bind def + /jisb6 {363 516 //.setpagesize exec} bind def + /c0 {2599 3677 //.setpagesize exec} bind def + /c1 {1837 2599 //.setpagesize exec} bind def + /c2 {1298 1837 //.setpagesize exec} bind def + /c3 {918 1298 //.setpagesize exec} bind def + /c4 {649 918 //.setpagesize exec} bind def + /c5 {459 649 //.setpagesize exec} bind def + /c6 {323 459 //.setpagesize exec} bind def + % U.S. CAD standard paper sizes + /archE {2592 3456 //.setpagesize exec} bind def + /archD {1728 2592 //.setpagesize exec} bind def + /archC {1296 1728 //.setpagesize exec} bind def + /archB {864 1296 //.setpagesize exec} bind def + /archA {648 864 //.setpagesize exec} bind def + % Other paper sizes + /flsa {612 936 //.setpagesize exec} bind def % U.S. foolscap + /flse {612 936 //.setpagesize exec} bind def % European foolscap + /halfletter {396 612 //.setpagesize exec} bind def + % minimum of a4 and letter (a4 width, letter length) + /pa4 {595 792 //.setpagesize exec} bind def + % Japanese postcard size, 100mm x 148mm + /hagaki {283 420 //.setpagesize exec} bind def + % U.S. ANSI/ASME Y14.1 paper sizes + /ANSI_A //letter def + /ANSI_B //11x17 def + /tabloid //11x17 def + /ANSI_C {1224 1585 //.setpagesize exec} bind def + /ANSI_D {1585 2448 //.setpagesize exec} bind def + /ANSI_E {2448 3168 //.setpagesize exec} bind def + /ANSI_F {2016 2880 //.setpagesize exec} bind def +%END SIZES +currentdict end +dup /.setpagesize .undef +userdict begin dup { def } forall end % reuse! +readonly def + +% Define the pagetype values for the known page formats. +% This array is now used for deterministic enumeration of .pagetypeprocs +/.pagetypenames [ .pagetypeprocs { pop } bind forall ] + { .namestring exch .namestring gt } bind .sort + readonly def + +%%%%%% The following items were suggested by a user as useful. + +% Permanent definitions + +/ramsize 4194304 def +/hardwareiomode 0 def + /sethardwareiomode {pop} bind def +/softwareiomode 0 def + /setsoftwareiomode {pop} bind def +/dosysstart //false def + /setdosysstart {pop} bind def +/allowjobreset //true def + /setallowjobreset {pop} bind def +/defaultpaperfamily 0 def + /setdefaultpaperfamily {pop} bind def +/defaultpapertray 0 def + /setdefaultpapertray {pop} bind def +/defaulttrayswitch //false def + /setdefaulttrayswitch {pop} bind def + +% Tray and format selection + + /11x17tray {/11x17 .uservar exec} bind def + /a3tray {/a3 .uservar exec} bind def + /a4tray {/a4 .uservar exec} bind def + /a5tray {/a5 .uservar exec} bind def + /a6tray {/a6 .uservar exec} bind def + /b4tray {/b4 .uservar exec} bind def + /b5tray {/b5 .uservar exec} bind def + /flsatray {/flsa .uservar exec} bind def + /flsetray {/flse .uservar exec} bind def + /halflettertray {/halfletter .uservar exec} bind def + /ledgertray {/ledger .uservar exec} bind def + /legaltray {/legal .uservar exec} bind def + /lettertray {/letter .uservar exec} bind def + +% Per-job parameters + +/paperfamily 0 def % 0 is US, 1 is European +/papertray 1 def + /setpapertray {statusdict exch /papertray exch put} bind def +/trayswitch //false def % paperout feeds from another tray +% We don't implement the (undocumented by Adobe) papersize 'operator', +% because it's very awkward to make it interact properly with all the +% different ways of setting the paper size. +%/papersize {/letter //true} bind def % <name of paper size>, <short-edge-first-p> +/appletalktype (LaserWriter) def + +%%%%%% The following items are defined in the PostScript Language +%%%%%% Reference Manual, First Edition, and subsequent 'compatibility' +%%%%%% documentation from Adobe. + + /checkpassword {statusdict begin .password eq end} bind def + /defaulttimeouts {statusdict begin .timeouts aload pop end} bind def + /diskonline { + //false (%disk*%) { pop not exit } 8192 string /IODevice resourceforall + } bind def + /diskstatus {10240 2097152 } bind odef % - diskstatus <free> <total> (in 1024 byte pages) + +%/dostartpage + /eescratch {pop 0} bind def + /idlefonts {statusdict begin mark .idlefonts aload pop end} bind def + /jobname () def +%/jobtimeout + /manualfeed //false def + /manualfeedtimeout 60 def + /margins {statusdict begin .topmargin .leftmargin end} bind def + /pagecount {4711} bind def + /pagestackorder {//false} bind def + /pagetype 0 def + /prefeed //false def + /printererror {pop pop} bind def + /printername {statusdict /.printername get exch copy} bind def + /processcolors /processcolors load def % defined in systemdict + /product product def % product is defined in systemdict + /revision revision def % revision is defined in systemdict + /sccbatch {pop 9600 0} bind def + /sccinteractive {pop 9600 0} bind def + /setdefaulttimeouts {statusdict begin .timeouts astore pop end} bind def + /setdostartpage {statusdict exch /dostartpage exch put} bind def + /setduplexmode {mark /Duplex 3 -1 roll currentdevice putdeviceprops} bind def + /seteescratch {pop pop} bind def + /setidlefonts {] statusdict exch /.idlefonts exch put} bind def + /setjobtimeout {statusdict exch /jobtimeout exch put} bind def + /setmargins + { statusdict begin + /.leftmargin exch def /.topmargin exch def + end + } bind def + +% The following compatibility operators are only documented by Adobe in a +% supplement to the Red Book. +% +% - pagemargin <offset> +% - pageparams <width> <height> <offset> <orientation> +% <width> <height> <orientation> setpage - +% <offset> setpagemargin - +% <width> <height> <offset> <orientation> setpageparams - +% +% width and height are in default units (and if orientation is odd, are +% exchanged!). offset is the x margin, also in default units. +% Unfortunately, because orientation is relative to the device paper feed, +% it does not have a consistent meaning in terms of image orientation. +% We follow the convention that ORIENT1 determines the orientation value +% that means portait: false means 0, true means 1. + + /pagemargin { 0 } bind def + /pageparams + { currentdevice 1 dict dup /.MediaSize dup put .getdeviceparams + exch pop exch pop aload pop 0 ORIENT1 { 1 } { 0 } ifelse + } bind def + /setpage + { ORIENT1 { 1 } { 0 } ifelse ne {exch} if + statusdict /.setpagesize get exec + } bind def + /setpagemargin {pop} bind def % can't do better without setpagedevice + /setpageparams + { exch pop ORIENT1 { 1 } { 0 } ifelse ne {exch} if + statusdict /.setpagesize get exec + } bind def + /setpagetype + { statusdict begin + % The Adobe documentation only defines setpagetype + % (a Level 1 operator) as accepting the values 0 and 1, + % so we do too. + {/letter /note} 1 index get + //systemdict /userdict get exch get cvx exec + /pagetype exch def + end + } bind def + + /setpassword + {exch checkpassword + {statusdict exch /.password exch put //true} + {pop //false} + ifelse} bind def + /setprintername + {dup length string copy statusdict exch /.printername exch put} bind def + +% setresolution is not documented by Adobe, but some applications +% use it anyway, without testing whether or not it is present. +% +% <pixels_per_inch> setresolution - +% +% sets the resolution of the device. + + /setresolution + { mark /HWResolution [ 4 -1 roll dup ] currentdevice putdeviceprops pop + initmatrix erasepage + } bind def + /setsccbatch {pop pop pop} bind def + /setsccinteractive {pop pop pop} bind def + /settumble {pop} bind def + /waittimeout 300 def + +%%%%%% End of documented items. + +/.setpagesize + { mark /HWSize [ + 4 index 4 index matrix defaultmatrix dtransform + abs ceiling cvi exch abs ceiling cvi exch + ] currentdevice putdeviceprops pop pop pop + initmatrix initclip erasepage + } bind def +/.password 0 def +/.timeouts [0 60 30] def +//true setdostartpage +mark setidlefonts +0 setjobtimeout +0 0 setmargins +product setprintername + +end % statusdict + +%%%%%% The following documented compatibility "operators" are in systemdict, +%%%%%% not in statusdict. + +systemdict begin +.currentglobal //true .setglobal + +/devformat //true def +/devforall { % <pattern> <proc> <scratch> devforall - + exch { + 1 index currentdevparams + /Type .knownget { /FileSystem eq } { //false } ifelse + { exec } { pop pop } ifelse + } /exec load 3 packedarray cvx exch + (*) 3 1 roll /IODevice resourceforall +} odef + +/devstatus { % <(%disk*%)> devstatus <searchable> <writable> + % <hasNames> <mounted> <removable> <searchOrder> + % <freePages> <size> //true + % <string> devstatus //false + dup length 5 ge { + dup 0 5 getinterval (%disk) eq { + dup /IODevice resourcestatus { + pop pop dup currentdevparams + dup /Searchable get + exch dup /Writeable get + exch dup /HasNames get + exch dup /Mounted get + exch dup /Removable get + exch dup /SearchOrder get + exch dup /Free get + exch /LogicalSize get + 9 -1 roll pop //true + } { + pop //false + } ifelse + } { + pop //false + } ifelse + } { + pop //false + } ifelse +} odef + +.setglobal end % systemdict + +% The following contents of serverdict are a complete guess, +% based on some observed LaserWriter boilerplate. + +serverdict begin + + /execjob { } bind def +% The Red Book implies that something like the following is +% an appropriate definition of exitserver. + /exitserver { clear stop } bind def +% However, this interacts badly with our standard error handler, +% so we override it with the following less appropriate definition. + /exitserver { 0 ne { clear cleardictstack } if } bind def + /setrealdevice { } bind def + +end % serverdict diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_std_e.ps b/Master/tlpkg/tlgs/Resource/Init/gs_std_e.ps new file mode 100644 index 00000000000..19200503fda --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_std_e.ps @@ -0,0 +1,72 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Define the standard encoding vector. +/StandardEncoding +% \00x + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +% \04x + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus + /comma /hyphen /period /slash + /zero /one /two /three + /four /five /six /seven + /eight /nine /colon /semicolon + /less /equal /greater /question +% \10x + /at /A /B /C /D /E /F /G + /H /I /J /K /L /M /N /O + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% \14x + /quoteleft /a /b /c /d /e /f /g + /h /i /j /k /l /m /n /o + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde /.notdef +% \20x + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +% \24x + /.notdef /exclamdown /cent /sterling + /fraction /yen /florin /section + /currency /quotesingle /quotedblleft /guillemotleft + /guilsinglleft /guilsinglright /fi /fl + /.notdef /endash /dagger /daggerdbl + /periodcentered /.notdef /paragraph /bullet + /quotesinglbase /quotedblbase /quotedblright /guillemotright + /ellipsis /perthousand /.notdef /questiondown +% \30x + /.notdef /grave /acute /circumflex /tilde /macron /breve /dotaccent + /dieresis /.notdef /ring /cedilla /.notdef /hungarumlaut /ogonek /caron + /emdash /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +% \34x + /.notdef /AE /.notdef /ordfeminine /.notdef /.notdef /.notdef /.notdef + /Lslash /Oslash /OE /ordmasculine /.notdef /.notdef /.notdef /.notdef + /.notdef /ae /.notdef /.notdef /.notdef /dotlessi /.notdef /.notdef + /lslash /oslash /oe /germandbls /.notdef /.notdef /.notdef /.notdef +% Make an array on large systems, a packed array on small ones. +256 +vmstatus exch pop exch pop +100000 ge { array astore readonly } { packedarray } ifelse +def +0 StandardEncoding .registerencoding +/StandardEncoding StandardEncoding .defineencoding diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_sym_e.ps b/Master/tlpkg/tlgs/Resource/Init/gs_sym_e.ps new file mode 100644 index 00000000000..5a7c0ccb2f7 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_sym_e.ps @@ -0,0 +1,82 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Define the Symbol encoding vector. +/currentglobal where + { pop currentglobal { setglobal } //true setglobal } + { { } } +ifelse +/SymbolEncoding +% \000 + StandardEncoding 0 32 getinterval aload pop % /.notdef +% \040 + /space /exclam /universal /numbersign + /existential /percent /ampersand /suchthat + /parenleft /parenright /asteriskmath /plus + /comma /minus /period /slash + /zero /one /two /three + /four /five /six /seven + /eight /nine /colon /semicolon + /less /equal /greater /question +% \100 + /congruent /Alpha /Beta /Chi + /Delta /Epsilon /Phi /Gamma + /Eta /Iota /theta1 /Kappa + /Lambda /Mu /Nu /Omicron + /Pi /Theta /Rho /Sigma + /Tau /Upsilon /sigma1 /Omega + /Xi /Psi /Zeta /bracketleft + /therefore /bracketright /perpendicular /underscore +% \140 + /radicalex /alpha /beta /chi + /delta /epsilon /phi /gamma + /eta /iota /phi1 /kappa + /lambda /mu /nu /omicron + /pi /theta /rho /sigma + /tau /upsilon /omega1 /omega + /xi /psi /zeta /braceleft + /bar /braceright /similar /.notdef +% \200 + StandardEncoding 0 32 getinterval aload pop % /.notdef +% \240 + /Euro /Upsilon1 /minute /lessequal + /fraction /infinity /florin /club + /diamond /heart /spade /arrowboth + /arrowleft /arrowup /arrowright /arrowdown + /degree /plusminus /second /greaterequal + /multiply /proportional /partialdiff /bullet + /divide /notequal /equivalence /approxequal + /ellipsis /arrowvertex /arrowhorizex /carriagereturn +% \300 + /aleph /Ifraktur /Rfraktur /weierstrass + /circlemultiply /circleplus /emptyset /intersection + /union /propersuperset /reflexsuperset /notsubset + /propersubset /reflexsubset /element /notelement + /angle /gradient /registerserif /copyrightserif + /trademarkserif /product /radical /dotmath + /logicalnot /logicaland /logicalor /arrowdblboth + /arrowdblleft /arrowdblup /arrowdblright /arrowdbldown +% \340 + /lozenge /angleleft /registersans /copyrightsans + /trademarksans /summation /parenlefttp /parenleftex + /parenleftbt /bracketlefttp /bracketleftex /bracketleftbt + /bracelefttp /braceleftmid /braceleftbt /braceex + /.notdef /angleright /integral /integraltp + /integralex /integralbt /parenrighttp /parenrightex + /parenrightbt /bracketrighttp /bracketrightex /bracketrightbt + /bracerighttp /bracerightmid /bracerightbt /.notdef +256 packedarray .defineencoding +2 SymbolEncoding .registerencoding +exec diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_trap.ps b/Master/tlpkg/tlgs/Resource/Init/gs_trap.ps new file mode 100644 index 00000000000..71aec983f4b --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_trap.ps @@ -0,0 +1,102 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% PostScript LanguageLevel 3 in-RIP trapping support. + +ll3dict begin + +% We need LanguageLevel 2 or higher in order to have setuserparams and +% defineresource. +languagelevel dup 2 .max .setlanguagelevel + +% ------ Trapping ------ % + +% The PostScript-level trapping parameters are maintained in userdict, +% and explicitly reinstalled upon restore. + +/Trapping mark + +/settrapparams dup { % <paramdict> settrapparams - + /.trapparams .uservar dup length dict .copydict + dup 2 index { + % Stack: paramdict olddict olddict key value + 2 index 2 index known { put dup } { pop pop } ifelse + } forall pop + dup .settrapparams % Let the operator check parameter validity. + .userdict /.trapparams 3 -1 roll put pop +} bind .makeoperator + +/.copyparams { % <obj> .copyparams <obj'> + dup type /dicttype eq { + dup length dict .copydict + dup { + .copyparams 3 copy put pop pop + } forall + } { + dup type /arraytype eq { + [ exch { .copyparams } forall ] + } if + } ifelse +} odef + +/currenttrapparams dup { % - currenttrapparams <paramdict> + /.trapparams .uservar .copyparams +} bind .makeoperator + +/settrapzone dup { % - settrapzone - + % ****** DUMMY ****** + newpath +} bind .makeoperator + +% Define initial (dummy) trapping parameters. +% These values are mostly complete guesses. +userdict /.trapparams mark + /BlackColorLimit 1.0 + /BlackDensityLimit 1.0 + /BlackWidth 1.0 + /ColorantZoneDetails 0 dict + /Enabled //true + /HalftoneName //null + /ImageInternalTrapping //false + /ImagemaskTrapping //true + /ImageResolution 1 + /ImageToObjectTrapping //true + /ImageTrapPlacement /Center + /SlidingTrapLimit 1.0 + /StepLimit 1.0 + /TrapColorScaling 0.0 + /TrapSetName //null + /TrapWidth 1.0 +.dicttomark readonly put + +.dicttomark /ProcSet defineresource pop + +% Define the InkParams and TrapParams resource categories. +{ /InkParams /TrapParams } { + /Generic /Category findresource dup maxlength 3 add dict .copydict begin + /InstanceType /dicttype def + currentdict end /Category defineresource pop +} forall + +% Define the TrappingType resource category. +/Generic /Category findresource dup maxlength 3 add dict .copydict begin + /InstanceType /integertype def +/TrappingType currentdict end /Category defineresource pop + +{1001} { dup /TrappingType defineresource pop } forall + +.setlanguagelevel + +end % ll3dict diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps b/Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps new file mode 100644 index 00000000000..ebacc6bbd0d --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps @@ -0,0 +1,1987 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Support code for direct use of TrueType fonts. +% (Not needed for Type 42 fonts.) + +% Note that if you want to use this file without including the ttfont.dev +% option when you built Ghostscript, you will need to load the following +% files before this one: +% lib/gs_mgl_e.ps +% lib/gs_mro_e.ps +% lib/gs_wan_e.ps + +% Thanks to B. Jackowski and GUST (the Polish TeX Users' Group) for +% the glyf-splitting code. + +% ---------------- Font loading machinery ---------------- % + +% Augment the FONTPATH machinery so it recognizes TrueType fonts. + +/.scanfontheaders where { + pop /.scanfontheaders [ + .scanfontheaders aload pop (\000\001\000\000*) (true*) (wOFF*) + ] def +} if + +% <file> <key> .findfontvalue <value> true +% <file> <key> .findfontvalue false +% Closes the file in either case. +/.findnonttfontvalue /.findfontvalue load def +/.findfontvalue { + 1 index .is_woff { + dup /FontType eq { + pop closefile 42 //true + } { + dup /FontName eq { pop .findwoffname } { pop closefile //false } ifelse + } ifelse + } + { + 1 index .is_ttf_or_otf { + % If this is a font at all, it's a TrueType font. + dup /FontType eq { + pop closefile 42 //true + } { + dup /FontName eq { pop .findttfontname } { pop closefile //false } ifelse + } ifelse + } { + % Not a TrueType font. + .findnonttfontvalue + } ifelse + } ifelse +} bind def + +% <file> .findttfontname <fname> true +% <file> .findttfontname false +% Closes the file in either case. +/.findttfontname { + //true 0 .loadttfonttables + tabdict /name .knownget { + dup 8 getu32 f exch setfileposition + 12 getu32 + dup 65535 gt { pop 65535 } if % protect against extremely large name + string f exch readstring pop + dup + 6 findname not { + 4 findname % Try FullName + } { + exch pop //true + } + ifelse + } { + //false + } ifelse + f closefile end end +} bind def + +/.findwoffname { + //true 0 .loadwofftables + tabdict /name .knownget { + dup /clen exch 8 getu32 def + dup /olen exch 12 getu32 def + 4 getu32 f exch setfileposition + olen dup 65535 gt { pop 65535 } if % protect against extremely large name + /fs + clen olen ne + {f clen () /SubFileDecode filter /FlateDecode filter} + {f clen () /SubFileDecode filter} + ifelse def + string fs exch readstring pop + fs closefile + dup + 6 findname not { + 4 findname % Try FullName + } { + exch pop //true + } + ifelse + } { + //false + } ifelse + f closefile end end +} bind def + + +% Load a font file that might be a TrueType font. + +/tt_tag_dict << <00010000> 0 (true) 0 (typ1) 0 (ttcf) 0 >> readonly def +/ttf_otf_tag_dict << <00010000> 0 (true) 0 (typ1) 0 (ttcf) 0 (OTTO) 0>> readonly def +% The wOFF tag is immediately followed by the sfnt "flavour" so for simplicity +% combine them +/woff_tag_dict << + (wOFF) 0 + <774F464600010000> 0 % (wOFF)<00010000> .concatstrings + (wOFFtrue) 0 + (wOFFtyp1) 0 +>> readonly def + +% <file> .loadfontfile - +/.loadnonttfontfile /.loadfontfile load def +/.loadfontfile { + dup (12345678) .peekstring { //woff_tag_dict exch known } { //false } ifelse + { + .loadwofffont pop + } + { + dup (1234) .peekstring { //tt_tag_dict exch known } { //false } ifelse { + % If this is a font at all, it's a TrueType font. + .loadttfont pop + } { + % Not a TrueType font. + .loadnonttfontfile + } ifelse + } ifelse +} bind def + +% <file> .is_ttf_or_otf <bool> +/.is_ttf_or_otf { + dup 0 setfileposition (1234) .peekstring { //ttf_otf_tag_dict exch known } { //false } ifelse +} bind def + +/.is_woff { + dup 0 setfileposition (1234) .peekstring { //woff_tag_dict exch known } { //false } ifelse +} bind def + +currentdict /tt_tag_dict .undef +currentdict /ttf_otf_tag_dict .undef +currentdict /woff_tag_dict .undef + +% ---------------- Automatic Type 42 generation ---------------- % + +% Load a TrueType font from a file as a Type 42 PostScript font. +% The thing that makes this really messy is the handling of encodings. +% There are 2 interacting tables that affect the encoding: +% 'cmap' provides multiple maps from character codes to glyph indices +% 'post' maps glyph indices to glyph names (if present) +% What we need to get out of this is: +% Encoding mapping character codes to glyph names +% (the composition of cmap and post) +% CharStrings mapping glyph names to glyph indices +% (the inverse of post) +% If the post table is missing, we have to take a guess based on the cmap +% table. + +/.loadttfontdict 50 dict dup begin + +/orgXUID AladdinEnterprisesXUID def +/maxstring 32764 def % half the maximum length of a PostScript string, + % must be a multiple of 4 (for hmtx / loca / vmtx) + +/.invert_encoding % <array> invert_encoding <dict> +{ dup 256 dict exch + 0 exch 1 exch length 1 sub { % [] <> i + dup 3 index exch get % [] <> i v + dup /.notdef ne { + exch 2 index 2 index .knownget { + dup type /arraytype eq { + [ exch aload pop counttomark 2 add -1 roll ] + } { + exch 2 array astore + } ifelse + } if 2 index 3 1 roll put + } { + pop pop + } ifelse + } for + exch pop +} bind def + +% Make /MacRomanEncodingForTrueType including additional +% characters in Mac OS Roman encoding, which is missing +% in /MacRomanEncoding. See PDF spec 1.7, p. 431 or +% "Inside Macintosh: Text" 1-55, Figure 1-36. +% This is useful to exploit the glyphs via Apple Roman +% TrueType cmap subtable, but not appropriate for information +% interchange. + +/MacRomanEncodingForTrueType + /MacRomanEncoding .findencoding + dup length array copy + << + /notequal 173 + /infinity 176 + /lessequal 178 + /greaterequal 179 + /partialdiff 182 + /summation 183 + /product 184 + /pi 185 + /integral 186 + /Omega 189 + /radical 195 + /approxequal 197 + /Delta 198 + /lozenge 215 + /Euro 219 + /apple 240 + >> { + TTFDEBUG { (Extend MacRomanEncodingForTrueType for TrueType: ) =only } if + + % check /.notdef to avoid overwriting + 2 index 1 index get dup /.notdef eq { + TTFDEBUG { (insert /) =only 2 index =only ( @ ) =only 1 index //== exec } if + pop + exch 2 index 3 1 roll put + } { + TTFDEBUG { (cannot insert /) =only 2 index =only ( @ ) =only 1 index =only ( used for ) =only dup //== exec } if + pop + pop pop + } ifelse + } forall + aload pop + 256 packedarray + 5 1 index .registerencoding +.defineencoding + +% Define the Macintosh standard mapping from characters to glyph indices. +/MacRomanEncoding dup .findencoding def +/MacGlyphEncoding dup .findencoding def +/MacRomanEncodingForTrueType dup .findencoding def + +% Invert the MacRomanEncoding. +/.romanmacdict MacRomanEncodingForTrueType .invert_encoding def +/.latin1isodict ISOLatin1Encoding .invert_encoding def + +% Define remapping for misnamed glyphs in TrueType 'post' tables. +% There are probably a lot more than this! +/postremap mark + /Eoverdot /Edotaccent + /eoverdot /edotaccent +.dicttomark readonly def + +% Array used for fast pre-filling of cmap array +/.array1024z [ 1024 { 0 } repeat ] def + +% ---- Utilities ---- % + +% Define a serial number for creating unique XUIDs for TrueType fonts. +% We used to use the checkSumAdjustment value from the font, but this is +% not reliable, since some fonts don't set it correctly. +% Note that we must do this in a string to make it immune to save/restore. + +% handle 64 bit integer objects +/xuidstring 16#ffffffff 0 gt +{ + <8000000000000000> +} +{ + <80000000> +} ifelse def +/curxuid { % - curxuid <int> + .getCPSImode + //false .setCPSImode + 0 xuidstring { exch 8 bitshift exch add } forall + % for tbe benefit of pdfwrite/ps2write we want the resulting XUID contents + % to fit into a 32 bit value + 16#ffffffff 0 gt + { + 16#ffffffff idiv + } if + exch .setCPSImode +} bind def +/nextxuid { % - nextxuid - + 3 -1 0 { + xuidstring 1 index 2 copy get dup 255 ne { + 1 add put pop exit + } if pop 0 put pop + } for +} bind def + +% <string> <index> getu16 <integer> +/getu16 { + 2 copy get 8 bitshift 3 1 roll 1 add get add +} bind def + +% <string> <index> gets16 <integer> +/gets16 { + getu16 16#8000 xor 16#8000 sub +} bind def + +% <string> <index> getu32 <integer> +/getu32 { + 2 copy getu16 16 bitshift 3 1 roll 2 add getu16 add +} bind def + +% <string> <index> gets32 <integer> +/gets32 { + 2 copy gets16 16 bitshift 3 1 roll 2 add getu16 add +} bind def + +% <string|array> <index> getu16 <integer> +/getu16a { + 2 getinterval_from_stringarray 0 getu16 +} bind def + +% <string|array> <index> gets16 <integer> +/gets16a { + 2 getinterval_from_stringarray 0 gets16 +} bind def + +% <string|array> <index> getu32a <integer> +/getu32a { + 4 getinterval_from_stringarray 0 getu32 +} bind def + +% <string|array> <index> gets32a <integer> +/gets32a { + 4 getinterval_from_stringarray 0 gets32 +} bind def + +16#ffffffff 0 gt { % 64-bit sign extension + { /gets32 /gets32a} { + mark 1 index load aload pop { 16#80000000 xor 16#80000000 sub } aload pop + .packtomark cvx def + } bind forall +} if + +% <string> <index> <integer> putu16 - +/putu16 { + 3 copy -8 bitshift put + exch 1 add exch 16#ff and put +} bind def + +% <string> <index> <integer> putu32 - +/putu32 { + 3 copy -16 bitshift putu16 + exch 2 add exch 16#ffff and putu16 +} bind def + +% <nametable> <nameid> findname <string> true +% <nametable> <nameid> findname false +/findname { + TTFDEBUG { (findname: ) print dup =only } if + //false 3 1 roll + 1 index length 0 gt { % check for zero length name table + 0 1 3 index 2 getu16 1 sub { + % Stack: false table id index + 12 mul 6 add 2 index exch 12 getinterval + dup 6 getu16 2 index eq 1 index 8 getu16 0 ne and { + % We found the name we want. + exch pop + % Stack: false table record + dup 10 getu16 2 index 4 getu16 add + 1 index 8 getu16 4 -1 roll 3 1 roll + 3 copy add 1 index length + le { + pop + getinterval exch + % Stack: false string record + % Check for 8- vs. 16-bit characters. + is2byte { //true } { dup is2byte2 } ifelse { string2to1 } if //true //null 4 -1 roll exit + } { + pop pop pop pop + //false + exit + } ifelse + } if pop + } for + } if + pop pop + TTFDEBUG { + dup { ( = ) print 1 index //== exec } { ( not found) = } ifelse + } if +} bind def + +% <namerecord> is2byte <bool> +/is2byte { + dup 0 getu16 + { + { pop //true } % Apple Unicode + { pop //false } % Macintosh Script manager + { 1 getu16 1 eq } % ISO + { 1 getu16 1 eq } % Microsoft + { pop //false } % default - *MUST* be last + } + % check for a valid Platform ID, if we don't get one, assume single byte encoding + dup length 1 sub + 2 index lt {exch pop dup length 1 sub}{exch} ifelse + get exec +} bind def + +% <string> is2byte2 <bool> +/is2byte2 { + dup length + dup 2 mod 0 ne { + pop pop //false + } { % s l + //true exch % s b l + 1 sub 0 exch 2 exch { + 2 index exch get 0 ne { + pop //false exit + } if + } for + exch pop + } ifelse +} bind def + +% <string2> string2to1 <string> +/string2to1 { + dup length 2 idiv string dup + 0 1 3 index length 1 sub { + 3 index 1 index 2 mul 1 add get put dup + } for pop exch pop +} bind def + +% Each procedure in this dictionary is called as follows: +% <encodingtable> proc <glypharray> +/cmapformats mark + 0 { % Apple standard 1-to-1 mapping. + 6 256 getinterval_from_stringarray + mark 0 3 -1 roll + { 1 index 1 add } forall pop + .dicttomark + } bind + 2 { % Apple 16bit CJK (ShiftJIS etc) + + % /sHK_sz subHeaderKey_size % 1 * uint16 + % /sH_sz subHeader_size % 4 * uint16 + % /sH_len subHeader_length + % /cmapf2_tblen total table length + % /cmapf2_lang language code (not used) + % /sHKs subHeaderKeys + + /sHK_sz 2 def + /sH_sz 8 def + dup 2 getu16a /cmapf2_tblen exch def + + dup 4 getu16a /cmapf2_lang exch def + + dup 6 256 sHK_sz mul getinterval_from_stringarray /sHKs exch def + + 0 % initialization value for /sH_len + 0 1 255 { + sHKs exch + 2 mul getu16a + 1 index % get current max + 1 index % get current subHeaderKey + lt {exch} if pop + } for + /sH_len exch def + + dup 6 256 sHK_sz mul add + cmapf2_tblen 1 index sub getinterval_from_stringarray + /sH_gIA exch def + + /cmapf2_glyph_array 0 dict def + + /.cmapf2_putGID { + /cmapf2_ch cmapf2_ch_hi 8 bitshift cmapf2_ch_lo add def + firstCode cmapf2_ch_lo le + cmapf2_ch_lo firstCode entryCount add lt + and { % true: j is inside + sH_offset idRangeOffset add % offset to gI + cmapf2_ch_lo firstCode sub 2 mul % rel. pos. in range + add 6 add % offset in sH_gIA + sH_gIA exch getu16a + dup 0 gt { % + idDelta add + cmapf2_glyph_array exch cmapf2_ch exch put + } { + pop + % cmapf2_glyph_array cmapf2_ch 0 put + } ifelse + } { % false: j is outside + % cmapf2_glyph_array cmapf2_ch 0 put + } ifelse + } def + + 16#00 1 16#ff { % hi_byte scan + /cmapf2_ch_hi exch def + sHKs cmapf2_ch_hi sHK_sz mul getu16a + /sH_offset exch def + sH_gIA sH_offset sH_sz getinterval + dup 0 getu16a /firstCode exch def + dup 2 getu16a /entryCount exch def + dup 4 gets16a /idDelta exch def + dup 6 getu16a /idRangeOffset exch def + pop + sH_offset 0 eq { + /cmapf2_ch_lo cmapf2_ch_hi def + /cmapf2_ch_hi 0 def + .cmapf2_putGID + } { + 16#00 1 16#ff { % lo_byte scan + /cmapf2_ch_lo exch def + .cmapf2_putGID + } for + } ifelse + } for + pop + cmapf2_glyph_array + } bind + 4 { % Microsoft/Adobe segmented mapping. + /etab exch def + /nseg2 etab 6 getu16a def + 14 /endc etab 2 index nseg2 getinterval_from_stringarray def + % The Apple TrueType documentation omits the 2-byte + % 'reserved pad' that follows the endCount vector! + 2 add + nseg2 add /startc etab 2 index nseg2 getinterval_from_stringarray def + nseg2 add /iddelta etab 2 index nseg2 getinterval_from_stringarray def + nseg2 add /idroff etab 2 index nseg2 getinterval_from_stringarray def + % The following hack allows us to properly handle + % idiosyncratic fonts that start at 0xf000: + pop + /firstcode startc 0 getu16a 16#ff00 and dup 16#f000 ne { pop 0 } if def + /putglyph { + glyphs code 3 -1 roll put /code code 1 add def + } bind def + % Do a first pass to compute the size of the glyphs array. + /numcodes 0 def + /glyphs 0 dict def + 0 0 2 nseg2 3 sub { + % Stack: /glyphs numglyphs i2 + /i2 exch def + /scode startc i2 getu16a def + /ecode endc i2 getu16a def + + % Bug 693538: More undocumented nonsense: in cases where scode == ecode, + % see Bug 691326 below *except*, it seems when both are zero + scode 0 eq ecode 0 eq and not { + scode ecode 1 add gt { % Bug 691326. + /ecode scode 1 add def % Acrobat does this contrary to TTF spec that + } if % requires such intervals to be ignored. + + numcodes scode firstcode sub + % Hack for fonts that have only 0x0000 and 0xf000 ranges + %dup 16#e000 ge { 255 and } if + % the previous line is obstructive to CJK fonts, so it was removed + exch sub 0 .max ecode scode sub 1 add add + exch 1 index add exch + numcodes add /numcodes exch def + } if + } for pop + + % Now fill in the array. + /numcodes 0 def /code 0 def + 0 2 nseg2 3 sub { + /i2 exch def + /scode startc i2 getu16a def + /ecode endc i2 getu16a def + % Bug 693538: see above + scode 0 eq ecode 0 eq and not { + scode ecode 1 add gt { /ecode scode 1 add def } if % Bug 691326. See above. + + numcodes scode firstcode sub + % Hack for fonts that have only 0x0000 and 0xf000 ranges + %dup 16#e000 ge { 255 and } if + % the previous line is obstructive to CJK fonts, so it was removed + exch sub 0 .max dup /code exch code exch add def + ecode scode sub 1 add add numcodes add /numcodes exch def + /delta iddelta i2 gets16a def + TTFDEBUG { + (scode=) print scode =only + ( ecode=) print ecode =only + ( delta=) print delta =only + ( droff=) print idroff i2 getu16 = + } if + idroff i2 getu16a dup 0 eq { + pop scode delta add 65535 and 1 ecode delta add 65535 and + { putglyph } for + } { % The +2 is for the 'reserved pad'. + /gloff exch 14 nseg2 3 mul add 2 add i2 add add def + 0 1 ecode scode sub { + 2 mul gloff add etab exch getu16a + dup 0 ne { delta add 65535 and } if putglyph + } for + } ifelse + } if + } for glyphs /glyphs //null def % for GC + } bind + 6 { % Single interval lookup. + dup 6 getu16a /firstcode exch def + dup 8 getu16a /ng exch def + ng dict + dup + % Stack: tab dict dict + % Fill elements firstcode .. firstcode+nvalue-1 with glyph values + 0 1 ng 1 sub { + dup firstcode add exch + 2 mul 10 add 4 index exch getu16a 3 copy put pop pop + } for pop exch pop + } bind + 12 { % Microsoft/Adobe segmented mapping. + /etab exch def + /glyphs 0 dict def + + 0 1 + etab 12 getu32a % nGroups + 1 sub { + /ind exch def + /gid etab 12 ind mul 8 add 16 add getu32a def % startGlyphID + etab 12 ind mul 16 add getu32a % startCharCode + 1 + etab 12 ind mul 4 add 16 add getu32a % endCharCode + { + gid glyphs 3 1 roll put + /gid gid 1 add def + } for + } for + glyphs /glyphs //null def % for GC + } bind +.dicttomark readonly def % cmapformats + +% <cmaptab> cmaparray <glypharray> +/cmaparray { + dup 0 getu16a cmapformats exch .knownget { + TTFDEBUG { + (cmap: format ) print 1 index 0 getu16a = flush + } if exec + } { + (Can't handle format ) print 0 getu16a = flush + mark 0 1 255 { dup } for .dicttomark + } ifelse + TTFDEBUG { + (cmap: length=) print dup length = dup === + } if +} bind def + +/get_from_stringarray % <array|string> <offset> get_from_stringarray <int> +{ 1 index type /stringtype eq { + get + } { + exch { % o () + 2 copy length ge { + length sub + } { + exch get exit + } ifelse + } forall + } ifelse +} bind def + +/getinterval_from_stringarray % <array|string> <offset> <length> getinterval_from_stringarray <string> +{ % May allocate a string in VM. + 2 index type /stringtype eq { + getinterval + } { + dup 65535 le { + string exch 0 % [] s o p + 4 3 roll { % s o p Si + dup length % s o p Si lSi + dup 4 index lt { + 3 index exch sub % s o p Si o' + exch pop 3 1 roll exch pop % s o' p + } { % s o p Si lSi + dup 3 1 roll % s o p lSi Si lSi + 4 index sub % s o p lSi Si lSi-o + 5 index length 4 index sub % s o p lSi Si lSi-o ls-p + 2 copy gt { exch } if pop % s o p lSi Si minl + dup 3 1 roll % s o p lSi minl Si minl + 5 index exch getinterval % s o p lSi minl from + 5 index 4 index 3 index % s o p lSi minl from s p minl + getinterval % s o p lSi minl from to + copy pop % s o p lSi minl + exch pop add exch pop 0 exch % s 0 p' + dup 3 index length ge { exit } if + } ifelse + } forall + pop pop % s + } { + [ 4 1 roll + { + dup 0 eq { + pop pop pop exit + } if + 3 copy + dup 65535 ge { + pop 65535 + } if + getinterval_from_stringarray 4 1 roll + 3 index length sub + exch + 3 index length add + exch + } loop + ] + } ifelse + } ifelse +} bind def + +/string_array_size % <array|string> string_array_size <int> +{ dup type /stringtype eq { + length + } { + 0 exch { length add } forall + } ifelse +} bind def + +% Each procedure in this dictionary is called as follows: +% posttable <<proc>> glyphencoding +/postformats mark + 16#00010000 { % 258 standard Macintosh glyphs. + pop MacGlyphEncoding + } + 16#00020000 { % Detailed map, required by Microsoft fonts. + dup dup type /arraytype eq { 0 get } if length 36 lt { + TTFDEBUG { (post format 2.0 invalid.) = flush } if + pop [ ] + } { + /postglyphs exch def + /post_first postglyphs dup type /arraytype eq { 0 get } if def + post_first 32 getu16 /numglyphs exch def + % Build names array in the order they occur in the 'post' table + /postpos numglyphs 2 mul 34 add def + /total_length postglyphs //string_array_size exec def + + % the number of names in a post table is not declared up front + % and there are fonts with more names than glyph indices <sigh> + % so we have to pre-process and find the highest index used. + % We start with a base value of numglyphs as it's most common, + % and we can safely have a array that's too large. + % Rather than parse out the indices twice, we store them in an + % array on the stack, which we then reuse, overwriting entries + % as we go later on. + numglyphs array numglyphs postglyphs + 0 1 numglyphs 1 sub { + dup 2 mul 34 add 2 index exch 2 //getinterval_from_stringarray exec + dup 0 get 8 bitshift exch 1 get add + dup 5 index exch + 4 -1 roll exch put + 258 sub dup 3 index gt + % if we find a reference to an index higher than the value + % already on the stack, replace the value on the stack + { 3 -1 roll pop 2 1 roll} {pop} ifelse + } for + pop + 1 add array 0 1 2 index length 1 sub { + postpos total_length ge { + % Fill the rest with .notdef + 1 2 index length 1 sub { 1 index exch /.notdef put } for + exit + } if + % No name available, /postnames will be defined as an empty + % array and the glyph won't get a name attached. + postglyphs postpos //get_from_stringarray exec + postglyphs postpos 1 add 2 index + 2 copy add total_length gt { + TTFDEBUG { (post table ends in the middle of the entry.) print flush } if + pop pop pop pop + % Fill the rest with .notdef + 1 2 index length 1 sub { 1 index exch /.notdef put } for + exit + } if + //getinterval_from_stringarray exec cvn + exch postpos add 1 add /postpos exch def + 2 index 3 1 roll + put + } for + /postnames exch def + % Some TrueType fonts converted by "Windows Type 1 Installer" have + % problematic post table including MacGlyphEncoding entries which + % should be omitted. Such extra entries in the beginning of glyphName + % array make /Encoding broken. If we find populary predefined + % ISOLatin1Encoding glyph name in the post table, empty encoding is + % returned. Some TrueType fonts for Microsoft Windows redefines + % MacGlyphEncoding glyph name out of predefined range). To permit + % such fonts, ISOLatin1Encoding is used to find broken post. Bug 689495. + /.broken_post //false def + tabdict /name .knownget { + (Windows Type 1 Installer V1.0) search { + pop pop pop + .latin1isodict postnames { + dup /.notdef ne { + 2 copy known { + TTFDEBUG { (ignore post table that redefines ISOLatin1Encoding glyph name ) print dup //== exec flush } if + /.broken_post //true def + pop exit + } if + } if + pop + } forall + pop + } { + pop + } ifelse + } if + % Loop through the array of name indices we created above. + % This loop replaces name index in the array with the name + % it references. + 0 1 2 index length 1 sub { + dup 2 index exch get dup 258 lt { + MacGlyphEncoding exch get + } { + 258 sub postnames exch get + % At least some of Microsoft's TrueType fonts use incorrect + % (Adobe-incompatible) names for some glyphs. + % Correct for this here. + postremap 1 index .knownget { exch pop } if + } ifelse + 2 index 3 1 roll + put + } for + + .broken_post { + pop + [ postnames aload length 1 roll ] + } if + } + ifelse + } bind + 16#00030000 { % No map. + pop [ ] + } bind +.dicttomark readonly def % postformats + +/call.readtable +{ .readtable +} bind def +/call.readbigtable +{ .readbigtable +} bind def + +% Each procedure in this dictionary is called as follows: +% <file> <length> -proc- <string|array_of_strings> +% Note that each table must have an even length, because of a strange +% Adobe requirement that each sfnts entry have even length. +/readtables mark + % Ordinary tables + (head) //call.readtable + (hhea) 1 index + (maxp) 1 index + (name) 1 index + (OS/2) 1 index + (post) //call.readbigtable + (vhea) //call.readtable + % Big tables + (cmap) //call.readbigtable + (GSUB) //call.readbigtable + (glyf) //call.readbigtable + (loca) 1 index + (hmtx) 1 index + (vmtx) 1 index + (cvt ) //call.readtable + (fpgm) 1 index + (prep) 1 index +.dicttomark +% Normally there would be a 'readonly' here, but the ttf2pf utility wants +% to include the 'kern' table as well, so we leave the readtables dictionary +% writable. +def % readtables + +/readtables_stripped readtables dup length dict copy +dup (loca) { .skiptable } put +dup (glyf) { .skiptable } put +def + +% Read a table as a single string. +% <file> <length> .skiptable <string> +/.skiptable { + pop pop () +} bind def + +% Read a table as a single string. +% <file> <length> .readtable <string> +/.readtable { + dup dup 1 and add string + % Stack: f len str + dup 0 4 -1 roll getinterval + % Stack: f str str1 + % Because of the absurd PostScript specification that gives an + % error for reading into an empty string, we have to check for + % this explicitly here. + 3 -1 roll exch + dup () ne { readstring } if pop pop +} bind def + +% Read a big table (one that may exceed 64K). +% <file> <length> .readbigtable <string[s]> +/.readbigtable { + dup 65400 lt { + .readtable + } { + currentuserparams /VMReclaim get -2 vmreclaim + [ 4 2 roll { + % Stack: mark ... f left + dup maxstring le { exit } if + 1 index maxstring string readstring pop 3 1 roll maxstring sub + } loop .readtable ] + exch vmreclaim + } ifelse +} bind def + +end readonly def % .loadttfontdict + +% <tab> .printtab - +/.printtab { + dup 0 4 getinterval print ( ) print + dup 8 getu32 =only ( ) print + 12 getu32 = +} bind def + +% <file> <bool> <SubfontID> .loadttfonttables - +% Pushes .loadttfontdict & scratch dict on d-stack. +% Defines f, offsets, tables, tabdict, tabs, tthdrlen. +% Skips loca and glyf if <bool> is true. +/.loadttfonttables { + .loadttfontdict begin + 40 dict begin + /SubfontID exch def + /load_stripped exch def + /f exch def + /offsets f 12 string readstring pop def + /tthdrlen offsets length def + load_stripped { readtables_stripped } { readtables } ifelse /readtables_ exch def + offsets 0 4 getinterval (ttcf) eq { + offsets 8 getu32 /num_fonts exch def + SubfontID num_fonts ge { + QUIET not { (True Type collection contains insufficient fonts.) = } if + /.loadttfonttables cvx /invalidfont signalerror + } if + f SubfontID 4 mul dup 0 ne { + () /SubFileDecode filter flushfile + } { + pop pop + } ifelse + + f 4 string readstring pop + 0 getu32 /ttc_offset exch def + + f ttc_offset SubfontID 4 mul sub 16 sub + dup 0 ne { + () /SubFileDecode filter flushfile + } { + pop pop + } ifelse + /offsets f 12 string readstring pop def + } { + SubfontID 0 gt { + QUIET not { (SubfontID > 0 with a True Type file which is not a collection.) = } if + /.loadttfonttables cvx /invalidfont signalerror + } if + /ttc_offset 0 def + } ifelse + % Peek because table counter may be incorrect. + /tables f offsets 4 getu16 16 mul string .peekstring pop def + /tabdict tables length 16 idiv dict def + % tabs = tables we want to keep, sorted by file position. + /tabs [ 0 16 tables length 1 sub { + tables exch 16 getinterval + TTFDEBUG { dup .printtab } if + dup 0 4 getinterval readtables_ 1 index known { + % put all 0 length tables at 0 to avoid overlap + 1 index 12 getu32 0 eq { 1 index 8 0 putu32 } if + tabdict exch 2 index put + } { + pop pop + } ifelse + } for ] { + exch 8 getu32 exch 8 getu32 lt + } .sort def + % In certain malformed TrueType fonts, tables overlap. + % Truncate tables if necessary. + 0 1 tabs length 2 sub { + dup tabs exch get exch 1 add tabs exch get + 1 index 8 getu32 2 index 12 getu32 add + 1 index 8 getu32 gt { + (**** Warning: ) print 1 index 0 4 getinterval print + ( overlaps ) print dup 0 4 getinterval print + (, truncating.) = flush + dup 8 getu32 2 index 8 getu32 sub + 2 index 12 3 -1 roll putu32 + } if pop pop + } for +} bind def + + + +% <file> <bool> <SubfontID> .loadwofftables - +% Pushes .loadttfontdict & scratch dict on d-stack. +% Defines f, offsets, tables, tabdict, tabs, tthdrlen. +% Skips loca and glyf if <bool> is true. +/.loadwofftables { + .loadttfontdict begin + 40 dict begin + /SubfontID exch def + /load_stripped exch def + /f exch def + % loading WOFFs "stripped" only works for .findfontvalue - we cannot + % (currently) use a stripped wOFF font + load_stripped { readtables_stripped } { readtables } ifelse /readtables_ exch def + /offsets 12 string def + /woffhdr f 44 string readstring pop def + /tthdrlen woffhdr length def + /ttc_offset 0 def + woffhdr 0 4 getinterval (wOFF) eq not + % allow loading wOFFOTTO fonts "stripped" for .findfontvalue + woffhdr 4 4 getinterval (OTTO) eq load_stripped not and or + {/.loadwofftables cvx /invalidfont signalerror} + { + offsets 0 woffhdr 4 4 getinterval putinterval + /tables f woffhdr 12 getu16 20 mul string .peekstring pop def + offsets 4 tables length 20 idiv putu16 + /tabdict tables length 20 idiv dict def + /tabs [ 0 20 tables length 1 sub + { + tables exch 20 getinterval + TTFDEBUG { dup .printtab } if + dup 0 4 getinterval readtables_ 1 index known + { + % put all 0 length tables at 0 to avoid overlap + 1 index 12 getu32 0 eq { 1 index 8 0 putu32 } if + tabdict exch 2 index put + } + {pop pop} + ifelse + }for + ] + { exch 4 getu32 exch 4 getu32 lt } .sort + def + } ifelse +} bind def + +/.file_table_pos_names +mark +/glyf 0 +/loca 0 +.dicttomark readonly def + +% - .readttdata - +% Read data. Updates offsets, tabs; stores data in tabdict. +/.readttdata { + /file_table_pos 10 dict def + /fpos tthdrlen ttc_offset add def + /sfpos offsets length tabs length 16 mul add def + offsets 4 tabs length putu16 + 0 1 tabs length 1 sub { + dup tabs exch get + dup 0 4 getinterval /tname exch def + dup length 20 eq + { + dup 4 getu32 /tpos exch def + dup 8 getu32 /tclen exch def + dup 12 getu32 /tlen exch def + } + { + dup 8 getu32 /tpos exch def + dup 12 getu32 /tlen exch def + /tclen tlen def + } ifelse + load_stripped //.file_table_pos_names tname known and { + pop + file_table_pos tname [tpos tlen tclen] put + tabdict tname () put + pop + } { + dup length 20 eq + { + 0 16 getinterval dup 8 sfpos putu32 + tabs 3 -2 roll put + } + {8 sfpos putu32 pop} + ifelse + % Skip data between the end of the previous table and + % the beginning of this one, if any. + tpos fpos gt { + load_stripped { + % 'setfileposition' is faster for skipping a big data. + f tpos setfileposition + } { + f tpos fpos sub () /SubFileDecode filter dup flushfile closefile + /fpos tpos def + } ifelse + } if + /ff + tlen tclen eq not + {f tclen () /SubFileDecode filter /FlateDecode filter} + {f tlen () /SubFileDecode filter} + ifelse + def + ff tlen readtables_ tname get exec + ff closefile + tabdict tname 3 -1 roll put + % Round up the table length to an even value. + /sfpos sfpos tlen dup 1 and add add def + } ifelse + /fpos fpos tclen add def + } for +} bind def + +% Find the string in a list of strings that includes a given index. +% <strings> <index> .findseg <string> <index'> +/.findseg { + exch { + dup length 2 index gt { exch exit } if + length sub + } forall +} bind def + +% - .makesfnts - +% Defines checksum, getloca, head, locatable, numloca, post, sfnts, upem +% Note that the 'loca' table may be out of order. +/.makesfnts { + .readttdata + /head tabdict /head get def + /post tabdict /post .knownget { + dup 0 get /post_first_part exch def + } { + //null + } ifelse def + load_stripped not { + /locatable tabdict /loca get def + /numloca + locatable dup type /stringtype eq + { length } + { 0 exch { length add } forall } + ifelse % no def yet + locatable type /stringtype eq { + /.indexloca {} def + } { + /.indexloca /.findseg load def + } ifelse + head 50 getu16 0 ne { + /getloca { + 2 bitshift locatable exch .indexloca getu32 + } def + 4 idiv 1 sub + } { + /getloca { + dup add locatable exch .indexloca getu16 dup add + } def + 2 idiv 1 sub + } ifelse def % numloca + } { + % We did not load loca, take the number of glyphs from maxp. + /numloca tabdict /maxp get 4 getu16 def + } ifelse + /sfnts [ + offsets tabs { concatstrings } forall + tabs { + 0 4 getinterval tabdict exch get + dup type /stringtype ne { aload pop } if + } forall + ] def +} bind def + +/first_post_string % - first_post_string <string> +{ + post dup type /arraytype eq { 0 get } if +} bind def + +% - .getpost - +% Uses post, defines glyphencoding +/.getpost { + /glyphencoding post //null eq { + TTFDEBUG { (post missing) = flush } if [ ] + } { + postformats first_post_string 0 getu32 .knownget { + TTFDEBUG { + (post: format ) print + first_post_string + dup 0 getu16 =only (,) print 2 getu16 = flush + } if + post exch exec + } { + TTFDEBUG { (post: unknown format ) print post 0 getu32 = flush } if [ ] + } ifelse + } ifelse + TTFDEBUG { (post=) print dup //== exec } if + def +} bind def + +% - .ttkeys <key> <value> ... +/.ttkeys { + count /ttkeycount exch def + /upem head 18 getu16 def + /FontMatrix matrix + /FontBBox [ 36 2 42 { head exch gets16 upem div } for ] + nextxuid + tabdict /name .knownget { + % Find the names from the 'name' table. + /names exch def + /FontName names 6 findname not { names 4 findname not { curxuid 16#ffffffff and 16 32 string cvrs } if } if + /fontname 1 index def + /FontInfo mark + names 0 findname { /Notice exch } if + names 1 findname { /FamilyName exch } if + names 4 findname { /FullName exch } if + names 5 findname { /Version exch } if + } { + % No name table, fabricate a FontName. + /FontName curxuid 16#ffffffff and 16 32 string cvrs + /fontname 1 index def + /FontInfo mark + } ifelse + % Stack: ... /FontInfo mark key1 value1 ... + post //null ne { + /ItalicAngle first_post_string 4 gets32 65536.0 div + /isFixedPitch first_post_string 12 getu32 0 ne + /UnderlinePosition first_post_string 8 gets16 upem div + /UnderlineThickness first_post_string 10 gets16 upem div + } if + counttomark 0 ne { .dicttomark } { pop pop } ifelse + /XUID [orgXUID 42 curxuid] + TTFDEBUG { + tabs { .printtab } forall + [ sfnts { length } forall ] //== exec + count ttkeycount sub array astore dup { //== exec } forall aload pop + } if + /sfnts sfnts +} bind def + +% ---------------- Standard TrueType font loading ---------------- % + +% - .pickcmap_with_no_xlatmap - +% Defines cmapsub, cmaptab +/.pickcmap_with_no_xlatmap { + tabdict /cmap get + % The Apple cmap format is no help in determining the encoding. + % Look for a Microsoft table. If we can't find one, + % just use the first table, whatever it is. + dup 4 8 getinterval_from_stringarray exch % () [] % the default + 0 1 2 index 2 getu16a 1 sub { % () [] i + 8 mul 4 add 1 index exch 8 getinterval_from_stringarray % () [] () + TTFDEBUG { + (cmap: platform ) print dup 0 getu16 =only + ( encoding ) print dup 2 getu16 = flush + } if + dup 0 getu16 3 eq { exch 3 -1 roll pop exit } if pop + } for + % Stack: subentry table + /cmapsub 2 index def % () [] + exch 4 getu32 1 index string_array_size 1 index sub getinterval_from_stringarray + /cmaptab exch def +} bind def + +% - .pickcmap_with_xlatmap - +% Defines cmapsub, cmaptab +/.pickcmap_with_xlatmap { + .xlatmap_dict /TrueType known not { + (Emulating a CID font with a True Type file, ) print + (the file gs/lib/xlatmap must contain /TrueType key.) = + /.pickcmap_with_xlatmap cvx /configurationerror signalerror + } if + //false + .xlatmap_dict /TrueType get + dup length 2 sub 0 exch 2 exch { % bool [] i + 2 copy get % bool [] i () + (.) search { % bool [] i post match pre + cvi exch pop exch cvi % bool [] i PlatID SpecID + } { + (gs/lib/xlatmap containg a record with an invalid (PlatformID.SpecificID)) = + /.pickcmap_with_xlatmap cvx /configurationerror signalerror + } ifelse + TTFDEBUG { + (Seeking a cmap for platform=) print 1 index =only ( encoding=) print dup = + } if + tabdict /cmap get % bool [] i PlatID SpecID (cmap) + dup /cmaptab exch def % temporary + 0 1 2 index 2 getu16a 1 sub { % bool [] i PlatID SpecID (cmap) j + 8 mul 4 add 1 index exch 8 + getinterval_from_stringarray % bool [] i PlatID SpecID (cmap) (cmapsub) + TTFDEBUG { + (cmap: platform ) print dup 0 getu16 =only + ( encoding ) print dup 2 getu16 = flush + } if + dup 0 getu16 4 index eq { + dup 2 getu16 3 index eq { % bool [] i PlatID SpecID (cmap) (cmapsub) + TTFDEBUG { + (Choosen a cmap for platform=) print 3 index =only + ( encoding=) print 2 index = + } if + /cmapsub 1 index def + dup 4 getu32 % bool [] i PlatID SpecID (cmap) (cmapsub) p + cmaptab 1 index getu16a % get cmap format + 8 lt { % length for traditional 16bit format 0, 2, 4, 6 + cmaptab 1 index 2 add getu16a + } { % length for advanced 32bit format 8, 10, 12 + cmaptab 1 index 4 add getu32a + } ifelse % bool [] i PlatID SpecID (cmap) (cmapsub) p l + cmaptab 3 1 roll getinterval_from_stringarray + /cmaptab exch def % bool [] i PlatID SpecID (cmap) (cmapsub) + 5 index 5 index 1 add get % bool [] i PlatID SpecID (cmap) (cmapsub) /Decoding + /Decoding exch def % bool [] i PlatID SpecID (cmap) (cmapsub) + 7 -1 roll pop //true 7 1 roll % true [] i PlatID SpecID (cmap) (cmapsub) + } if + } if + pop % true [] i PlatID SpecID (cmap) + 5 index { exit } if + } for % bool [] i PlatID SpecID (cmap) + pop pop pop pop % bool [] + 1 index { exit } if + } for % bool [] + pop % bool + not { + QUIET not { (True Type font doesn't contain a charset listed in gs/lib/xlatmap.) = } if + /.pickcmap_with_xlatmap cvx /invalidfont signalerror + } if % +} bind def + +% - .pickcmap - +% Defines cmapsub, cmaptab +/.pickcmap { + % Currently we use xlatmap only for emulation CIDFontType 2 with + % a disk True Type font files, and use load_stripped + % to check this regime. We would like to do so + % while emulating a Type 42, but first the old code + % about handling them to be changed + % with adding a handling of a Decoding. + % fixme : A correct way to fix this is to implenent + % the Type 42 emulation with gs_fntem.ps . + % Also note that PDF embedded fonts probably don't need a xlatmap - + % see PDF spec, "Encodings for True Type fonts". + load_stripped { + //.pickcmap_with_xlatmap exec + } { + //.pickcmap_with_no_xlatmap exec + } ifelse +} bind def + +% <glyph> .nname <_name> +/.nname { + =string cvs (_) exch concatstrings cvn +} bind def + + +% - .charkeys /CharStrings <charstrings> /Encoding <encoding> +% Resets glyphencoding +/.charkeys { + TTFDEBUG { + (glyphencoding: length=) print glyphencoding dup length = === flush + } if + % Hack: if there is no usable post table but the cmap uses + % the Microsoft Unicode encoding, use ISOLatin1Encoding. + % if 'post' presents, .charkeys computes (with dropping minor details) : + % CharStrings = glyphencoding^-1 + % Encoding = cmap*glyphencoding + % because 'post' maps glyph indices to glyph names. + % Otherwise .charkeys must compute (with dropping same details) : + % CharStrings = glyphencoding^-1 * cmap + % Encoding = glyphencoding + % because glyphencoding is stubbed with an encoding, + % which maps char codes to glyph names. + glyphencoding length 0 eq { + /have_post //false def + cmapsub 0 4 getinterval <00030001> eq { + PDFDEBUG { (No post but have cmap 3.1, so use ISOLatin1Encoding) = } if + /glyphencoding ISOLatin1Encoding dup length array copy def + } { + PDFDEBUG { (No encoding info, use .GS_extended_SymbolEncoding) = } if + /glyphencoding /.GS_extended_SymbolEncoding findencoding dup length array copy def + } ifelse + } { + /have_post //true def + } ifelse + % If necessary, fabricate additional glyphencoding entries + % to cover all of loca + glyphencoding length numloca lt { + /glyphencoding numloca array + glyphencoding length dup 1 sub 0 1 3 2 roll { + dup glyphencoding exch get + 3 index 3 1 roll put + } for + % /glyphencoding <newarray> <glyphencoding length> + 1 numloca 1 sub { + 1 index exch dup .nname put + } for + def + } if + + /cmapa cmaptab cmaparray def + % Some badly designed Chinese fonts have a post table + % in which all glyphs other than 0 are named .null. + % Use CharStrings to keep track of the reverse map from + % names to glyphs, and don't let any name be used for + % more than one glyph. + /CharStrings glyphencoding dup length 1 add dict % +1 for .notdef + 0 1 3 index length 1 sub { + % Stack: glyphencoding dict index + dup 3 index 1 index get + have_post not { + exch + cmapa exch .knownget not { + 0 % a stub for a while. Must skip the entry. + } if + exch + } if + 3 index 1 index known + { % The same name maps to more than one glyph. Change the name. + % No special treatment for /.notdef glyph. Bug 689408. + pop .nname 3 index 2 index 2 index put + 2 index exch 3 -1 roll put + } { + 3 index exch 3 -1 roll put % unique name + pop + } ifelse + } for exch pop + % If there is no .notdef entry, map it to glyph 0. + dup /.notdef known not { dup /.notdef 0 put } if + + TTFDEBUG { + (CharStrings:)= dup { exch =string cvs print ( ) print //== exec } forall + } if + + % Provide all known aliases for each glyph + cmapsub 0 4 getinterval <00030001> eq % is the cmap table a unicode one? + cmapa //ReverseAdobeGlyphList //AdobeGlyphList + { % CharStrings(dict) isunicode(boolean) cmap(dict) RAGL(dict) gname(name) codep(integer) + exch + dup 6 index exch .knownget + { % CharStrings(dict) isunicode(boolean) cmap(dict) RAGL(dict) codep(integer) gname(name) gindex(integer) + 3 index 3 index .knownget + { % CharStrings(dict) isunicode(boolean) cmap(dict) RAGL(dict) codep(integer) gname(name) gindex(integer) gnames(array) + { % CharStrings(dict) isunicode(boolean) cmap(dict) RAGL(dict) codep(integer) gname(name) gindex(integer) gname(name) + TTFDEBUG { (\n1 setting alias: ) print dup ==only + ( to be the same as ) print 2 index //== exec } if + + 7 index 2 index 3 -1 roll exch //.growput superexec + } forall + pop pop pop + } + { + pop pop + } ifelse + } + { % CharStrings(dict) isunicode(boolean) cmap(dict) RAGL(dict) gname(name) codep(integer) + exch + % Only do this for Unicode cmap table + 4 index + { + dup 4 index exch .knownget + { % CharStrings(dict) isunicode(boolean) cmap(dict) RAGL(dict) gname(name) codep(integer) gindex(integer) + exch pop + TTFDEBUG { (\n2 setting alias: ) print 1 index ==only + ( to use glyph index: ) print dup //== exec } if + 5 index 3 1 roll //.growput superexec + //false + } + { + //true + }ifelse + } + { + //true + } ifelse + + { % CharStrings(dict) isunicode(boolean) cmap(dict) RAGL(dict) gname(name) codep(integer) + 16 4 string cvrs dup length neg 7 add (uni0000) dup + 4 -2 roll exch putinterval cvn 3 index 1 index .knownget + { % CharStrings(dict) isunicode(boolean) cmap(dict) RAGL(dict) gname(name) codep(integer) gindex(integer) + TTFDEBUG { (\3 nsetting alias: ) print 1 index ==only + ( to be index: ) print dup //== exec } if + exch pop 5 index 3 1 roll //.growput superexec + } + { + pop pop + } ifelse + } if + } ifelse + } forall + pop pop pop + + readonly + + /Encoding [ + have_post { + 0 1 255 { + cmapa exch .knownget not { 0 } if + glyphencoding dup length + 2 index le { + pop pop /.notdef + } { + exch get + } ifelse + } for + } { + glyphencoding dup length 256 gt { 0 256 getinterval } if + aload pop + counttomark 256 exch sub { /.notdef } repeat + } ifelse + ] + TTFDEBUG { (Encoding: ) print dup === flush } if +} bind def + +% to be removed 9.09...... +currentdict /postalias undef +% .....to be removed 9.09 + +% <file> .loadttfont <type42font> +/.loadttfont { + TTFDEBUG { (.loadttfont) = } if + //false 0 .loadttfonttables + .makesfnts + .getpost + .pickcmap + mark + % if we're loading to substitute for TTF in a PDF, + % load the font the "PDF way" + /prebuilt_encoding where + {pop .pdfcharkeys} + {.charkeys} ifelse + .ttkeys + /FontType 42 + /PaintType 0 + TTFDEBUG { + (numloca=) print numloca = + } if + .dicttomark + end end dup /FontName get exch definefont +} bind def + +% <file> .loadwofffont <type42font> +/.loadwofffont +{ + TTFDEBUG { (.loadwofffont) = } if + //false 0 .loadwofftables + .makesfnts + .getpost + .pickcmap + mark + .charkeys + .ttkeys + /FontType 42 + /PaintType 0 + TTFDEBUG { + (numloca=) print numloca = + } if + .dicttomark + end end dup /FontName get exch + definefont +} bind def + + +% ---------------- CIDFontType 2 font loading ---------------- % + +% Fill a string with sequential CIDs starting from the initial value. +% <string> <value> .fill_identity_cmap <string> +/.fill_identity_cmap { % () v + 1 index length 2 sub % () v n-2 + 0 2 3 2 roll { % () v 0 2 n-1 + 3 copy exch % () v i () i v + -8 bitshift % () v i () i v>>8 + put % () v i + 3 copy 1 add % () v i () v i+1 + exch 255 and % () v i () i+1 v&255 + put % () v i + pop 1 add % () v+1 + } for + pop +} bind def + +% <CIDSystemInfo dict> <dict> .definettcidfont <font> +/.definettcidfont { + dup begin + /CIDFontName fontname def + /CIDFontType 2 def + /CIDSystemInfo 4 -1 roll def + /CharStrings mark /.notdef 0 .dicttomark def + % The cmap isn't of any use even if it is present. + % Just construct an identity CIDMap covering all the glyphs. + + /CIDCount numloca % Wrong if a CIDFontType2 embedded into PDF with a non-Identity CIDToGIDMap. + def % processCIDToGIDMap may replace. + /CIDMap numloca maxstring le { + % Use a single string. + numloca 2 mul string 0 .fill_identity_cmap + } { + % We must use 2 strings. + maxstring 2 mul string 0 .fill_identity_cmap + numloca maxstring sub 2 mul string maxstring .fill_identity_cmap + 2 array astore + } ifelse + def + + /GDBytes 2 def + end + + end end dup /CIDFontName get exch /CIDFont defineresource +} bind def + +% <CIDSystemInfo dict> <file> <Substite name> .loadttcidfont <cidtype2font> +/.loadttcidfont { + exch + //false 0 .loadttfonttables + .makesfnts + % CIDFontType2 fonts don't have a cmap: they are indexed by CID. + mark + .ttkeys + .dicttomark dup % convert keys to dict and copy dict + 3 -1 roll % Bring PDF substitute name to top of stack + + dup + /fontname exch def + /FontName exch put % replace any definition of /FontName + .definettcidfont +} bind def + +% <file> <SubfontID> .load_tt_font_stripped <font_data> +% The font_data includes sfnts, NumGlyphs, TT_cmap, file_table_pos, Decoding. +% CIDMap to be created later from TT_cmap. +/.load_tt_font_stripped { + //true exch .loadttfonttables + .makesfnts + .pickcmap + mark + .ttkeys + /NumGlyphs numloca + /TT_cmap cmaptab cmaparray + /file_table_pos file_table_pos + /Decoding Decoding + .dicttomark + end end +} bind def + +/.load_woff_for_cid { + //false exch .loadwofftables + .makesfnts + % we have to set load_stripped here so + % .pickcmap will follow the right logic + % for emulating a CIDFont + /load_stripped //true def + .pickcmap + /load_stripped //false def + mark + .ttkeys + /NumGlyphs numloca + /TT_cmap cmaptab cmaparray +% /file_table_pos file_table_pos + /Decoding Decoding + .dicttomark + end end +} bind def + +% ---------------- PDF TrueType font loading ---------------- % + +% Strictly speaking, this code should be loaded only if we have a PDF +% interpreter, but it's so closely tied to the rest of the code in this +% file that we always include it. + +% <plat+enc> .findcmap <subtable> true +% <plat+enc> .findcmap false +/.findcmap { + //false exch tabdict /cmap get + % Some fonts have multiple cmaps with the same platform and + % encoding. Use the first one we find. + 0 1 2 index 2 getu16a 1 sub { + % Stack: false plat+enc cmap index + 8 mul 4 add 1 index exch 8 getinterval_from_stringarray + dup 0 4 getinterval 3 index eq { + 4 getu32 1 index exch 1 index string_array_size 1 index sub getinterval_from_stringarray + 4 -1 roll not 4 2 roll exit + } if pop + } for + % Stack: false plat+enc cmap || subtable true plat+enc cmap + pop pop +} bind def + +% Build .symbol_list for .pdfcharkeys . +% It is a dictionary containing all SymbolEncoding glyph names +% and random names for filling gaps in the character code range. +/.symbol_list 256 dict def +{ + =string 0 (x) 0 get put + /SymbolEncoding .findencoding + 0 1 255 { + dup 2 index exch get + dup /.notdef eq { + pop dup + =string 1 3 getinterval cvs length 1 add + =string exch 0 exch getinterval cvn + } if + exch //.symbol_list 3 1 roll put + } for + pop +} bind exec + +% Create .GS_extended_SymbolEncoding as inverse of .symbol_list . +{ + /.GS_extended_SymbolEncoding 256 array + //.symbol_list { + exch 2 index 3 1 roll put + } forall + .defineencoding +} bind exec + +/.hexdigits (0123456789ABCDEF) def + +/.is_hex_digit { % <int> .is_hex_digit <bool> + dup 48 ge exch + dup 57 le exch + dup 65 ge exch + 70 le and + 3 1 roll + and or +} bind def + +/.popfex { pop //false exit } bind def +/.pop3ex { pop pop pop exit } bind def + +/.addglyph { % <dict> <name> <glyph#> .addglyph - + 1 index .namestring % d n g s + dup length 7 eq { + % Bug688467.ps doesn't work if the uniXXXX mapping is allowed with any cmap. + % Allow it with cmap 3.1 only. + currentdict /.allow_uniXXXX_glyph_names .knownget not { //false } if + } { //false + } ifelse % d n g s b + { + % An undocumented Adobe feature (not sure) : + % if the name is uniXXXX, obtain Unicode code from it. + % See bug 688946. + TTFDEBUG { (Try uniXXXX:) print dup print } if + { dup 0 get 117 ne //.popfex if % u + dup 1 get 110 ne //.popfex if % n + dup 2 get 105 ne //.popfex if % i + dup 3 get //.is_hex_digit exec not //.popfex if + dup 4 get //.is_hex_digit exec not //.popfex if + dup 5 get //.is_hex_digit exec not //.popfex if + dup 6 get //.is_hex_digit exec not //.popfex if + dup 3 1 getinterval .hexdigits exch search pop length exch pop exch pop 12 bitshift exch + dup 4 1 getinterval .hexdigits exch search pop length exch pop exch pop 8 bitshift exch + dup 5 1 getinterval .hexdigits exch search pop length exch pop exch pop 4 bitshift exch + dup 6 1 getinterval .hexdigits exch search pop length exch pop exch pop exch pop + add add add + + cmapencoding exch .knownget not { 0 } if + dup 0 eq //.popfex if + + TTFDEBUG { ( index=) print dup =string cvs print } if + exch pop + put //true exit + } loop + TTFDEBUG { ()= } if + } { + pop //false + } ifelse + not { % d n g + { + cmapencoding exch .knownget not { 0 } if + dup 0 eq //.pop3ex if + 3 copy pop known //.pop3ex if + put exit + } loop + } if +} bind def + +% <chartoglyphmap> <subcmap> <AGL> .pdfmapchars /CharStrings <charstrings> +/.pdfmapchars { + exch cmaparray /cmapencoding exch def % c2g + /CharStrings 0 dict % c2g /CS <<>> + + % Add glyphs of <AGL>*<subcmap> : + 3 2 roll { % /CS <<>> v + dup type /arraytype eq { % /CS <<>> /name [] + { 3 copy //.addglyph exec + pop + } forall + } { + 3 copy //.addglyph exec pop + } ifelse + pop + } forall + % Add glyphs of 'post' with lower priority : + 0 1 glyphencoding length 1 sub { + dup glyphencoding exch get exch + dup 0 ne { + 3 copy pop known not { + 3 copy put + } if + } if + pop pop + } for + + % Finally, add glyphs from the prebuilt_encoding with lowest priority + % this is a catch-all for poorly matched font/PDF combos + 3 2 roll { % /CS <<>> v + dup type /arraytype eq { % /CS <<>> /name [] + { 3 copy //.addglyph exec + pop + } forall + } { + 3 copy //.addglyph exec pop + } ifelse + pop + } forall + + dup /.notdef 0 put + +} bind def + +% <subtable> .pdfmapsymbolic /Encoding [] /CharStrings <<>> +/.pdfmapsymbolic { + //true /.render_notdef gput + cmaparray + dup length 1 add dict begin + [ 64 { /.notdef /.notdef /.notdef /.notdef } repeat ] + exch { % [] char glyph + exch + dup 255 gt { + 255 and + 2 index 1 index get /.notdef ne { + pop pop + //false + } { + //true + } ifelse + } { + //true + } ifelse { + dup (01234567) cvs cvn % glyph char /char + 3 1 roll % /char glyph char + 3 index exch % /char glyph [] char + 3 index put % /char glyph + def % - + } if + } forall + /.notdef 0 def + /Encoding exch + /CharStrings currentdict end +} bind def + +% - .pdfcharkeys /CharStrings <charstrings> /Encoding <encoding> +/.pdfcharkeys { + % The following algorithms are per the PDF 1.7 Reference. + TTFDEBUG { (.pdfcharkeys beg) = } if + + % if the flags say symbolic, *and* the font contains a symbol + % cmap table, ignore Encoding if there is one, treat as symbolic. + % If the flags say symbolic, and the font doesn't have a symbol cmap + % and we have an Encoding, treat it as non-symbolic + % if we don't have an Encoding, try the MacRoman cmap table. + % Finally, if none of that works, remove the Encoding, and treat it + % as non-symbolic. + is_symbolic { + <00030000> .findcmap { //true } { prebuilt_encoding //null eq { <00010000> .findcmap}{//false}ifelse } ifelse { + .pdfmapsymbolic + /prebuilt_encoding //null def + //false + } { + /prebuilt_encoding //null def + //true + } ifelse + } { + //true + } + ifelse + { + <00030001> .findcmap { + prebuilt_encoding //null ne { + TTFDEBUG { (Using cmap 3.1 with prebuilt_encoding for non-symbolic.) = } if + //true /.render_notdef gput + % The character code in /prebuilt_encoding[] is not guaranteed to be + % compatible with the Microsoft UCS2 TrueType cmap subtable. + % If the glyphname is known by AdobeGlyphList, the charcode for the glyph + % is replaced by UCS2 charcode from AdobeGlyphList. Otherwise it is left + % as in /prebuilt_encoding[]. /.pdfmapchars should dredge them. + + /.allow_uniXXXX_glyph_names //true def + AdobeGlyphList prebuilt_encoding .invert_encoding dup { % <<AGL>> <<pbe>> <glyphname> <pbecode> + pop % <<AGL>> <<pbe>> <glyphname> + TTFDEBUG { (check glypname /) print dup =only flush } if + 2 index 1 index .knownget { % <<AGL>> <<pbe>> <glyphname> <AGLcode> + 2 index 3 1 roll % <<AGL>> <<pbe>> <<pbe>> <glyphname> <AGLcode> + TTFDEBUG { ( redefine codepoint by AdobeGlyphList, ) print dup //== exec flush } if + put % <<AGL>> <<pbe>> + } { % <<AGL>> <<pbe>> <glyphname> + TTFDEBUG { ( unknown glyphname, leave as it is ) = flush } if + pop % <<AGL>> <<pbe>> + } ifelse + } forall + exch pop % <<pbe>> + TTFDEBUG { dup (<<\n) print { exch ( ) print =only (\t) print //== exec } forall (>>\n) print flush } if + exch AdobeGlyphList + .pdfmapchars + /Encoding prebuilt_encoding + } { + % Likely this branch is now obsolete. + TTFDEBUG { (Using cmap 3.1 for non-symbolic.) = } if + 0 dict exch + AdobeGlyphList .pdfmapchars + /Encoding /WinAnsiEncoding .findencoding + % WinAnsiEncoding is just a stub here. + % It will be replaced with one from font resource, + % because PDF spec requires it. + } ifelse + } { + <00010000> .findcmap { + TTFDEBUG { (Using cmap 1.0 for non-symbolic.) = } if + 0 dict exch + .romanmacdict .pdfmapchars + /Encoding + prebuilt_encoding //null ne { + prebuilt_encoding + } { + /MacRomanEncodingForTrueType .findencoding + } ifelse + } { + % Apply the default algorithm for using the 'post'. + .charkeys + % But use PDF encoding when available. + prebuilt_encoding //null ne { + pop prebuilt_encoding + } if + } ifelse + } ifelse + } if + TTFDEBUG { (.pdfcharkeys end) = } if +} bind def + +% <file> <is_symbolic> <Encoding|null> <FontName> .loadpdfttfont <type42font> +/.loadpdfttfont { + TTFDEBUG { (.loadpdfttfont FontName=) print dup == } if + /font_name gput + TTFDEBUG { (.loadpdfttfont Encoding=) print dup //== exec } if + /prebuilt_encoding gput % for .pdfcharkeys + /is_symbolic gput + % init key for whether to display the TTF notdef + //false /.render_notdef gput + //false 0 .loadttfonttables + .makesfnts + tabdict /cmap known not { + ( **** Warning: Embedded TT font lacks required cmap table. Using identity cmap.\n) + pdfformaterror + % Unknown (i.e. not 0 ) language ID brings in post table. + % Fields: cmap_version, number_of_subtables, + % plarform_id, encoding_id, offset, + % format, subtable_length, language, + % 256 bytes of identity mapping. + tabdict /cmap + < 0000 0001 + 0001 D00D 0000000c + 0000 0106 0000 + 00 01 02 03 04 05 06 07 08 09 0a 0d 0c 0d 0e 0f + 10 11 12 13 14 15 16 17 18 19 1a 1d 1c 1d 1e 1f + 20 21 22 23 24 25 26 27 28 29 2a 2d 2c 2d 2e 2f + 30 31 32 33 34 35 36 37 38 39 3a 3d 3c 3d 3e 3f + 40 41 42 43 44 45 46 47 48 49 4a 4d 4c 4d 4e 4f + 50 51 52 53 54 55 56 57 58 59 5a 5d 5c 5d 5e 5f + 60 61 62 63 64 65 66 67 68 69 6a 6d 6c 6d 6e 6f + 70 71 72 73 74 75 76 77 78 79 7a 7d 7c 7d 7e 7f + 80 81 82 83 84 85 86 87 88 89 8a 8d 8c 8d 8e 8f + 90 91 92 93 94 95 96 97 98 99 9a 9d 9c 9d 9e 9f + a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ad ac ad ae af + b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bd bc bd be bf + c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cd cc cd ce cf + d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da dd dc dd de df + e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea ed ec ed ee ef + f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fd fc fd fe ff + > readonly put + } if + .getpost + .pickcmap + mark + .pdfcharkeys + .ttkeys + /FontType 42 + /PaintType 0 + /.render_notdef .render_notdef + TTFDEBUG { + (numloca=) print numloca = + } if + .dicttomark + dup /FontName font_name put % replace any definition of /FontName + end end + .completefont +} bind def diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_typ32.ps b/Master/tlpkg/tlgs/Resource/Init/gs_typ32.ps new file mode 100644 index 00000000000..1ed1a2c0eeb --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_typ32.ps @@ -0,0 +1,133 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Initialization file for Type 32 fonts. + +% ------ Type 32 fonts ------ % + +% We need LanguageLevel 2 or higher in order to have defineresource. +languagelevel dup 2 .max .setlanguagelevel + +/BitmapFontInit mark + +/.makeglyph32 systemdict /.makeglyph32 get +systemdict /.makeglyph32 .undef + +/addglyph { % ([wx wy llx lly urx ury] | + % [w0x w0y llx lly urx ury w1x w1y vx vy]) + % <bitmap> <cid> <type32font> addglyph - + 1 index dup 2 index .removeglyphs + 22 string .makeglyph32 + % Stack: metrics bitmap cid font metstr + 3 index () ne { + % Use G4 encoding to compress the bitmap. + % Define a string large enough to hold the metrics, + % an uncompressed bitmap (worst case = 5x expansion), + % and the 2 RTC codes (3 bytes). + dup length 4 index length 5 mul add 10 add + 65535 .min string + % Stack: metrics bitmap cid font metstr buffer + dup 0 3 index putinterval + dup 2 index length 1 index length 1 index sub getinterval + % Stack: metrics bitmap cid font metstr buffer bitbuf + mark /Columns 8 index dup 4 get exch 2 get sub + /Rows 10 index dup 5 get exch 3 get sub + /K -1 /EndOfBlock //true /BlackIs1 //true + .dicttomark /CCITTFaxEncode filter + % Stack: metrics bitmap cid font metstr buffer filter + dup 6 index writestring closefile + % Find the end of the data by scanning backwards for the RTC. + % There are 2 RTCs x 12 bits = 3 bytes to remove. + { + dup dup length 1 sub get 0 ne { exit } if + 0 1 index length 1 sub getinterval + } loop + 0 1 index length 3 sub getinterval + exch pop % metstr + } if + 1 index /CharStrings get 3 index 3 -1 roll put + pop pop pop pop +} obind + +/removeall { % <type32font> removeall - + 0 65535 2 index removeglyphs pop +} obind + +/.removeglyphs systemdict /.removeglyphs get +systemdict /.removeglyphs .undef + +/removeglyphs { % <cid_min> <cid_max> <type32font> .removeglyphs - + 3 copy .removeglyphs + dup /CharStrings get dup { + % Stack: cidmin cidmax font CharStrings cid bitmap + pop dup 5 index ge { dup 4 index le { 2 copy undef } if } if pop + } forall pop pop pop pop +} obind + +.dicttomark /ProcSet defineresource pop + +/.cidfonttypes where { pop } { /.cidfonttypes 6 dict def } ifelse +.cidfonttypes begin + +4 % CIDFontType 4 = FontType 32 +{ dup /FontType 32 .forceput + dup /CharStrings 20 dict .forceput + 1 index exch .buildfont32 exch pop +} bind def + +end % .cidfonttypes + +% Define the BuildGlyph procedure. +% Since Type 32 fonts are indexed by CID, there is no BuildChar procedure. +% The name %Type32BuildGlyph is known to the interpreter. +(%Type32BuildGlyph) cvn { % <font> <cid> %Type32BuildGlyph - + 1 index /CharStrings get + % Stack: font cid CharStrings + dup 2 index .knownget { + exch pop + } { + 0 .knownget not { + exch pop % Stack: cid + .getshowoperator /invalidfont signalerror + } if + } ifelse + % Stack: font cid cstr + dup //.getmetrics32 % use // because of .undef below + dup 14 gt { + 8 index 8 index 13 3 roll setcachedevice2 + } { + 4 index 4 index 9 3 roll setcachedevice + } ifelse + % Stack: font cid cstr w h nmetrics llx lly + 6 -1 roll 4 -1 roll 1 index length 1 index sub getinterval + % Stack: font cid w h llx lly bitstr + dup () eq { + pop pop pop + } { + mark /Columns 6 index /Rows 7 index /K -1 /EndOfBlock //false /BlackIs1 //true + .dicttomark /CCITTFaxDecode filter 4 index 4 index //true + % Stack: font cid w h llx lly filter w h //true + [ 1 0 0 1 11 -2 roll exch neg exch neg ] 5 -1 roll imagemask + } ifelse + pop pop pop pop +} .bind def + +systemdict /.getmetrics32 .undef + +buildfontdict 32 /.buildfont32 cvx put + +32 dup /FontType defineresource pop + +.setlanguagelevel diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_typ42.ps b/Master/tlpkg/tlgs/Resource/Init/gs_typ42.ps new file mode 100644 index 00000000000..fc4f3fad94a --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_typ42.ps @@ -0,0 +1,59 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Type 42 font support code. + +% Here are the BuildChar and BuildGlyph implementation for Type 42 fonts. +% The names %Type42BuildChar and %Type42BuildGlyph are known to the +% interpreter. The real work is done in an operator: +% <font> <code|name> <name> <glyphindex> .type42execchar - + +(%Type42BuildChar) cvn % <font> <code> %Type42BuildChar - + { 1 index /Encoding get 1 index get .type42build + } bind def +(%Type42BuildGlyph) cvn % <font> <name> %Type42BuildGlyph - + { dup .type42build + } bind def +/.type42build % <font> <code|name> <name> .type42build - + { 2 index begin + dup CharStrings exch .knownget not + { 2 copy eq { exch pop /.notdef exch } if + QUIET not + { (Substituting .notdef for ) print + =string cvs print ( in the font ) print + 1 index /FontName get = flush + } + { pop } + ifelse + /.notdef CharStrings /.notdef get + } if + end .type42execchar + } bind def + +% Register the font type for definefont. +buildfontdict 42 + { % check for bogus sfnts -- this happens in Genoa FTS 421-01.ps + dup /sfnts get 0 get length 14 lt { % smallest valid sfnts is 14 bytes + % HACK: Add a BuildGlyph and make this a Type 3 font instead + dup /FontType 3 put + dup /BuildGlyph { + 1 index /CharStrings get exch 2 copy known not { pop /.notdef } if get exec + } bind put + //.buildfont3 exec + } { + systemdict /.buildfont42 get exec + } ifelse + } bind +put diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_type1.ps b/Master/tlpkg/tlgs/Resource/Init/gs_type1.ps new file mode 100644 index 00000000000..772bb7163ff --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_type1.ps @@ -0,0 +1,303 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Type 1 font support code. + +% The standard representation for PostScript compatible fonts is described +% in the book "Adobe Type 1 Font Format", published by Adobe Systems Inc. + +/t1_glyph_equivalence mark % Exported for pf2afm.ps + /Odblacute /Ohungarumlaut + /Udblacute /Uhungarumlaut + /odblacute /ohungarumlaut + /udblacute /uhungarumlaut +.dicttomark def + +% Define an augmented version of .buildfont1 that inserts UnderlinePosition +% and UnderlineThickness entries in FontInfo if they aren't there already, +% and FontBBox isn't degenerate. +% (This works around the incorrect assumption, made by many word processors, +% that these entries are present in the built-in fonts.) +% Also add alternative names to some glyphs. +/.buildfont1 + { + .currentglobal 3 1 roll + dup .gcheck .setglobal + dup .fontbbox { + pop pop pop pop + dup /FontInfo known not + { .growfontdict dup /FontInfo 2 dict put } + if + dup dup /FontInfo get dup dup + /UnderlinePosition known exch /UnderlineThickness known and + { pop pop % entries already present + } + { dup length 2 add dict .copydict + dup /UnderlinePosition known not + { dup /UnderlinePosition 3 index /FontBBox get + 1 get 2 div put % 1/2 the font descent + } + if + dup /UnderlineThickness known not + { dup /UnderlineThickness 3 index /FontBBox get + dup 3 get exch 1 get sub 20 div put % 1/20 the font height + } + if + 1 index /FontInfo get wcheck not { readonly } if + /FontInfo exch put + } + ifelse + } if + + % We want to skip this process if we've already done it, and + % not do it for embedded fonts. + dup /.AGLprocessed~GS known not 1 index /PathLoad known and + { + dup /CharStrings get + % Provide all known aliases for each glyph if + % substitution is allowed (pf2afm.ps has code + % to disables it by modifying t1_glyph_equivalence). + t1_glyph_equivalence length 0 ne + { + % 16 byte scratch string + % 16 bytes is arbitrary, but should be large enough to hold any "uniXXXX" style name + //ReverseAdobeGlyphList //AdobeGlyphList 3 -1 roll + % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) + dup + { % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) gname cstring + exch dup % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname gname + 4 index exch .knownget + { //true} + { % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname + dup length 16 gt + { //false } + { + % if we couldn't derive the code point from the AGL, we might derive it + % from a formatted "uniXXXX" name. + dup <00000000000000000000000000000000> cvs dup flush (uni) anchorsearch + { + % as luck would have it, we can just replace the "uni" with "16#" + % to get something we can convert to a number + pop pop dup 0 (16#) putinterval {cvi} .internalstopped + { pop //false} + { % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname cpoint + dup 5 index exch known + { //true } + { pop //false } + ifelse + } ifelse + } + { pop pop //false} + ifelse + } ifelse + } ifelse + + { + % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname cpoint + % loop through the array of names for this codepoint + % if the CharStrings dict doesn't contain an entry for the name + % create one. + 5 index exch .knownget + { % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname aglnames(array) + { % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname aglname + dup 4 index exch known not + { % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname aglname + CFFDEBUG { (\nsetting alias: ) print dup ==only + ( to be the same as glyph: ) print 1 index //== exec } if + 3 index exch 3 index //.growput superexec + % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname + } + {pop} ifelse + } forall + pop pop + } + { + pop pop pop + } ifelse + } + { + % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname + pop pop + } ifelse + } forall + 3 1 roll pop pop + } if + pop + dup /.AGLprocessed~GS //true //.growput superexec + } if + + %% We need to excute the C .buildfont1 in a stopped context so that, if there + %% are errors we can put the stack back sanely and exit. Otherwise callers won't + %% be able to execute this redefinied .buildfont1 in a stopped context and still + %% usefully continue (because the stack will be altered, which it shold not be). + %% + %% Uncovered working on bug #696306 and fixed as part of that bug. + %% + {//.buildfont1} stopped + 4 3 roll .setglobal + {//.buildfont1 $error /errorname get signalerror} if + } bind def + +% If the diskfont feature isn't included, define a dummy .loadfontdict. +/.loadfontdict where + { pop } + { /.loadfontdict 0 dict readonly def } +ifelse +/.loadfontfile % <file> .loadfontfile - + { mark exch + DISKFONTS { .loadfontdict begin } if + % In order to load fonts reliably, we should push systemdict + % here. However, Ed Taft says that Adobe implementations + % push userdict and nothing else! + % We really would just like systemdict on the stack, + % but fonts produced by Fontographer require a writable dictionary. + % However, we can't use any of the other well-known dictionaries + % (such as userdict), since the whole point of pushing systemdict + % is to make sure that nothing important has been redefined. + /userdict .systemvar begin + % We can't just use `run', because we want to check for .PFB files. + currentpacking + { //false setpacking .loadfont1 //true setpacking } + { .loadfont1 } + ifelse end + { stop } if + DISKFONTS { end } if + cleartomark + } bind def + % container for CloseSource flag (default //true to prevent buildup of file handles) + /closesourcedict mark + /CloseSource //true + .dicttomark readonly def +/.loadfont1 { % <file> .loadfont1 <errorflag> + { % We would like to use `false /PFBDecode filter', + % but this occasionally produces a whitespace character as + % the first of an eexec section, so we can't do it. + % Also, since the real input file never reaches EOF if we are using + % a PFBDecode filter (the filter stops just after reading the last + % character), we must explicitly close the real file in this case. + % Since the file might leave garbage on the operand stack, + % we have to create a procedure to close the file reliably. + dup read not { -1 } if + 2 copy unread 16#80 eq { + dup //closesourcedict //true /PFBDecode filter cvx + exch .currentresourcefile eq { + dup /.execasresource .systemvar + } { + {exec} + } ifelse + 2 index cvlit + /closefile .systemvar 3 .execn + } { + cvx exec + } ifelse + } stopped +} bind def +% undefine a dict that is only used internally, and is immediately bound +currentdict /closesourcedict .undef + +% Here are the BuildChar and BuildGlyph implementation for Type 1 fonts. +% The names %Type1BuildChar and %Type1BuildGlyph are known to the interpreter. +% The real work is done in an operator: +% <font> <code|name> <name> <charstring> .type1execchar - + +(%Type1BuildChar) cvn { % <font> <code> %Type1BuildChar - + 1 index /Encoding get 1 index get .type1build .type1execchar +} bind def +(%Type1BuildGlyph) cvn { % <font> <name> %Type1BuildGlyph - + dup .type1build .type1execchar +} bind def +% Note: this procedure is used for both Type 1 and Type 2 fonts. +/.type1build { % <font> <code|name> <name> .type1build + % <font> <code|name> <name> <charstring> + 2 index begin + dup CharStrings exch .knownget not { + 2 copy eq { exch pop /.notdef exch } if + QUIET not + { (Substituting .notdef for ) print + =string cvs print ( in the font ) print + 1 index /FontName get = flush + } + { pop } + ifelse + /.notdef CharStrings /.notdef get + } if + end +} bind def + +1183615869 internaldict begin +% CCRun is an undocumented procedure provided for Type 4 and Type 0 fonts. +% Apparently there are two different argument lists for CCRun. +% Handling the one with the extra Private dictionary requires fabricating +% a Type 1 font on the fly, since we aren't currently prepared to parse the +% dictionary any other way. +/CCRun { % <font> <code|name> <charstring> CCRun - + % <font> <code|name> <charstring> <Private> CCRun - + dup type /dicttype eq { + dup 4 index /Private .knownget { ne } { pop //true } ifelse { + % The Private dictionary was supplied, and is different + % from the Private dictionary of the font. Fabricate a + % Type 1 font with this Private dictionary. Most of the + % font entries are arbitrary or not needed. + .currentglobal //false .setglobal 10 dict exch .setglobal begin + /Private exch def + /FontType 1 def + /FontMatrix 3 index /FontMatrix get def + /Encoding 3 index /Encoding .knownget not { StandardEncoding } if def + /FontBBox 3 index /FontBBox .knownget not { {0 0 0 0} } if def + /PaintType 0 def + /CharStrings 1 dict dup /.notdef () put def + 3 -1 roll pop () currentdict end .buildfont1 exch pop 3 1 roll + } { + pop + } ifelse + } if + 1 index dup type /integertype eq { + 3 index /Encoding get exch get + } if exch .type1execchar +} bind def + +% setweightvector is an undocumented procedure that force writes +% weight vector to the font. Do extra checks for safety. +/setweightvector { % <font> <vector> setweightvector - + dup type dup /arraytype ne exch /packedarraytype ne and + 2 index type /dicttype ne or { + /setweightvector cvx /typecheck signalerror + } if + 1 index /FontType known not { + /setweightvector cvx /invalidfont signalerror + } if + dup gcheck 2 index gcheck not and { + /setweightvector cvx /invalidaccess signalerror + } if + 2 copy /WeightVector exch .forceput + .setweightvector +} .bind executeonly def +end + +% Register the font types for definefont. +buildfontdict 1 /.buildfont1 cvx put +buildfontdict 4 /.buildfont4 cvx put + +% Add Type 2 support if applicable. +/.buildfont2 where not { (%END2) .skipeof } if +pop +(%Type2BuildChar) cvn { % <font> <code> %Type2BuildChar - + 1 index /Encoding get 1 index get .type1build .type2execchar +} bind def +(%Type2BuildGlyph) cvn { % <font> <name> %Type2BuildGlyph - + dup .type1build .type2execchar +} bind def +buildfontdict 2 /.buildfont2 cvx put +%END2 diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_wan_e.ps b/Master/tlpkg/tlgs/Resource/Init/gs_wan_e.ps new file mode 100644 index 00000000000..96320334e88 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/gs_wan_e.ps @@ -0,0 +1,45 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Define the WinAnsi encoding vector. +/currentglobal where + { pop currentglobal { setglobal } //true setglobal } + { { } } +ifelse +/WinAnsiEncoding +ISOLatin1Encoding 0 39 getinterval aload pop + /quotesingle +ISOLatin1Encoding 40 5 getinterval aload pop + /hyphen +ISOLatin1Encoding 46 50 getinterval aload pop + /grave +ISOLatin1Encoding 97 30 getinterval aload pop + /bullet +% \20x + % NOTE: /Euro, /Zcaron, and /zcaron are new for PDF 1.3. + % We may have to take them out for backward compatibility. + /Euro /bullet /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /bullet /Zcaron /bullet + /bullet /quoteleft /quoteright /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /bullet /zcaron /Ydieresis +ISOLatin1Encoding 160 96 getinterval aload pop +256 packedarray +4 1 index .registerencoding +.defineencoding +exec diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_base.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_base.ps new file mode 100644 index 00000000000..bdfe9ee8feb --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_base.ps @@ -0,0 +1,1225 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% pdf_base.ps +% Basic parser for PDF reader. + +% This handles basic parsing of the file (including the trailer +% and cross-reference table), as well as objects, object references, +% streams, and name/number trees; it doesn't include any facilities for +% making marks on the page. + +/.setlanguagelevel where { pop 2 .setlanguagelevel } if +.currentglobal //true .setglobal +/pdfdict where { pop } { /pdfdict 100 dict def } ifelse +pdfdict begin + +% Define the name interpretation dictionary for reading values. +/valueopdict mark + (<<) cvn { mark } bind % don't push an actual mark! + (>>) cvn { { .dicttomark } stopped { + ( **** Error: File has an unbalanced >> \(close dictionary\).\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } if + } bind + ([) cvn { mark } bind % ditto + (]) cvn dup load +% /true true % see .pdfexectoken below +% /false false % ibid. +% /null null % ibid. + /F dup cvx % see Objects section below + /R dup cvx % see Objects section below + /stream dup cvx % see Streams section below +.dicttomark readonly def + +% ------ Utilities ------ % + +% Define a scratch string. The PDF language definition says that +% no line in a PDF file can exceed 255 characters, but this string +% is also used to search for %PDF-, which needs 1024 characters. +/pdfstring 1024 string def + +% Handle the PDF 1.2 #nn escape convention when reading from a file. +% This should eventually be done in C. +/.pdffixname { % <execname> .pdffixname <execname'> + PDFversion 1.2 ge { + dup .namestring (#) search { + name#escape cvn exch pop + } { + pop + } ifelse + } if +} bind def +/name#escape % <post> <(#)> <pre> name#escape <string> +{ exch pop + 1 index 2 () /SubFileDecode filter dup (x) readhexstring + % Stack: post pre stream char t/f + not { % tolerate, but complain about bad syntax + pop closefile (#) concatstrings exch + ( **** Error: Invalid hex following '#' name escape, using literal '#' in name.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } { + exch closefile concatstrings + exch 2 1 index length 2 sub getinterval + } ifelse + (#) search { name#escape } if concatstrings +} bind def + +/num-chars-dict mark (0123456789-.) {dup} forall .dicttomark readonly def + +% Execute a file, interpreting its executable names in a given +% dictionary. The name procedures may do whatever they want +% to the operand stack. +/.pdftokenerror { % <count> <opdict> <errtoken> .pdftokenerror - + BXlevel 0 le { + ( **** Error: Unknown operator: ') pdfformaterror + dup =string cvs pdfformaterror + (') pdfformaterror + % Attempt a retry scan of the element after changing to PDFScanInvNum + << /PDFScanInvNum //true >> setuserparams + =string cvs + token pop exch pop dup type + dup /integertype eq exch /realtype eq or { + exch pop exch pop + (, processed as number, value: ) pdfformaterror + dup =string cvs pdfformaterror (\n) pdfformaterror + << /PDFScanInvNum //null >> setuserparams % reset to default scanning rules + //false % suppress any stack cleanup + } { + % error was non-recoverable with modified scanning rules, continue. + dup type /nametype eq { + //true 1 index .namestring { + //num-chars-dict exch known and + } forall { % perhaps, it's a malformed number. + PDFSTOPONERROR {//true}{ + pop pop pop 0 //false + ( looks like a malformed number, replacing with 0.) pdfformaterror + } ifelse + } { + //true % punt + } ifelse + } { + //true % punt + } ifelse + (\n) pdfformaterror + } ifelse + } { + //true + } ifelse + { % clean up the operand stack if this was non-recoverable + pop pop count exch sub { pop } repeat % pop all the operands + } if + ( Output may be incorrect.\n) pdfformaterror +} bind def + +currentdict /num-chars-dict .undef + +/.pdfexectoken { % <count> <opdict> <exectoken> .pdfexectoken ? + PDFDEBUG { + pdfdict /PDFSTEPcount known not { pdfdict /PDFSTEPcount 1 .forceput } if + PDFSTEP { + pdfdict /PDFtokencount 2 copy .knownget { 1 add } { 1 } ifelse .forceput + PDFSTEPcount 1 gt { + pdfdict /PDFSTEPcount PDFSTEPcount 1 sub .forceput + } { + dup ==only + ( step # ) print PDFtokencount =only + ( ? ) print flush 1 //false .outputpage + (%stdin) (r) file 255 string readline { + token { + exch pop pdfdict /PDFSTEPcount 3 -1 roll .forceput + } { + pdfdict /PDFSTEPcount 1 .forceput + } ifelse % token + } { + pop /PDFSTEP //false def % EOF on stdin + } ifelse % readline + } ifelse % PDFSTEPcount > 1 + } { + dup ==only () = flush + } ifelse % PDFSTEP + } if % PDFDEBUG + 2 copy .knownget { + exch pop exch pop exch pop exec + } { + % Normally, true, false, and null would appear in opdict + % and be treated as "operators". However, there is a + % special fast case in the PostScript interpreter for names + % that are defined in, and only in, systemdict and/or + % userdict: putting these three names in the PDF dictionaries + % destroys this property for them, slowing down their + % interpretation in all PostScript code. Therefore, we + % check for them explicitly here instead. + dup dup dup /true eq exch /false eq or exch /null eq or { + exch pop exch pop //systemdict exch get + } { + % Hackish fix to detect missing whitespace after "endobj". Yet another + % problem that (you guessed it!) Adobe Acrobat ignores silently + dup .namestring (endobj) anchorsearch { + ( **** Error: Missing whitespace after 'endobj'.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + pop pop pop exch pop /endobj get exec + } { + %% First, lets try and see if this 'might' be a broken number + %% we look for 0-9 as well as '.' ',' and '-' to permit those + %% locales in which the separator is a comma, as well as negative + %% numbers. We've seena t least one tool replace '0' with '-' *sometimes* + true exch + dup length 1 sub 0 1 3 -1 roll { + 1 index exch get + dup 44 lt { + pop exch pop false exch exit + }{ + dup 57 gt { + pop exch pop false exch exit + }{ + dup 47 eq { + pop exch pop false exch exit + }{ + pop + } ifelse + } ifelse + } ifelse + } for + pop + { + %% If it looks like a number, try to deal with it as such + PDFSTOPONERROR { + dup .pdftokenerror + }{ + dup {.pdftokenerror} stopped + } ifelse + { pop + %% But if it fails, fall back to converting into a anem. + %% This will propagate through and cause different + %% fallback code to try and take care ot if. + cvlit exch pop exch pop + }{ + exch pop + } ifelse + }{ + %% Doesn't look like a number, convert it into a name + cvlit exch pop exch pop + } ifelse + } ifelse + } ifelse + } ifelse +} bind def +/PDFScanRules_true << /PDFScanRules //true >> def +/PDFScanRules_null << /PDFScanRules //null >> def +/.pdfrun { % <file> <opdict> .pdfrun - + % Construct a procedure with the stack depth, file and opdict + % bound into it. + 1 index cvlit % file <<>> file + count 2 sub % file <<>> file cnt + 3 1 roll mark % file cnt <<>> file [ + /PDFScanRules .getuserparam //null eq { + //PDFScanRules_true { setuserparams } 0 get % force PDF scanning mode + mark 7 4 roll + } { + mark 5 2 roll % file [ [ cnt <<>> file + } ifelse + { % Stack: ..operands.. count opdict file + { token } stopped { + dup type /filetype eq { pop } if + pop pop stop + } if { + dup type /nametype eq { + dup xcheck { + .pdfexectoken + } { + .pdffixname + exch pop exch pop PDFDEBUG { + PDFSTEPcount 1 le { + dup ==only ( ) print flush + } if + } if + } ifelse + } { + exch pop exch pop PDFDEBUG { + PDFSTEPcount 1 le { + dup ==only ( ) print flush + } if + } if + } ifelse + } { + pop pop exit + } ifelse + } + aload pop .packtomark cvx % file [ {cnt <<>> file ... } + { loop } 0 get 2 packedarray cvx % file [ { {cnt <<>> file ... } loop } + PDFSTOPONERROR { {exec //false} } { {stopped} } ifelse + aload pop % file [ { {cnt <<>> file ... } loop } stopped + /PDFScanRules .getuserparam //null eq { + //PDFScanRules_null { setuserparams } 0 get % reset PDF scannig mode if it was off + } if + /PDFsource PDFsource % file [ { {cnt <<>> file ... } loop } stopped /PDFsource PDFsource + { store { + /StreamRunAborted //true store + ( **** Error reading a content stream. The page may be incomplete.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } if + } aload pop % file [ { {cnt <<>> file ... } loop } stopped /PDFsource PDFsource store {...} if + .packtomark cvx % file { { {cnt <<>> file ... } loop } stopped /PDFsource PDFsource store {...} if} + /PDFsource 3 -1 roll store % {...} + exec +} bind def + +% Execute a file, like .pdfrun, for a marking context. +% This temporarily rebinds LocalResources and DefaultQstate. +/.pdfruncontext { % <resdict> <file> <opdict> .pdfruncontext - + /.pdfrun load LocalResources DefaultQstate + /LocalResources 7 -1 roll store + /DefaultQstate qstate store + 3 .execn + /DefaultQstate exch store + /LocalResources exch store +} bind def + +% Get the depth of the PDF operand stack. The caller sets pdfemptycount +% before calling .pdfrun or .pdfruncontext. It is initially set by +% pdf_main, and is also set by any routine which changes the operand +% stack depth (currently .pdfpaintproc, although there are other callers +% of .pdfrun{context} which have not been checked for opstack depth. +/.pdfcount { % - .pdfcount <count> + count pdfemptycount sub +} bind def + +% Read a token, but simply return false (no token read) in the case of an +% error. This is messy because 'token' either may or may not pop its operand +% if an error occurs, and because the return values are different depending +% on whether the source is a file or a string. To avoid closing the file +% check for '{' before trying 'token'. +/token_nofail_dict mark + ( ) { dup ( ) readstring pop pop } bind + (\t) 1 index + (\r) 1 index + (\n) 1 index + (\000) 1 index + ({) { //null //true exit } bind +.dicttomark def + +/token_nofail { % <file|string> token_nofail false + % <file> token_nofail <token> true + % <string> token_nofail <post> <token> true + dup type /filetype eq { + { dup ( ) .peekstring not { ({) } if + //token_nofail_dict exch .knownget not { + //null 1 index { token } .internalstopped exit + } if + exec + } loop + { % stack: source null [source] + //null ne { pop } if pop //false + } { % stack: source null ([post] token true | false) + { 3 1 roll pop pop //true } + { pop pop //false } + ifelse + } ifelse + } { + //null 1 index % stack: source null source + { token } .internalstopped { % stack: source null [source] + //null ne { pop } if pop //false + } { % stack: source null ([post] token true | false) + { 4 2 roll pop pop //true } + { pop pop //false } + ifelse + } ifelse + } ifelse +} bind def + +currentdict /token_nofail_dict .undef + +% ================================ Objects ================================ % + +% We keep track of PDF objects using the following PostScript variables: +% +% Generations (string): Generations[N] holds 1+ the current +% generation number for object number N. (As far as we can tell, +% this is needed only for error checking.) For free objects, +% Generations[N] is 0. +% +% Objects (array): If object N is loaded, Objects[N] is the actual +% object; otherwise, Objects[N] is an executable integer giving +% the file offset of the object's location in the file. If +% ObjectStream[N] is non-zero then Objects[N] contains the index +% into the object stream instead of the file offset of the object. +% +% ObjectStream (array): If object N is in an object stream then +% ObjectStream[N] holds the object number of the object stream. +% Otherwise ObjectStream[N] contains 0. If ObjectStream[N] +% is non-zero then Objects[N] contains the index into the object +% stream. +% +% GlobalObjects (dictionary): If object N has been resolved in +% global VM, GlobalObjects[N] is the same as Objects[N] +% (except that GlobalObjects itself is stored in global VM, +% so the entry will not be deleted at the end of the page). +% +% IsGlobal (string): IsGlobal[N] = 1 iff object N was resolved in +% global VM. This is an accelerator to avoid having to do a +% dictionary lookup in GlobalObjects when resolving every object. + +% Initialize the PDF object tables. +/initPDFobjects { % - initPDFobjects - + /ObjectStream 0 array def + /Objects 0 array def + /Generations 0 string def + .currentglobal //true .setglobal + /GlobalObjects 20 dict def + .setglobal + /IsGlobal 0 string def +} bind def + +% Grow the tables to a specified size. +/growPDFobjects { % <minsize> growPDFobjects - + dup ObjectStream length gt { + dup ObjectStream exch array dup 3 1 roll copy pop /ObjectStream exch def + } if + dup Objects length gt { + dup Objects exch array dup 3 1 roll copy pop /Objects exch def + } if + dup Generations length gt { + dup Generations exch string dup 3 1 roll copy pop /Generations exch def + } if + dup IsGlobal length gt { + dup IsGlobal exch string dup 3 1 roll copy pop /IsGlobal exch def + } if + pop +} bind def + +% We represent an unresolved object reference by a procedure of the form +% {obj# gen# resolveR}. This is not a possible PDF object, because PDF has +% no way to represent procedures. Since PDF in fact has no way to represent +% any PostScript object that doesn't evaluate to itself, we can 'force' +% a possibly indirect object painlessly with 'exec'. +% Note that since we represent streams by executable dictionaries +% (see below), we need both an xcheck and a type check to determine +% whether an object has been resolved. +/resolved? { % <object#> resolved? <value> true + % <object#> resolved? false + Objects 1 index get dup xcheck { % Check if executable + dup type /integertype eq { % Check if an integer + % Check whether the object is in GlobalObjects. + pop IsGlobal 1 index get 0 eq { % 0 --> Not in GlabalObjects + pop //false % The object is not resolved + } { % The object is in GlobalObjects + % Update Objects from GlobalObjects + PDFDEBUG { (%Global=>local: ) print dup //== exec } if + GlobalObjects 1 index get dup Objects 4 1 roll put //true + } ifelse + } { % Else object is executable but not integer + exch pop //true % Therefore must be executable dict. (stream) + } ifelse + } { % Else object is not executable. + exch pop //true % Therefore it must have been resolved. + } ifelse +} bind def +/oforce /exec load def +/oget { % <array> <index> oget <object> + % <dict> <key> oget <object> + % Before release 6.20, this procedure stored the resolved + % object back into the referring slot. In order to support + % PDF linearization, we no longer do this. + get oforce +} bind def + +/oforce_array { % <array> oforce_array <array> + [ exch { oforce } forall ] +} bind def + +/oforce_elems { % <array> oforce_elems <first> ... <last> + { oforce } forall +} bind def + +/oforce_recursive { % <any> oforce_recursive <any> + dup type dup /arraytype eq exch /packedarraytype eq or { + dup rcheck { % protect tint transform functions, etc. + oforce % but dereference {1 0 R} + dup type dup /arraytype eq exch /packedarraytype eq or { + [ exch { oforce_recursive } forall ] + } { + dup type /dicttype eq { + << exch { oforce_recursive exch oforce exch } forall >> + } if + } ifelse + } if + } { + dup type /dicttype eq { + << exch { oforce_recursive exch oforce exch } forall >> + } if + } ifelse +} bind def + +% A null value in a dictionary is equivalent to an omitted key; +% we must check for this specially. +/knownoget { % <dict> <key> knownoget <value> true + % <dict> <key> knownoget false + % See oget above regarding this procedure. + .knownget { + oforce dup //null eq { pop //false } { //true } ifelse + } { + //false + } ifelse +} bind def + +% See /knownoget above. +/oknown { % <dict> <key> oknown <bool> + .knownget { oforce //null ne } { //false } ifelse +} bind def + +/knownogetdict { % <dict> <key> knownogetdict <dict> true + % <dict> <key> knownogetdict false + //knownoget exec dup { + 1 index type /dicttype ne { pop pop //false } if + } if +} bind def + +% PDF 1.1 defines a 'foreign file reference', but not its meaning. +% Per the specification, we convert these to nulls. +/F { % <file#> <object#> <generation#> F <object> + % Some PDF 1.1 files use F as a synonym for f! + .pdfcount 3 lt { f } { pop pop pop //null } ifelse +} bind def + +% Verify the generation number for a specified object +% Note: The values in Generations is the generation number plus 1. +% If the value in Generations is zero then the object is free. +/checkgeneration { % <object#> <generation#> checkgeneration <object#> <OK> + Generations 2 index get 1 sub 1 index eq { % If generation # match ... + pop //true % Then return true + } { % Else not a match ... + QUIET not { % Create warning message if not QUIET + Generations 2 index get 0 eq { % Check if object is free ... + ( **** Warning: reference to free object: ) + 2 index =string cvs concatstrings ( ) concatstrings % put obj # + exch =string cvs concatstrings ( R\n) concatstrings % put gen # + } { + ( **** Warning: wrong generation: ) + 2 index =string cvs concatstrings ( ) concatstrings % put obj # + exch =string cvs concatstrings % put gen # + (, xref gen#: ) concatstrings 1 index Generations % put xref gen # + exch get 1 sub =string cvs concatstrings (\n) concatstrings + } ifelse + pdfformatwarning % Output warning message + } { % Else QUIET ... + pop % Pop generation number + } ifelse + % We should return false for an incorrect generation number, however + % we are simply printing a warning and then returning true. This makes + % Ghostscript tolerant of of bad generation numbers. + //true + } ifelse +} bind def +/R { % <object#> <generation#> R <object> + %% Parameter validation; this should not be required but we have found files + %% (Bug 697351) which are corrupted in ways that mean we see a 'R' in a stream + %% even though it is not an indirect object reference. Because a stream + %% may reference objetcs which have not been resolved, we cannot simply + %% 'undef' teh R operator, the only solution is to have it chekc the + %% types of its operands. This is poterntially slow of course, we may + %% need to remove this in future if the performance penalty is too great. + %% We cannot slow down all files significantly purely to work-around + %% files which are invalid. + 1 index type /integertype eq 1 index type /integertype eq and { + /resolveR cvx 3 packedarray cvx + } { + ( **** Error: indirect object reference \(R\) encountered with invalid arguments.) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse +} bind def + +% If we encounter an object definition while reading sequentially, +% we just store it away and keep going. +/objopdict mark + valueopdict { } forall + /endobj dup cvx +.dicttomark readonly def + +/obj { % <object#> <generation#> obj <object> + PDFfile objopdict .pdfrun +} bind def + +/endobj { % <object#> <generation#> <object> endobj <object> + + %% If we have a stream wioth a broken endstream we can get here without + %% an object definition on nthe stack. If we simply pop the 'extraneous' + %% data we will break the stream definition and throw an error. So we look + %% to see if this appears to be this specific case. + 2 index type /marktype eq 2 index type /marktype eq or { + { + dup type /marktype eq { + exit + }{ + pop + }if + }loop + }{ + { + 2 index type /integertype ne 2 index type /integertype ne or { + count 3 gt { + ( **** Error: obj definition followed by multiple tokens, attempting to recover.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + pop + } { + //null + ( **** Error: ignoring obj followed by multiple tokens.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + exit + } ifelse + } { + exit + } ifelse + } loop + + 3 1 roll + % Read the xref entry if we haven't yet done so. + % This is only needed for generation # checking. + 1 index resolved? { + pop + } if + checkgeneration { + % The only global objects we bother to save are + % (resource) dictionaries. + 1 index dup gcheck exch type /dicttype eq and { + PDFDEBUG { (%Local=>global: ) print dup //== exec } if + GlobalObjects 1 index 3 index put + IsGlobal 1 index 1 put + } if + Objects exch 2 index put + } { + pop pop //null + } ifelse + }ifelse +} bind def + +% When resolving an object reference in an object stream, we stop at +% the end of file. Note: Objects in an object stream do not have either +% a starting 'obj' or and ending 'endobj'. +/resolveobjstreamopdict mark + valueopdict { } forall + (%%EOF) cvn { exit } bind + /endobj { % bug 689795 + ( **** Error: Objects in an object stream should not have 'endobj'.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } bind +.dicttomark readonly def + +% Note: This version of this function is not currently being used. +% Resolve all objects in an object stream +/resolveobjectstream { % <object stream #> resolveobjectstream - + PDFDEBUG { (%Resolving object stream: ) print } if + 0 resolveR % Get the objectstream dict, all objstrms use 0 as the gen # + dup /First get % Save location of first object onto the stack + 1 index /N get % Save number of objects onto the stack + 2 index //false resolvestream % Convert stream dict into a stream + /ReusableStreamDecode filter % We need to be able to position stream + % Objectstreams begin with list of object numbers and locations + % Create two arrays to hold object numbers and stream location + 1 index array % Array for holding object number + 2 index array % Array for holding stream object location + % Get the object numbers and locations. + 0 1 5 index 1 sub { % Loop and collect obj # and locations + % Stack: objstreamdict First N objectstream [obj#] [loc] index + 2 index 1 index % Setup to put obj# into object number array + 5 index token pop put % Get stream, then get obj# and put into array + 1 index 1 index % Setup to put object loc into location array + 5 index token pop put % Get stream, get obj loc and put into array + pop % Remove loop index + } for + % Create a bytestring big enough for reading any object data + % Scan for the size of the largest object + 0 0 % Init max object size and previous location + 2 index { % Loop through all object locations + % Stack: ... maxsize prevloc currentloc + dup 4 1 roll % Save copy of object location into stack + exch sub % Object size = currentloc - prevloc + .max % Determine maximum object size + exch % Put max size under previous location + } forall + pop % Remove previous location + .bigstring % Create bytestring based upon max obj size + % Move to the start of the object data + 3 index 6 index % Get objectstream and start of first object + setfileposition % Move to the start of the data + % Read the data for all objects except the last. We do + % not know the size of the last object so we need to treat + % it as a special case. + 0 1 6 index 2 sub { + dup 4 index exch get % Get our current object number + % Stack: objstreamdict First N objectstream [obj#] [loc] + % bytestring loopindex object# + dup resolved? { % If we already have this object + pop pop % Remove object and object number + 1 add 2 index exch get % Get location of next object + 6 index add 6 index exch % Form location of next object and get stream + setfileposition % Move to the start of the next object data + } { % Else this is a new object ... + % We are going to create a string for reading the object + 2 index 0 % use our working string + % Determine the size of the object + 5 index 4 index 1 add get % Get location of the next object + 6 index 5 index get % Get location of this object + sub % Size of object = next loc - this loc + getinterval % Create string for reading object + 6 index exch readstring pop % Read object + /ReusableStreamDecode filter % Convert string into a stream + resolveobjstreamopdict .pdfrun % Get PDF object + Objects exch 2 index exch put % Put object into Objects array + pop pop % Remove object # and loop index + } ifelse + } for + pop pop % Remove our working string and loc array + % Now read the last object in the object stream. Since it + % is the last object, we can use the original stream and + % terminate when we hit the end of the stream + % Stack: objstreamdict First N objectstream [obj#] + 2 index 1 sub get % Get our current object number + dup resolved? not { % If we do not already have this object + exch % Get our object stream + resolveobjstreamopdict .pdfrun % Get PDF object + Objects exch 2 index exch put % Put object into Objects array + } if + pop pop pop pop % Clear stack +} bind def + +/no_debug_dict << + /PDFDEBUG //false +>> readonly def + +% Resolve all objects in an object stream +/resolveobjectstream { % <object stream #> resolveobjectstream - + PDFDEBUG { (%Resolving object stream: ) print } if + dup 0 resolveR % Get the objectstream dict, all objstrms use 0 as the gen # + dup /Type get /ObjStm ne { % Verify type is object stream + ( **** Error: Incorrect Type in object stream dictionary.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + /resolveobjectstream cvx /typecheck signalerror + } if + dup /N get % Save number of objects onto the stack + 1 index //false resolvestream % Convert stream dict into a stream + /ReusableStreamDecode filter % We need to be able to position stream + % Objectstreams begin with list of object numbers and locations + 1 index array % Create array for holding object number + % Get the object numbers + 0 1 4 index 1 sub { % Loop and collect obj numbers + % Stack: strm# objstreamdict N PDFDEBUG objectstream [obj#] loopindex + 1 index 1 index % Setup to put obj# into object number array + 4 index token pop put % Get stream, then get obj# and put into array + 2 index token pop pop pop % Get stream, get obj loc and clear stack + } for + % Move to the start of the object data + 1 index 4 index /First get % Get objectstream and start of first object + setfileposition % Move to the start of the data + % We disable PDFDEBUG while reading the data stream. We will + % print the data later + PDFDEBUG { //no_debug_dict begin } if + % Read the data for all objects. We check to see if we get + % the number of objects that we expect. + % Stack: strm# objstreamdict N objectstream [obj#] PDFDEBUG + mark 3 -1 roll % Get objectstream + count 4 index add % Determine stack depth with objects + 3 1 roll + resolveobjstreamopdict .pdfrun % Get PDF objects + count counttomark 1 add index ne { % Check stack depth + ( **** Error: Incorrect object count in object stream.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + /resolveobjectstream cvx /rangecheck signalerror + } if + % We have the object data + counttomark array astore % Put objects into an array + exch pop exch pop % Remove mark and count + currentdict //no_debug_dict eq { end } if % Restore debug context + % Save the objects into Objects + 0 1 2 index length 1 sub { % Loop through all objects + % Stack: strm# objstreamdict N [obj#] [objects] loopindex + dup 3 index exch get % Get our current object number + % Stack: strm# objstreamdict N [obj#] [objects] loopindex obj# + dup ObjectStream exch get 7 index eq { + dup resolved? { % If we already have this object + pop pop % Remove object and object number + } { % Else if we do not have this object + PDFDEBUG { (%Resolving compressed object: [) print dup =only ( 0]) = } if + Objects exch 3 index % Put the object into Objects + 3 index get + PDFDEBUG { dup === flush } if + put + } ifelse + } { + pop % Ignore old object; remove object number. + } ifelse + pop % Remove loop index + } for + pop pop pop pop pop % Remove strm# objstream, N, (obj#], and [objects] +} bind def + +currentdict /no_debug_dict undef + +% When resolving an object reference, we stop at the endobj or endstream. +/resolveopdict mark + valueopdict { } forall + /endstream { endobj exit } bind + /endobj { endobj exit } bind + /endjobj { % Bug 689876. + ( **** Error: Operator 'endobj' is misspelled as 'endjobj'.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + endobj exit + } bind + /enbobj { % Bug 690397. + ( **** Error: Operator 'endobj' is misspelled as 'enbobj'.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + endobj exit + } bind + % OmniForm generates PDF file with endobj missing in some + % objects. AR ignores this. So we have to do it too. + /obj { pop pop endobj exit } bind +.dicttomark readonly def + +/resolveR { % <object#> <generation#> resolveR <object> + 1 index 3 1 roll % copy the object for the code after pdf_run_resolve (may store it) + PDFDEBUG { + PDFSTEPcount 1 le { + (%Resolving: ) print 2 copy 2 array astore //== exec + } if + } if + 1 index dup 0 le exch NumObjects ge or { + ( **** Error: Considering object with an invalid number ) + 2 index 20 string cvs concatstrings + ( as null.\n) concatstrings pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + pop pop //null + } { + 1 index resolved? { % If object has already been resolved ... + exch pop exch pop % then clear stack and return object + } { % Else if not resolved ... + PDFfile fileposition 3 1 roll % Save current file position + 1 index Objects exch get % Get location of object from xref + 3 1 roll checkgeneration { % Verify the generation number + % Stack: savepos objpos obj# + ObjectStream 1 index get dup 0 eq { % Check if obj in not an objstream + pop exch PDFoffset add PDFfile exch setfileposition + PDFfile token pop 2 copy ne + { ( **** Error: Unrecoverable error in xref!\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + /resolveR cvx /rangecheck signalerror + } + if pop PDFfile token pop + PDFfile token pop /obj ne + { ( **** Error: Unrecoverable error in xref!\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + /resolveR cvx /rangecheck signalerror + } + if + pdf_run_resolve % PDFfile resolveopdict .pdfrun + } { % Else the object is in an ObjectStream + % Process an objectstream object. We are going to resolve all + % of the objects in sthe stream and place them into the Objects + % array. + % Stack: savepos objpos obj# objectstream# + resolveobjectstream + resolved? { % If object has already been resolved ... + exch pop % Remove object pos from stack. + } { + pop pop //null % Pop objpos and obj#, put null for object + } ifelse + } ifelse + } { % Else the generation number is wrong + % Don't cache if the generation # is wrong. + pop pop //null % Pop objpos and obj#, put null for object + } ifelse % ifelse generation number is correct + exch PDFfile exch setfileposition % Return to original file position + } ifelse + } ifelse + + dup type /dicttype eq % For dictionaries only + { + dup /Type .knownget % make sure the dictionary has a type + { + dup /Font eq exch /FontDescriptor eq or % and ensure its a Font or FontDescriptor + {dup 3 -1 roll /.gs.pdfobj# exch put} + {exch pop} + ifelse + } + {exch pop} + ifelse + } + {exch pop} + ifelse +} bind def + +% ================================ Streams ================================ % + +% We represent a stream by an executable dictionary that contains, +% in addition to the contents of the original stream dictionary: +% /File - the file or string where the stream contents are stored, +% if the stream is not an external one. +% /FilePosition - iff File is a file, the position in the file +% where the contents start. +% /StreamKey - the key used to decrypt this stream, if any. +% We do the real work of constructing the data stream only when the +% contents are needed. + +% Construct a stream. The length is not reliable in the face of +% different end-of-line conventions, but it's all we've got. +% +% PDF files are inconsistent about what may fall between the 'stream' keyword +% and the actual stream data, and it appears that no one algorithm can +% detect this reliably. We used to try to guess whether the file included +% extraneous \r and/or \n characters, but we no longer attempt to do so, +% especially since the PDF 1.2 specification states flatly that the only +% legal terminators following the 'stream' keyword are \n or \r\n, both of +% which are properly skipped and discarded by the token operator. +% Unfortunately, this doesn't account for other whitespace characters that +% may have preceded the EOL, such as spaces or tabs. Thus we back up one +% character and scan until we find the \n terminator. +/stream { % <dict> stream <modified_dict> + dup /Length knownoget { + 0 eq { + dup /Filter undef % don't confuse any filters that require data + } if + } if + dup /F known dup PDFsource PDFfile eq or { + not { + dup /File PDFfile put + % make sure that we are just past the EOL \n character + PDFfile dup fileposition 1 sub setfileposition % back up one + % Skip spaces till \n or a non-space character is found. + //false + { + PDFfile read pop + dup 32 eq { pop //true or } { exit } ifelse + } loop + dup 13 eq { + pop + PDFfile read pop + } if + 10 ne { + PDFfile dup fileposition 1 sub setfileposition + //true or + } if { + ( **** Error: stream operator isn't terminated by valid EOL.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } if + + dup /FilePosition PDFfile fileposition put + PDFDEBUG { + PDFSTEPcount 1 le { + (%FilePosition: ) print dup /FilePosition get //== exec + } if + } if + } if + % Some (bad) PDf files have invalid stream lengths. This causes problems + % if we reposition beyond the end of the file. So we compare the given + % length to number of bytes left in the file. + dup /Length knownoget { + dup PDFfile bytesavailable lt { % compare to to bytes left in file + PDFfile fileposition % reposition to the end of stream + add PDFfile exch setfileposition + } { + pop % bad stream length - do not reposition. + % This will force a length warning below + } ifelse + } if + } { + pop + % We're already reading from a stream, which we can't reposition. + % Capture the sub-stream contents in a string. + dup /Length oget string PDFsource exch readstring + not { + ( **** Error: Unexpected EOF in stream!\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + /stream cvx /rangecheck signalerror + } if + 1 index exch /File exch put + } ifelse + PDFsource token_nofail not { //null } if + dup /endobj eq { + % Another case that Acrobat Reader handles -- 'endobj' without 'endstream'. + ( **** Error: stream missing 'endstream'.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + pop /endstream % fake a valid endstream + } if + /endstream ne { + ( **** Error: stream Length incorrect.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + dup /Length undef % prevent the use of the incorrect length. + + %% Bug #696560 If we get a stream whose length is incorrect we cannot + %% safely *assume* it has an object definition as we can get here when + %% reading an XRef stream, and in that case we will not have the object + %% and generation numbers on the stack! + %% So before we call endobj and exit pdfrun, try and see if ths looks like + %% a regular object or not. If it isn't then don't try and ahndle it as + %% one, just return the object. + count 3 ge { + 1 index type /integertype eq 2 index type /integertype eq and { + cvx endobj exit % exit from .pdfrun now. + } if + } if + } { + PDFsource (??) .peekstring pop (>>) eq { % Bug 690161, sample #1 + ( **** Error: Spurious '>>' after 'endstream' ignored.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + PDFsource (12) readstring pop pop + } if + } ifelse + cvx +} bind def + +/endstream { + exit +} bind def + +% Contrary to the published PDF (1.3) specification, Acrobat Reader +% accepts abbreviated filter names everywhere, not just for in-line images, +% and some applications (notably htmldoc) rely on this. +/unabbrevfilterdict mark + /AHx /ASCIIHexDecode /A85 /ASCII85Decode /CCF /CCITTFaxDecode + /DCT /DCTDecode /Fl /FlateDecode /LZW /LZWDecode /RL /RunLengthDecode +.dicttomark readonly def + +% Extract and apply filters. +/filterparms { % <dict> <DPkey> <Fkey> filterparms + % <dict> <parms> <filternames> + 2 index exch knownoget { + oforce_recursive + exch 2 index exch knownoget { + dup length 0 eq { + pop //false + } { + //true + } ifelse + } { + //false + } ifelse { + % Both filters and parameters. + oforce_recursive + exch dup type /nametype eq { + 1 array astore exch + dup type /arraytype ne { 1 array astore } if exch + } if + } { + % Filters, but no parameters. + //null exch + dup type /nametype eq { 1 array astore } if + } ifelse + } { + % No filters: ignore parameters, if any. + pop //null { } + } ifelse +} bind def +/filtername { % <filtername> filtername <filtername'> + //unabbrevfilterdict 1 index .knownget { exch pop } if + dup /Filter resourcestatus { pop pop } { + Repaired exch % this error is not the creator's fault + RepiredAnError exch + ( **** ERROR: Unable to process ) pdfformaterror + 64 string cvs pdfformaterror + ( data. Page will be missing data.\n) pdfformaterror + /RepairedAnError exch store + /Repaired exch store % restore the previous "Repaired" state + % provide a filter that returns EOF (no data) + /.EOFDecode + } ifelse +} bind def + +/pdf_rules_dict << /PDFRules //true >> readonly def + +% Add PDF option to ASCII85Decode filter +% <source> <name> add_A85_param <source> <dict'> <name> +% <source> <dict> <name> add_A85_param <source> <dict'> <name> +/add_A85_param { + dup /ASCII85Decode eq { + 1 index type /dicttype eq { + exch dup length 1 add dict copy + dup /PDFRules //true put + exch + } { + //pdf_rules_dict exch + } ifelse + } if +} bind def + +currentdict /pdf_rules_dict undef + +/applyfilters { % <parms> <source> <filternames> applyfilters <stream> + 2 index //null eq + { + { filtername add_A85_param filter } + } + { + dup length 3 index length ne %% compare lengths of DecodeParmas and Filter arrays + { %% if they aren't the same, ignore the decode params + ( **** Error: ignoring stream /DecodeParams array as its length is different to the Filters array.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + 3 -1 roll pop //null 3 1 roll + { filtername add_A85_param filter } + } + { + { % Stack: parms source filtername + 2 index 0 oget dup type /dicttype ne + { pop } + { + exch filtername dup /JBIG2Decode eq { exch jbig2cachectx exch } if + } ifelse + add_A85_param filter + exch dup length 1 sub 1 exch getinterval exch + } + } ifelse + } ifelse + forall exch pop +} bind def + +% JBIG2 streams have an optional 'globals' stream obj for +% sharing redundant data between page images. Here we resolve +% that stream reference (if any) and run it through the decoder, +% creating a special -jbig2globalctx- postscript object our +% JBIG2Decode filter implementation looks for in the parm dict. +/jbig2cachectx { % <parmdict> jbig2cachectx <parmdict> + dup /JBIG2Globals knownoget { + % make global ctx + PDFfile fileposition exch % resolvestream is not reentrant + //true resolvestream % stack after: PDFfileposition -file- + % Read the data in a loop until EOF to so we can move the strings into a bytestring + [ { counttomark 1 add index 60000 string readstring not { exit } if } loop ] + exch pop 0 1 index { length add } forall % compute the total length + % now copy the data from the array of strings into a bytestring + .bytestring exch 0 exch { 3 copy putinterval length add } forall pop + .jbig2makeglobalctx + PDFfile 3 -1 roll setfileposition + 1 index exch + /.jbig2globalctx exch put + } if +} bind def + +% Resolve a stream dictionary to a PostScript stream. +% Streams with no filters require special handling: +% - Whether we are going to interpret the stream, or If we are just +% going to read data from them, we impose a SubFileDecode filter +% that reads just the requisite amount of data. +% Note that, in general, resolving a stream repositions PDFfile. +% Clients must save and restore the position of PDFfile themselves. +/resolvestream { % <streamdict> <readdata?> resolvestream <stream> + 1 index /F knownoget { + % This stream is stored on an external file. + (r) file 3 -1 roll + /FDecodeParms /FFilter filterparms + % Stack: readdata? file dict parms filternames + 4 -1 roll exch + pdf_decrypt_stream + applyfilters + } { + exch + dup /Length knownoget { 0 eq } { //false } ifelse { + () 0 () /SubFileDecode filter + } { + dup /FilePosition .knownget { + 1 index /File get exch setfileposition + } if + % Stack: readdata? dict + /DecodeParms /Filter filterparms + % Stack: readdata? dict parms filternames + 2 index /File .knownget not { + ( **** Error: Stream object is missing the stream data.\n) + ( Output may be incorrect.\n) pdfformaterror + pdfformaterror + () + } if exch + % Stack: readdata? dict parms file/string filternames + dup length 0 eq { + % All the PDF filters have EOD markers, but in this case + % there is no specified filter. + exch dup type /filetype eq 5 index or { + % Use length for any files or reading data from any source. + 3 index /Length knownoget not { 0 } if + } { + 0 % Otherwise length of 0 for whole string + } ifelse + 4 index /IDFlag known { pop } { () /SubFileDecode filter } ifelse + exch + pdf_decrypt_stream % add decryption if needed + pop exch pop + } { + % Stack: readdata? dict parms source filternames + exch 3 index /Length knownoget { + () /SubFileDecode filter + } if exch + pdf_decrypt_stream % add decryption if needed + applyfilters + } ifelse + } ifelse + } ifelse + % Stack: readdata? dict file + exch pop exch pop +} bind def + +% ============================ Name/number trees ============================ % + +/nameoget { % <nametree> <key> nameoget <obj|null> + exch /Names exch .treeget +} bind def + +/numoget { % <numtree> <key> numoget <obj|null> + exch /Nums exch .treeget +} bind def + +/.treeget { % <key> <leafkey> <tree> .treeget <obj|null> + dup /Kids knownoget { + exch pop .branchget + } { + exch oget .leafget + } ifelse +} bind def + +/.branchget { % <key> <leafkey> <kids> .branchget <obj|null> + dup length 0 eq { + pop pop pop //null + } { + dup length -1 bitshift 2 copy oget + % Stack: key leafkey kids mid kids[mid] + dup /Limits oget aload pop + % Stack: key leafkey kids mid kids[mid] min max + 6 index lt { + pop pop + 1 add 1 index length 1 index sub getinterval .branchget + } { + 5 index gt { + pop + 0 exch getinterval .branchget + } { + exch pop exch pop .treeget + } ifelse + } ifelse + } ifelse +} bind def + +/.leafget { % <key> <pairs> .leafget <obj|null> + dup length 2 eq { + dup 0 get 2 index eq { 1 oget } { pop null } ifelse + exch pop + } { + dup length -1 bitshift -2 and 2 copy oget + % Stack: key pairs mid pairs[mid] + 3 index gt { 0 exch } { 1 index length 1 index sub } ifelse + getinterval .leafget + } ifelse +} bind def + +end % pdfdict +.setglobal diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps new file mode 100644 index 00000000000..88da2de7485 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps @@ -0,0 +1,4088 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% pdf_draw.ps +% PDF drawing operations (graphics, text, and images). + +/.setlanguagelevel where { pop 2 .setlanguagelevel } if +.currentglobal //true .setglobal +/pdfdict where { pop } { /pdfdict 100 dict def } ifelse +GS_PDF_ProcSet begin +pdfdict begin + +% For simplicity, we use a single interpretation dictionary for all +% PDF graphics operations, even though this is too liberal. +/drawopdict 100 dict def + +/SetGroupExtGStateDict +<< + /AlphaIsShape //AIS + /FillConstantAlpha //ca + % We don't have to worry about the enumeration order, even + % with the color/space settings, since we only store, not + % not set them. + /FillColor //sc1 + /FillColorSpace { /FillColorSpace gput } bind + /FillOverprint //op + /SoftMask //SMask + /StrokeConstantAlpha //CA + /StrokeColor //SC1 + /StrokeColorSpace { /StrokeColorSpace gput } bind + /StrokeOverprint //OP + /TextSpacing //Tc + % We can't use //Tz as we've stored the value we actually use, + % not value * 100 (see /Tz in pdf_ops.ps) + /TextHScaling { /TextHScaling gput } bind + /Leading //TD + /TextFont { /TextFont gput} bind + /TextLineMatrix { /TextLineMatrix gput } bind + /TextMatrix { /TextMatrix gput } bind + /TextRise { /TextRise gput } bind + /TextRenderingMode { /TextRenderingMode gput } bind + /WordSpacing //Tw +>> def + +% ================================ Graphics ================================ % + +% ---------------- Functions ---------------- % + +% Note that resolvefunction converts a PDF Function to a PostScript Function; +% resolve*fnproc converts a PDF function to a PostScript procedure. +% We need to process all required and optional parameters to resolve any +% use of indirect references. + +/fnrdict mark + 0 { .resolvefn0 } + 2 { .resolvefn2 } + 3 { .resolvefn3 } + 4 { .resolvefn4 } +.dicttomark readonly def + +/.resolvefn0 { + dup length 1 add dict .copydict % make room for DataSource + % now resolve any indirect references + dup /Size 2 copy knownoget { put } { pop pop } ifelse + dup /BitsPerSample 2 copy knownoget { put } { pop pop } ifelse + dup /Order 2 copy knownoget { put } { pop pop } ifelse + dup /Encode 2 copy knownoget { put } { pop pop } ifelse + dup /Decode 2 copy knownoget { put } { pop pop } ifelse + + % Don't lose our place in PDFfile. + PDFfile fileposition exch + dup //true resolvestream + % The stream isn't positionable, so read all the data now. + % Stack: filepos fndict stream + 1 index /Range get length 2 idiv 2 index /BitsPerSample get mul + 2 index /Size get { mul } forall + 7 add 8 idiv + dup 65535 le { + string 1 index exch readstring pop + } { + 1 index exch () /SubFileDecode filter /ReusableStreamDecode filter + } ifelse + exch closefile + % Stack: filepos fndict data + exch dup /DataSource 4 -1 roll put + exch PDFfile exch setfileposition +} bdef + +/.resolvefn2 { + dup length dict .copydict + dup /C0 2 copy knownoget { put } { pop pop } ifelse + dup /C1 2 copy knownoget { put } { pop pop } ifelse + dup /N 2 copy knownoget { put } { pop pop } ifelse +} bdef + +/.resolvefn3 { + dup length dict .copydict + dup /Bounds 2 copy knownoget { put } { pop pop } ifelse + dup /Encode 2 copy knownoget { put } { pop pop } ifelse + dup /Functions 2 copy oget mark exch dup { + oforce .resolvefn + } forall + counttomark -1 roll astore exch pop put +} bdef + +/.resolvefn4 { + PDFfile fileposition exch % filepos fndict + dup //true resolvestream % filepos fndict stream + exch dup length dict copy % filepos stream fndict2 + dup /Function undef % filepos stream fndict2 + exch dup token not { + () /rangecheck cvx signalerror + } if + exch token { + /rangecheck cvx signalerror + } if + % Use .bind to avoid idiom recognition. + .bind + 1 index /Function 3 -1 roll put + exch PDFfile exch setfileposition +} bdef + +/.resolvefn { % <fndict> .resolvefn <fndict'> + dup length dict .copydict + dup /Domain 2 copy knownoget { put } { pop pop } ifelse + dup /Range 2 copy knownoget { put } { pop pop } ifelse + dup /FunctionType oget //fnrdict exch get exec +} bdef + +/resolvefunction { % <fndict> resolvefunction <function> + .resolvefn + PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Function: ) print dup === flush } if } if +} bdef + +/resolvefnproc { % <fndict> resolvefnproc <proc> + resolvefunction .buildfunction +} bdef + +/resolveidfnproc { % <fndict> resolveidfnproc <proc> + dup /Identity eq { pop { } } { resolvefnproc } ifelse +} bdef + +/resolvedefaultfnproc { % <fndict> <default> resolved'fnproc <proc> + 1 index /Default eq { exch pop } { pop resolveidfnproc } ifelse +} bdef + +% ---------------- Shadings ---------------- % + +/shrdict mark + /Coords { + aload + 5 1 roll + 4 { % Bug 694542 + dup type dup /integertype ne exch /realtype ne and { + ( **** Error: replacing malformed number ') pdfformaterror pdfstring cvs pdfformaterror + (' with 0.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + 0 + } if + 4 1 roll + } repeat + 5 -1 roll + astore + } bind + /BBox { + dup dup dup aload pop normrect_elems + 5 -1 roll astore + } bind + /ColorSpace { + resolvecolorspace + } bind + /Function { + dup type /dicttype eq { + resolvefunction + } { + [ exch { oforce resolvefunction } forall ] + } ifelse + } bind + /Extend { + mark exch {oforce} forall ] + } bind +.dicttomark readonly def + +/resolveshading { % <shadingstream> resolveshading <shading> + dup /.shading_dict .knownget { + exch pop + dup /ShadingType get 4 ge { + dup /DataSource get 0 setfileposition + } if + } { + dup + PDFfile fileposition exch + mark exch { + oforce //shrdict 2 index .knownget { exec } if + } forall .dicttomark + dup /ShadingType get 4 ge { + dup dup //true resolvestream + % Make a reusable stream so that the shading doesn't + % reposition PDFfile at unexpected times. + /ReusableStreamDecode filter /DataSource exch put + } if + exch PDFfile exch setfileposition + dup 3 1 roll /.shading_dict exch put + } ifelse +} bdef +/resolvesh { % <shname> resolvesh <shading> + % <shname> resolvesh <null> + Page /Shading rget { + %% Horrible hacky fix, see /DoImage later in ths file for more information + %% + dup /ColorSpace known { + dup /ColorSpace get dup type /arraytype eq { + exch dup length dict copy exch + dup length array copy /ColorSpace exch 2 index 3 1 roll put + } {pop} ifelse + } if + + resolveshading + } { + //null + }ifelse +} bdef + +% ---------------- Halftones ---------------- % + +/spotfunctions mark + /Round { + abs exch abs 2 copy add 1 le { + dup mul exch dup mul add 1 exch sub + } { + 1 sub dup mul exch 1 sub dup mul add 1 sub + } ifelse + } bind + /Diamond { + abs exch abs 2 copy add .75 le { + dup mul exch dup mul add 1 exch sub + } { + 2 copy add 1.23 le { + .85 mul add 1 exch sub + } { + 1 sub dup mul exch 1 sub dup mul add 1 sub + } ifelse + } ifelse + } bind + /Ellipse { + abs exch abs 2 copy 3 mul exch 4 mul add 3 sub dup 0 lt { + pop dup mul exch .75 div dup mul add 4 div 1 exch sub + } { + dup 1 gt { + pop 1 exch sub dup mul exch 1 exch sub + .75 div dup mul add 4 div 1 sub + } { + .5 exch sub exch pop exch pop + } ifelse + } ifelse + } bind + /EllipseA { dup mul .9 mul exch dup mul add 1 exch sub } bind + /InvertedEllipseA { dup mul .9 mul exch dup mul add 1 sub } bind + /EllipseB { dup 5 mul 8 div mul exch dup mul exch add sqrt 1 exch sub } bind + /EllipseC { dup mul .9 mul exch dup mul add 1 exch sub } bind + /InvertedEllipseC { dup mul .9 mul exch dup mul add 1 sub } bind + /Line { exch pop abs neg } bind + /LineX { pop } bind + /LineY { exch pop } bind + /Square { abs exch abs 2 copy lt { exch } if pop neg } bind + /Cross { abs exch abs 2 copy gt { exch } if pop neg } bind + /Rhomboid { abs exch abs 0.9 mul add 2 div } bind + /DoubleDot { 2 {360 mul sin 2 div exch } repeat add } bind + /InvertedDoubleDot { 2 {360 mul sin 2 div exch } repeat add neg } bind + /SimpleDot { dup mul exch dup mul add 1 exch sub } bind + /InvertedSimpleDot { dup mul exch dup mul add 1 sub } bind + /CosineDot { 180 mul cos exch 180 mul cos add 2 div } bind + /Double { exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add } bind + /InvertedDouble { + exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add neg + } bind +.dicttomark readonly def + +/.resolveht1 { + mark exch { + oforce + 1 index /SpotFunction eq { + dup type /nametype eq + { //spotfunctions exch get } { resolvefnproc } + ifelse + } { + 1 index /TransferFunction eq { + resolveidfnproc + } if + } ifelse + } forall .dicttomark +} bdef + +/.resolveht5 { + mark exch { + oforce dup type /dicttype eq { resolvehalftone } if + } forall .dicttomark +} bdef + +/.resolveht6 { + %% resolvestream will reposition PDFfile. If we are in the middle + %% of reading a content stream from PDFfile when we execute this, + %% then reading the next buffer will read from the wrong place. We + %% must save and restore the position of PDFfile. See the definition + %% of resolvestream. Bug #695886 + PDFfile fileposition exch + mark exch { oforce } forall .dicttomark + dup dup //false resolvestream /ReusableStreamDecode filter + /Thresholds exch put + dup /TransferFunction .knownget { + resolveidfnproc + 1 index exch /TransferFunction exch put + } if + exch PDFfile exch setfileposition +} bdef + +/htrdict mark + 1 //.resolveht1 + 5 //.resolveht5 + 6 //.resolveht6 + 10 //.resolveht6 + 16 //.resolveht6 +.dicttomark readonly def + +currentdict /.resolveht1 undef +currentdict /.resolveht5 undef +currentdict /.resolveht6 undef + +/resolvehalftone { % <dict> resolvehalftone <halftone> + dup /HalftoneType oget + dup //htrdict exch .knownget { + exch pop exec + } { + =string cvs + ( **** Error: Incorrect halftone type ) exch concatstrings + (. Using defailt.\n) concatstrings pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + gsave .setdefaulthalftone currenthalftone grestore + } ifelse +} bdef + +% ---------------- Graphics state management ---------------- % + +/cmmatrix matrix def +drawopdict begin + % Graphics state stack + /q { q } def + /Q { Q } def + % Graphics state setting + /cm { //cmmatrix astore + .getpath + exch concat + newpath { exec } forall + % If inside a BT/ET block, we need to update the TextSaveMatrix + currentdict /TextSaveMatrix .knownget { + //cmmatrix exch dup concatmatrix pop + } if + % And if we ha\ve done a gsave inside a text block, we need to update + % that matrix instead. + currentdict /qTextSaveMatrix .knownget { + //cmmatrix exch dup concatmatrix pop + } if + } bdef + + /i { 1 .min setflat } bdef + /J { setlinecap } bind 0 get def + /d { setdash } bind 0 get def + /j { setlinejoin } bind 0 get def + /w { setlinewidth } bind 0 get def + /M { 1 .max setmiterlimit } bdef + /gs { gs } def +end + +% Each entry in this dictionary is +% <gsres> <value> -proc- <gsres> +/gsbg { + /BGDefault load resolvedefaultfnproc setblackgeneration +} bdef +/gsucr { + /UCRDefault load resolvedefaultfnproc setundercolorremoval +} bdef +/gstr { + dup type /arraytype eq { + { oforce /TRDefault load resolvedefaultfnproc } forall + setcolortransfer + } { + /TRDefault load resolvedefaultfnproc settransfer + } ifelse +} bdef +/gsparamdict mark + /SA { setstrokeadjust } + /OP { 1 index /op known not { dup op } if OP } + % The PDF 1.3 specification says that the name /Default is only + % recognized for {BG,UCR,TR}2. However, PDF 1.3 files produced + % by Adobe Acrobat Distiller 4.0 for Windows use the name /Default + % with the older keys, so we have to implement this. + /BG { 1 index /BG2 known { pop } { gsbg } ifelse } + /UCR { 1 index /UCR2 known { pop } { gsucr } ifelse } + /TR { 1 index /TR2 known { pop } { gstr } ifelse } + + % Some functions used to implement phases of HT and HTP + /sethalftones { + dup /Default eq { + pop .setdefaulthalftone + } { + resolvehalftone sethalftone + } ifelse + } bdef + /sethalftonephases { + /sethalftonephase where { pop aload pop sethalftonephase } { pop } ifelse + } bdef + + /HT { + dup sethalftones .swapcolors sethalftones .swapcolors + % the transfer function may dependent on the halftone, so make sure + % it is set if included in the graphic state (otherwise this is + % subject to order of a dictionary forall, which is unpredictable) + dup /TR2 .knownget { + dup /Default eq { oforce gsparamdict /TR2 get exec } { pop } ifelse + } { + dup /TR .knownget { + /dup /Default eq { oforce gsparamdict /TR get exec } { pop } ifelse + } if + } ifelse + } + /HTP { + % HTP may be present even if this isn't a DPS interpreter. + dup sethalftonephases .swapcolors sethalftonephases .swapcolors + } + % PDF 1.3 + % The font is an indirect reference, not a resource name + /Font { aload pop exch oforce resourcefont exch Tf } + /LW { setlinewidth } + /LC { setlinecap } + /LJ { setlinejoin } + /ML { 1 .max setmiterlimit } + /D { aload pop setdash } + /RI { ri } + /op { op } + /OPM { OPM } + /BG2 { gsbg } + /UCR2 { gsucr } + /TR2 { gstr } + /FL { 1 .min setflat } + /SM { + % SM may be present even if this is only a Level 2 interpreter. + /setsmoothness where { pop setsmoothness } { pop } ifelse + } + % PDF 1.4 + % All of these require the "transparency" feature in the interpreter. + /ca { ca } + /CA { CA } + /SMask { + {gssmask} PDFSTOPONERROR { exec //false } { stopped } ifelse + { + pop (\n **** Error in SMask during ExtGState. Ignoring the mask, output may be incorrect.\n) + pdfformaterror + } if + } + /AIS { AIS } + /BM { BM } + /TK { TK } +.dicttomark readonly def +/gs { % <gsres> gs - + Page /ExtGState rget { + % We keep the dictionary on the stack during the forall so that + % keys that interact with each other have access to it. + dup { + oforce exch gsparamdict exch .knownget { exec } { pop } ifelse + } forall pop + } if +} bdef + +% ------ Transparency support ------ % + +/gssmask { + { + dup type /dicttype eq + { + dup /G knownogetdict + {pop} + { + ( **** Error: Ignoring invalid transparency SMask group\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + % replace the invalid SMask object + pop /None + } ifelse + } if + + dup /None eq 1 index //null eq or PDFusingtransparency not or { + pop //null + SoftMask //null ne { + % get rid of the current SMask (Bug 695471) + false % colorspace not set + << /Subtype /None >> % Special type for this purpose + 0 0 0 0 % fake BBox + .begintransparencymaskgroup + } if + exit + } if + % Preprocess the SMask value into a parameter dictionary for + % .begintransparencymaskgroup, with added /BBox and /Draw keys. + mark exch % Stack: mark smaskdict + dup /S oget /Subtype exch 3 2 roll + % Stack: mark ... smaskdict + dup /BC knownoget { + dup /Background exch 4 2 roll + 1 index /G oget /Group knownoget not { + ( **** Error: Ignoring a transparency group XObject without /Group attribute.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + cleartomark //null exit + } if + gsave //nodict begin + /CS knownoget { + resolvecolorspace dup setgcolorspace csput + } if + aload pop setcolor [ currentgray ] + end grestore + /GrayBackground exch 3 2 roll + } if + dup /TR knownoget { + dup /Identity eq { + pop + } { + resolvefnproc /TransferFunction exch 3 2 roll + } ifelse + } if + dup /G oget + dup /BBox oget oforce_array + 1 index /Matrix knownoget { + oforce_array .bbox_transform 4 array astore + } if + /BBox exch 4 2 roll + % Because we don't execute the group form stream until we find + % out whether we're actually going to draw through it, we need + % to save the current gstate with the other parameters, so + % we can subsequently execute it in the correct graphics state. + % We need to concatenate the Matrix in this gstate as per the PDF + % spec 7.5.4 (p. 552 in the PDF 1.7 Ref) (bug 694455). + gsave + dup /Matrix knownoget { + matrix currentmatrix matrix concatmatrix setmatrix + } if + /GroupGState gstate currentgstate 6 2 roll + grestore + /GroupMat matrix currentmatrix 8 2 roll + /GroupExtGState 1 dict + //SetGroupExtGStateDict + { + exch dup where + { + exch get 2 index 3 1 roll put + } + { + pop pop + } ifelse + } forall + 10 2 roll + /.execmaskgroup cvx 2 packedarray cvx /Draw exch 3 2 roll + pop + .dicttomark + exit + } loop + SMask +} bdef + +% Functions specific to the Device* colorspaces to force the switch to +% the Device* colorspace so that the SMask will not get a CIEBased* colorspace +% in the case when UseCIEColor changes the Device* colorspace to something else. +% Also see the logic in pdf_main.ps:pdfopen that similarly defines these resources. +/forceDefaultCS << + { + currentcolorspace setcolorspace % this will switch to Device colorspace + } bind + /DeviceGray exch + /DeviceRGB 1 index + /DeviceCMYK 1 index +>> +def + +% This procedure is called to actually render the soft mask. +/.execmaskgroup { % <masknum> <paramdict> <formdict> .execmaskgroup - + % Save our place in PDFfile. Do not use gsave-grestore when creating + % a soft mask with .begintransparencygroup because high level devices + % need to modify the graphic state by storing the soft mask ID. + % Save the ExtGState (//nodict begin) BEFORE changing the colorspace + //nodict begin + matrix currentmatrix 4 1 roll + mark currentcolor counttomark dup 4 add exch roll pop + currentcolorspace 4 1 roll .getuseciecolor 4 1 roll + currentuserparams /OverrideICC get 4 1 roll + mark /OverrideICC true .dicttomark setuserparams + + % We can't simply set the group's gstate here because + % we can't use gsave/grestore. So we actually set it + % in .execgroup. But the matrix needs set here for + % .begintransparencymaskgroup to correctly work. + % It might seem we should also set the colorspace + % in case the group doesn't have one, *but* empirical + % suggests that is not the case - fts_26_2600.pdf and + % fts_26_2603.pdf render incorrectly if we set the + % colrospace + 1 index /GroupMat .knownget { setmatrix } if + + PDFfile fileposition 4 1 roll + % We have to select the group's color space so that the + % background color will be interpreted correctly. + % [save/restore]DefaultCS make sure that the SMask logic sees + % the Device* spaces, not CIEBased* that UseCIEColor may have + % established. + //false .setuseciecolor % SMask gets processed without UseCIEColor + dup /Group oget /CS knownoget { + resolvecolorspace dup setgcolorspace csput + //true % use currentcolorspace + } { + % inheriting the colorspace -- make sure Device* spaces are not CIEBased + forceDefaultCS currentcolorspace 0 get .knownget { exec } if + //false % no defined colorspace + } ifelse + 3 -1 roll dup + dup 4 1 roll /BBox get aload pop .begintransparencymaskgroup + exch dup /Resources knownoget { oforce } { 2 dict } ifelse + 3 -1 roll dup /GroupGState .knownget { 2 index /GroupGState 3 -1 roll put} if + /GroupExtGState .knownget { 1 index /GroupExtGState 3 -1 roll put} if + exch //false resolvestream + 1 index exch .execgroup + % We have to remove these in case the Form XObject is subsequently used as + % a form rather than a group - they remain in the paramdict for the SMask + % so this will all still work if the SMask is re-evaluated. + dup /GroupGState undef + /GroupExtGState undef + .endtransparencymask + PDFfile exch setfileposition + mark exch /OverrideICC exch .dicttomark setuserparams + .setuseciecolor setcolorspace setcolor + setmatrix + end % restore colorspace, color and ExtGState (end) + /SoftMask where pop /SoftMask //true put % special setting to tell us it has been rendered +} bdef + +% Paint a Form+Group XObject, either for a transparency mask or for a Do. +/.execgroup { % <resdict> <stream> .execgroup - + pdfemptycount 3 1 roll + /pdfemptycount count 3 sub store + gsave //nodict begin + + % We have to set the gstate correctly for lazy evaluation of a softmask group. + % we also must preserve the color(space) as setup in .execmaskgroup. + % This stuff must be done here, as .execmaskgroup can't use gsave/grestore to + % manipulate the gstates, due to the requirements of .begintransparencymaskgroup. + % We also must set the ExtGState values. + % It may seem redundant to do the color(space) twice (once here and once in + % .execmaskgroup) but we have to set it in .execmaskgroup for the background + % color and set it here once in the correct gstate. + mark currentcolor currentcolorspace counttomark 2 add index dup + /GroupGState .knownget { setgstate } if + /GroupExtGState .knownget { { exch exec } forall } if + setcolorspace setcolor pop + newpath //null SMask + 1 .setopacityalpha 1 .setshapealpha + 1 CA 1 ca + /Compatible .setblendmode + % Execute the body of the Form, similar to DoForm. + pdfopdict .pdfruncontext + end grestore + /pdfemptycount exch store +} bdef + +/.beginformgroup { % groupdict bbox .beginformgroup - + exch mark exch % bbox mark groupdict + dup /CS knownoget { resolvecolorspace dup setgcolorspace /CS exch 3 2 roll} if + dup /I knownoget { /Isolated exch 3 2 roll } if + dup /K knownoget { /Knockout exch 3 2 roll } if + pop .dicttomark + % Stack: bbox paramdict + exch aload pop + .begintransparencygroup +} bdef + +% .paintgroupform implements the Form PaintProc in the case where the +% Form XObject dictionary includes a Group key. See .paintform below. +/.paintgroupform { % <resdict> <stream> <formdict> .paintgroupform - + dup /Group oget exch /BBox oget + % Stack: resdict stream groupdict bbox + .beginformgroup + .execgroup + .endtransparencygroup +} bdef + +% Make an ImageType 103 (soft-masked) image. +/makesoftmaskimage { % <datasource> <imagemask> <SMask> makesoftmaskimage + % <datasource> <imagemask>, updates currentdict = + % imagedict + % See the ImageType 3 case of makemaskimage below. + % SMask is a stream, another Image XObject. + % Stack: datasource imagemask(false) smaskstreamdict + PDFfile fileposition exch + dup /Matte knownoget { /Matte exch def } if + dup length dict makeimagedict pop + % In order to prevent the two data sources from being + % aliased, we need to make at least one a reusable stream. + % We pick the mask, since it's smaller (in case we need to + % read all its data now). + % Stack: datasource imagemask(false) savedpos + % maskdict is currentdict + /DataSource DataSource mark + /Intent 1 + /AsyncRead //true + .dicttomark {.reusablestreamdecode} stopped {pop} if def + PDFfile exch setfileposition + currentdict end currentdict end + 5 dict begin + /ImageType 103 def + /DataDict exch def + dup /InterleaveType 3 put + DataDict /Matte knownoget { + /Matte exch def + } if + AlphaIsShape { /ShapeMaskDict } { /OpacityMaskDict } ifelse exch def + /ColorSpace DataDict /ColorSpace get def +} bdef + +% ---------------- Color setting ---------------- % + +/01_1 [0 1] readonly def +/01_3 [0 1 0 1 0 1] readonly def +/01_4 [0 1 0 1 0 1 0 1] readonly def + +% The keys here are resolved (PostScript, not PDF) color space names. +/csncompdict 9 dict begin + /DeviceGray { pop 1 } bdef + /DeviceRGB { pop 3 } bdef + /DeviceCMYK { pop 4 } bdef + /CIEBasedA //DeviceGray def + /CIEBasedABC //DeviceRGB def + /CalGray //DeviceGray def + /CalRGB //DeviceRGB def + /Lab //DeviceRGB def + /ICCBased { 1 oget /N oget } bdef + /Separation //DeviceGray def + /DeviceN { 1 oget length } bdef + /Indexed //DeviceGray def +currentdict end readonly def + +% <colorspace> csncomp <n> +/csncomp { + dup dup type /arraytype eq { 0 oget } if + //csncompdict exch get exec +} bdef + +currentdict /csncompdict undef + +/ICCBased-resolve { + PDFfile fileposition exch + dup dup 1 oget + mark exch { oforce } forall .dicttomark + dup dup //true resolvestream + /ReusableStreamDecode filter /DataSource exch put + + % Check that the number of components (/N) defined in the ICCBased + % dictionry matches the actual profile. Bug #696120 + dup /N get + 1 index + %% If we get an error reading the profile, just assume that /N is correct + %% If its genuinely faulty we will use an alternate based on /N. + {.numicc_components} stopped {pop dup} if + dup 3 -1 roll ne { + %% /N and the actual number of components don't match. Ensure + %% that we have a valid number of components from the ICC + %% profile. Certain kinds of profile can't determine the numebr of components + %% and in ths case we must not override the /N value. + dup 0 gt { + ( **** Error: ICCbased space /N value does not match the ICC profile.\n) pdfformaterror + ( Using the number of channels from the profile.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + 1 index dup /N get /OrigN exch put + 1 index exch /N exch put + }{ + pop + } ifelse + } { + pop + } ifelse + + 1 exch put + exch PDFfile exch setfileposition + % Resolve alternate color space + dup 1 get % Get colorspace dictionary + dup /Alternate .knownget { % Check for alternate color space + oforce resolvecolorspace /Alternate exch put % resolve and replace + } { + pop % remove colorspace dictionary + } ifelse +} bdef + +/csrdict 13 dict begin + /DeviceGray { } bdef + /DeviceRGB { } bdef + /DeviceCMYK { } bdef + + /CalGray { 1 oget [ exch /CalGray exch ] } bdef + /CalRGB { 1 oget [ exch /CalRGB exch ] } bdef + /Lab { 1 oget [ exch /Lab exch ] } bdef + + /CalCMYK { + pop /DeviceCMYK % not defined by Adobe + } bdef + + /ICCBased { + dup 1 get type /dicttype ne { % don't resolve more than once + ICCBased-resolve + } if + } bdef + + /Separation { + aload pop exch oforce resolvecolorspace + % Contrary to PDF manuals up to v.1.5, Acrobat Distiller 3.01 + % can use /Identity name here instead of a function. + exch oforce resolveidfnproc + + %% Make sure the ink name is not an indirect object.... + 3 -1 roll oforce 3 1 roll + + 4 array astore + } bdef + + /DeviceN { + [ exch aload pop ] % Copy into a new array + dup dup 1 oget % Resolve Names array + [ exch { oforce } forall ] % resolve each of the names + 1 exch put + dup dup 2 oget resolvecolorspace + 2 exch put + dup dup 3 oget resolvefnproc + 3 exch put + dup length 4 gt { % Check for attributes dict + dup dup 4 oget % devn_array devn_array attr_dict + dup /Colorants knownoget % Check for Colorants Dict + { % Create a new attribute dict with only a Colorants dict entry. + % Resolve all of the Colorant dict entries. This is needed + % to prevent a conflict if we attempt to resolve the tint + % transform functions of the Colorant color spaces multiple + % times. + exch pop % Remove old attributes dict + << exch % Start new attributes dict + % Build new Colorants dict with resolved entries + << exch { oforce resolvecolorspace } forall >> + /Colorants exch >> % Finish new attributes dict + } if + 4 exch put % Put resolved or new attributes dict + } if + } bdef + + /Indexed { + aload pop + %% Resolve 'hival' in case it is an indirect reference. This is kind of + %% dumb, it just makes the file bigger, but it *is* legal. + 3 1 roll oforce 3 -1 roll + + 1 index -1 eq { + exch pop 255 exch + ( **** Error: Highest color index given as -1. Assuming this actually means 255.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } if + 3 -1 roll oforce resolvecolorspace + % Stack: /Indexed hival lookup basespace + % If the underlying space is a Lab space, we must scale + % the output of the lookup table as part of DecodeABC. + dup dup type /arraytype eq { 0 get } if /CIEBasedABC eq { + dup 1 get /DecodeLMN known { + 1 get dup length dict copy + begin /DecodeABC [ 0 2 4 { + RangeABC 1 index 1 add get RangeABC 2 index get sub /mul load + RangeABC 3 index get /add load + DecodeABC 6 -1 roll 2 idiv get [ 6 1 roll aload pop ] cvx + } for ] def + /RangeABC //01_3 def + currentdict end /CIEBasedABC exch 2 array astore + } if + } if + 3 1 roll % Stack: /Indexed csp comp table + oforce dup type /stringtype ne { + % The color lookup table is a stream. + % Get its contents. Don't lose our place in PDFfile. + % Stack: /Indexed basespace hival lookup + PDFfile fileposition 5 1 roll + dup /Filter oknown not { % For Bug691941.pdf and similar lossage + dup /Length knownoget not { 0 } if + } { + 0 + } ifelse + % Stack: filepos /Indexed basespace hival lookup Length + 2 index 1 add + % Stack: filepos /Indexed basespace hival lookup Length len + 4 index csncomp mul .max string + % Stack: filepos /Indexed basespace hival lookup (...) + exch //true resolvestream + 1 index readstring not { + % The string is padded with 0s + ( **** Error: Short look-up table in the Indexed color space was padded with 0's.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } if + pop + % Stack: filepos /Indexed basespace hival (...) + PDFfile 6 -1 roll setfileposition + } if + 4 array astore + % Stack: [filepos /Indexed basespace hival (...)] + % Replace the PDFColorSpace with the Indexed space if needed. + dup 1 get + dup type /arraytype eq { + dup length 2 ge { + dup 1 get type /dicttype eq { + dup 1 get /PDFColorSpace known { + dup 1 get /PDFColorSpace 3 index put + } if + } if + } if + } if pop + } bdef + + /I { % Bug 689815 + ( **** Error: The name /Indexed cannot be abbreviated to /I in the color space\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + dup 0 /Indexed put + //Indexed exec + } bdef + + /Pattern { + dup type /nametype ne { + dup length 1 gt { + 1 oget resolvecolorspace + /Pattern exch 2 array astore + } if + } if + } bdef + +currentdict end readonly def + +/cssubst { % <csname> cssubst <cspace'> true + % <csname> cssubst false + dup resolvecolorspace + dup 1 index ne { exch pop //true } { pop pop //false } ifelse +} bdef + +/csnames mark + /DeviceGray dup /DeviceRGB dup /DeviceCMYK dup /Pattern dup +.dicttomark readonly def +/csresolve { % <csresourcename> csresolve <cspace> <true> | <false> + dup type /nametype ne { + (\n **** Error: CS/cs (setcolorspace) operand not a name: ) pdfformaterror + dup stderrfile dup 3 -1 roll write==only flushfile + ( ****\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + dup type /arraytype eq { % Adobe InDesign + PDF Library has array + resolvecolorspace + } if //true + } { + dup Page /ColorSpace rget { + exch pop resolvecolorspace //true + } { + //csnames 1 index known { + //true + } { + ( **** Error: Undefined space resource: /) + exch .namestring concatstrings (\n) concatstrings pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + //false + } ifelse + } ifelse + } ifelse +} bdef + +/resolvecolorspace { % <cspace> resolvecolorspace <cspace'> + dup type /dicttype eq { + dup /N known { + ( **** ICCBased color space is a bare stream dictionary\n) pdfformatwarning + [ /ICCBased 3 -1 roll ] ICCBased-resolve exec + //false + } { + dup /ColorSpace knownoget { + ( **** Error: unrecognised color space <</ColorSpace /Device...>>\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + exch pop //true + } { + //true + } ifelse + } ifelse + } { + //true + } ifelse { + dup dup type /arraytype eq { 0 get } if + //csrdict exch .knownget { + exec dup type /nametype ne { dup length 1 eq { 0 get } if } if + } { + dup type /nametype eq { + csresolve not { /DeviceRGB } if % Arbitrary + } { + csset exch pop + } ifelse + } ifelse + } if +} bdef + +/scresolve { % <c0> ... scresolve <multi> + % We can't really make sc[n] and SC[N] work, because + % the color space information isn't available at + % conversion time; so we hack it by assuming that + % all the operands on the stack are used, and that + % if the top operand is a name, it's a Pattern resource. + dup type /nametype eq + { Page /Pattern rget { resolvepattern } { //null } ifelse } + if + dup type /dicttype eq { + % Check the PaintType, if any (shading patterns don't + % have one). + dup /PaintType knownoget { 2 eq } { //false } ifelse + } { + .pdfcount 1 gt + } ifelse +} bdef + +%% Bug #696017 When we begin a text block, we switch to a special set of marking operations +%% for paths, these ops don't use the current CTM, but the 'SavedTextMatrix', in order to +%% correctly position marks which are illegally present inside a text block. But, if we are +%% executing a PaintProc (eg for a pattern) we *don't* want to do that or the pattern will be wrong. +%% So we moved the .pdfpaintproc to .actual_pdfpaintproc, and redefined .pdfpaintproc to test +%% the current value of /m. We always switch to the regular marking operations, but if the definition +%% of /m at the start of the PaintProc was a special text version, then we switch back to that after we +%% finished running the PaintProc. + +/.actual_pdfpaintproc { % <patdict> <resdict> .pdfpaintproc - + PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Begin PaintProc) print dup === flush } if } if + PDFfile fileposition 3 1 roll + q + 1 index /PaintType oget 1 eq { + % For colored patterns, set default fill and stroke colors. + 0 g 0 G + } { + % For uncolored patterns, we have to unbind the current + % color and color space before running the PaintProc. + //null sc1 //null SC1 + } ifelse + + % Save old values on opstack, set pdfemptycount to new value. + pdfemptycount countdictstack mark + + /pdfemptycount count 3 sub def 5 3 roll + % + % Stack: ... <old emptycount> <dictcount> mark <patdict> <resdict> + % | + % New empty count points here -----------+ + + exch //false resolvestream pdfopdict .pdfruncontext + cleartomark + + //false + { countdictstack + 2 index le { exit } if + currentdict /n known not or + Q + } loop { + ( **** Error: Pattern stream has unbalanced q/Q operators \(too many q's\)\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } if + pop + + % restore pdfemptycount + /pdfemptycount exch def + + Q + PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%End PaintProc) print dup === flush } if } if + PDFfile exch setfileposition +} bdef + +/.pdfpaintproc { + %% Get the /m from pdfopdict (must be present) + %% and check its a packedarray + pdfopdict /m get dup type /packedarraytype eq { + %% get the initial element of the packedarray + %% and check its a name + 0 get dup type /nametype eq { + %% If the name is inside_text_m then we are in a text block + /inside_text_m eq + }{ + pop false + } ifelse + }{ + pop false + } ifelse + %% rearrange the operands, move the boolean to the back + 3 1 roll + %% Uncopnditionally use the normal marking ops + switch_to_normal_marking_ops + .actual_pdfpaintproc + %% If we were in a text block, restore the text marking ops. + { + switch_to_text_marking_ops + } if +}bdef + +/resolvepattern { % <patternstreamdict> resolvepattern <patterndict> + % Don't do the resolvestream now: just capture the data + % from the file if necessary. + dup length dict copy + dup /FilePosition .knownget { + 1 index /File get dup fileposition 3 1 roll + % Stack: dict savepos pos file + dup 3 -1 roll setfileposition + dup 3 index /Length knownoget { + dup 65535 le { + dup 0 eq { + pop pop () + } { + string readstring pop + } ifelse + } { + () /SubFileDecode filter /ReusableStreamDecode filter + } ifelse + } { + 0 (endstream) /SubFileDecode filter /ReusableStreamDecode filter + } ifelse + % Stack: dict savepos file string + 3 1 roll exch setfileposition + 1 index /File 3 -1 roll put + dup /FilePosition undef + } if + dup /Shading knownoget { + resolveshading 1 index /Shading 3 -1 roll put + } if + dup /PaintProc [ + % Bind the resource dictionary into the PaintProc. + 2 index /Resources knownoget { oforce } { 0 dict } ifelse + /.pdfpaintproc cvx + ] cvx put + dup /BBox 2 copy knownoget { normrect put } { pop pop } ifelse + dup /.pattern_uses_transparency 1 index patternusestransparency put + PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Pattern: ) print dup === flush } if } if +} bdef + +/ignore_color_op ( **** Error: Ignoring a color operation in a cached context.\n Output may be incorrect.\n) readonly def + +drawopdict begin + /g { .incachedevice { % Bug 689302 + pop //ignore_color_op pdfformaterror + } { + /DeviceGray cssubst { cs sc1 } { g } ifelse + } ifelse + } bdef + + /rg { .incachedevice { + pop pop pop //ignore_color_op pdfformaterror + } { + /DeviceRGB cssubst { cs sc* } { rg } ifelse + } ifelse + } bdef + + /k { .incachedevice { + pop pop pop pop //ignore_color_op pdfformaterror + } { + k + } ifelse + } bdef + + /cs { .incachedevice { + pop //ignore_color_op pdfformaterror + } { + csresolve { cs } if + } ifelse + } bdef + + /sc { .incachedevice { + .pdfcount { pop } repeat //ignore_color_op pdfformaterror + } { + scresolve { sc*_and_set } { sc1_and_set } ifelse + } ifelse + } bdef + + /scn /sc load def + + /G { .incachedevice { + pop //ignore_color_op pdfformaterror + } { + /DeviceGray cssubst { CS SC1 } { G } ifelse + } ifelse + } bdef + + /RG { .incachedevice { + pop pop pop //ignore_color_op pdfformaterror + } { + /DeviceRGB cssubst { CS SC* } { RG } ifelse + } ifelse + } bdef + + /K { .incachedevice { + pop pop pop pop //ignore_color_op pdfformaterror + } { + K + } ifelse + } bdef + + /CS { .incachedevice { + pop //ignore_color_op pdfformaterror + } { + csresolve { CS } if + } ifelse + } bdef + + /ri { .incachedevice { + pop //ignore_color_op pdfformaterror + } { + ri + } ifelse + } bdef + + /SC { .incachedevice { + .pdfcount { pop } repeat //ignore_color_op pdfformaterror + } { + scresolve { SC*_and_set } { SC1_and_set } ifelse + } ifelse + } bdef + + /SCN /SC load def +end + +currentdict /ignore_color_op undef + +% ---------------- Paths ---------------- % + +drawopdict begin + % Path construction + /m { { moveto } stopped { count pdfemptycount sub 2 .min { pop } repeat 0 0 moveto } if } bdef + /l { { lineto } stopped { count pdfemptycount sub 2 .min { pop } repeat } if } bdef + /c { { curveto } stopped { count pdfemptycount sub 6 .min { pop } repeat } if } bdef + + /v { count pdfemptycount sub 4 ge { + { currentpoint 6 2 roll curveto } stopped { count pdfemptycount sub 6 .min { pop } repeat } if + } { + count pdfemptycount sub { pop } repeat + } ifelse + } bdef + /y { { 2 copy curveto } stopped { count pdfemptycount sub 6 .min { pop } repeat } if } bdef + + /re { + 4 2 roll moveto exch dup 0 rlineto 0 3 -1 roll rlineto neg 0 rlineto + closepath + } bdef + + /h { closepath } bind 0 get def + % Path painting and clipping + /n { n } def + /S { S } def + /s { s } def + /f { f } def + /f* { f* } def + /B { B } def + /b { b } def + /B* { B* } def + /b* { b* } def + /W { W } def + /W* { W* } def + + /sh_save 1 array def + /sh_group << /Subtype /Group /Isolated //true >> readonly def + + /do_shade { + 0 .setoverprintmode + { dup /.shading .knownget { + exch pop + } { + .buildshading + } ifelse + .shfill + } stopped { + pop + ( **** Error: Ignoring invalid smooth shading object, output may be incorrect.\n) + pdfformaterror + } if + } bdef + + /sh { + OFFlevels length 0 eq { + setfillstate resolvesh + //sh_save 0 save put + PDFusingtransparency { + SoftMask //null ne { + //sh_group + 1 index /BBox knownoget { + { oforce } forall + } { + gsave clippath pathbbox grestore + } ifelse + .begintransparencygroup + } if + dup checkOPtrans exch 1 index { + % We need to push a non-isolated, non-knockout transparency group and + % perform the operation in CompatibleOverprint mode, then end the + % transparency group. Do the begintransparencygroup step here. + mark /Subtype /Group /Isolated //false .dicttomark + 1 index /BBox knownoget { + { oforce } forall + } { + gsave clippath pathbbox grestore + } ifelse + .begintransparencygroup + exch .currentblendmode exch .currentopacityalpha exch 4 -1 roll % save current values + /CompatibleOverprint .setblendmode 1 .setopacityalpha + } if + //do_shade exec + { + .endtransparencygroup .setopacityalpha .setblendmode % end the CompatibleOverprint group + } if + SoftMask //null ne { + .endtransparencygroup + } if + } { + //do_shade exec + } ifelse + //sh_save 0 get restore + } { + pop + } ifelse + } bdef + currentdict dup /sh_save undef /sh_group undef +end + +% ---------------- XObjects ---------------- % + +/xobjectprocs mark % <dict> -proc- - + /Image { DoImage } + /Form { DoForm } + /PS { DoPS } +.dicttomark readonly def + +% Note that the keys in defaultdecodedict are resolved (PostScript, not PDF) +% color space names. +/defaultdecodedict mark + /DeviceGray { pop //01_1 } bind + /DeviceRGB { pop //01_3 } bind + /DeviceCMYK { pop //01_4 } bind + /CIEBasedA { 1 get /RangeA knownoget not { //01_1 } if } bind + /CIEBasedABC { 1 get /RangeABC knownoget not { //01_3 } if } bind + /CalGray { pop //01_1 } bind + /CalRGB { pop //01_3 } bind + /Lab { 1 get /Range knownoget not { [-100 100 -100 100] } if } bind + /ICCBased { + 1 oget dup /Range knownoget { + exch pop + }{ + /N get [ exch {0 1} repeat ] readonly + } ifelse + } bind + /Separation { pop //01_1 } bind + /DeviceN { + 1 oget length [ exch {0 1} repeat ] readonly + } bind + /Indexed { + pop [ 0 1 BitsPerComponent bitshift 1 sub ] + } bind +.dicttomark readonly def + +/checkaltimage { % <resdict> checkaltimage <resdict[']> + Printed { + dup /Alternates knownoget { + { + dup /DefaultForPrinting knownoget { + { + /Image oget exch pop exit + } { + pop + } ifelse + } { + pop + } ifelse + } forall + } if + } if +} bdef + +% <string> <index> getu16 <integer> +/getu16 { + 2 copy get 8 bitshift 3 1 roll 1 add get add +} bind def + +% <string> <index> getu32 <integer> +/getu32 { + 2 copy getu16 16 bitshift 3 1 roll 2 add getu16 add +} bind def + +/jp2_csp_dict mark + 12 { /DeviceCMYK } % CMYK + 14 { [ /Lab << /WhitePoint [ 0.9505 1 1.0890 ] readonly >> ] } % LAB, WhitePoint == D65 + 16 { /sRGBICC /ColorSpace findresource } bind + 17 { /sGrayICC /ColorSpace findresource } bind + 18 3 index % YCC is converted to RGB +% 19 % CIEJab not supportec by PDF 1.7 +% 20 % e-sRGB +% 21 % ROMMRGB +% 24 % e-sYCC +.dicttomark readonly def + +% Process jp2 blocks (aka boxes). All procedures have the signature +% <file> <length> -> ... <file> <flush_length> +/jp2_tag_dict 10 dict begin + + /jp2h { % descend into a sub-stream, don't return. + () /SubFileDecode filter 0 + } bdef + + /ihdr { + 14 sub % file len-14 + 1 index (1234567890abcd) readstring pop % file len-14 (14) + /JPXComponents 1 index 8 getu16 % file len-14 (14) /JPXComponents NC + def % file len-14 (14) + 10 get + %% If the BPC is 255 then each component has variable depth + %% we can't handle this, but JasPer is known to produce + %% images whcih declare this, but are actually all equal, we cater + %% for that in the bpcc box below. + dup 16#FF eq not { + 16#7F and 1 add + dup 12 eq { pop 16 } if + /BitsPerComponent exch def % file len-14 + } {pop} ifelse + } bdef + + %% if the ihdr has a BPC of 255 then we get a bpcc box which + %% gives the bpc for each component individually. We cannot + %% actually deal with differing component depths, but it + %% seems JasPer produces images with this box where all the + %% component depths are in fact the same. + /bpcc { + JPXComponents sub + 1 index JPXComponents string readstring pop + dup 0 get /BitsPerComponent exch def + 1 1 JPXComponents 1 sub { + 1 index exch get BitsPerComponent eq not { + ( **** Error: JPX image colour channels do not all have the same colour depth\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } if + } for + + pop + /BitsPerComponent BitsPerComponent 1 add def + } bdef + + /colr { + currentdict /ColorSpace known not { + 3 sub + 1 index (123) readstring pop % file len-3 (3) + 0 get dup 1 eq { + pop 4 sub % file len-7 + 1 index (1234) readstring pop % file len-16 (4) + 0 getu32 % file len-16 enum + //jp2_csp_dict exch .knownget { + exec /ColorSpace exch def % file len-7 + } { + ( **** Error: Unknown enumerated color space in JPX stream.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + } { + dup 2 eq exch 3 eq or { + 1 index exch () /SubFileDecode filter /ReusableStreamDecode filter + /JPXICC exch def + 0 % file 0 + } { + ( **** Error: Unknown color space method in JPX stream.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + } ifelse + } if + } bdef + + % Palette colors are decoded by the library. + /pclr { + 4 sub + 1 index (1234) readstring pop + 3 get 16#7F and 1 add + /BitsPerComponent exch def + } bdef + + /cdef { + pop + dup (12) readstring pop + 0 getu16 { + dup (123456) readstring pop + 2 getu16 + dup 3 lt { + { /JPXColors /JPXOpacity /JPXPremult } exch get + currentdict 1 index .knownget { 1 add } { 1 } ifelse def + } { + pop + } ifelse + } repeat + 0 + } bdef + +currentdict end readonly def + +% Parse jp2 file format to get color space and image depth info. +% <file> get_jp2_csp - +/get_jp2_csp { + { + dup (01234567) readstring pop % f (LBoxTBox) + dup length 8 lt { + pop exit + } if + dup 4 4 getinterval exch % f (TBox) (LBoxTBox) + 0 getu32 % f (TBox) LBox + dup 0 eq { + pop pop exit % cannot happen + } { + dup 1 eq { + pop 1 index (01234567) readstring pop + 4 getu32 % f (TBox) LBox + 16 sub + } { + 8 sub + } ifelse + } ifelse % f (TBox) LBox-8..16 + + PDFDEBUG { + 2 copy 2 packedarray //== exec % f (TBox) LBox-8..16 + } if + + //jp2_tag_dict 3 -1 roll .knownget { + exec + } if % f flush + + dup 0 ne { + 1 index exch % f f flush + () /SubFileDecode filter flushfile % skip unwanted blocks + } { + pop + } ifelse + } loop + pop +} bind def + +currentdict /jp2_tag_dict .undef +currentdict /jp2_csp_dict .undef + +% Add a key-value pair to the last /DecodeParms dictionary +% Copy the objects to avoid spoiling shared ones. +% <resdict> <key> <value> -> <resdict> +/add-to-last-param { + 2 index /DecodeParms knownoget { + dup {} eq { + pop //false + } { + //true + } ifelse + } { + //false + } ifelse { + dup type /arraytype eq { + [ exch { oforce } forall + dup //null eq { pop 1 dict } if + ] + dup dup length 1 sub get % <resdict> <key> <value> [] <<>> + } { + dup length 1 add dict copy dup % <resdict> <key> <value> <<>> <<>> + } ifelse + 4 2 roll put % <resdict> obj + } { + % <resdict> <key> <value> + mark 3 1 roll .dicttomark % <resdict> obj + 1 index /Filter knownoget { + dup type /arraytype eq { + length array % <resdict> obj [...] + dup dup length 1 sub % <resdict> obj [...] [...] len-1 + 4 -1 roll put % <resdict> [... obj] + } { + pop + } ifelse + } if + } ifelse + 1 index exch + /DecodeParms exch put % <resdict> +} bdef + +/last-ditch-bpc-csp { + currentdict /BitsPerComponent oknown not { + ( **** Error: image has no /BitsPerComponent key; assuming 8 bit.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + /BitsPerComponent 8 def + } if + + currentdict /ColorSpace knownoget not { + dup /ColorSpace knownoget not { + ( **** Error: image has no /ColorSpace key; assuming /DeviceRGB.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + /DeviceRGB + } if + } if + resolvecolorspace + + %% This section is to deal with the horrible pair of files in Bug #696690 and Bug #696120 + %% These files have ICCBased spaces where the value of /N and the number of components + %% in the profile differ. In addition the profile in Bug #696690 is invalid. In the + %% case of Bug #696690 the /N value is correct, and the profile is wrong, in the case + %% of Bug #696120 the /N value is incorrect and the profile is correct. + %% We 'suspect' that Acrobat uses the fact that Bug #696120 is a pure image to detect + %% that the /N is incorrect, we can't be sure whether it uses the profile or just uses + %% the /N to decide on a device space. What we now do is; If the /N and device profile + %% number of components don't match, we assume the device profile is correct and patch + %% /N to be the same as the profile (see /ICCBased-resolve), but we save the original + %% value of /N in /OrigN. In setcolor, if the space is a genuine ICCBased space + %% (not a replacement for a device profile) we call set_dev_color which will actually + %% exercise the profile. If that fails we return an error. Here we run setcolor in a + %% stopped context, and if it fails we check to see if there is a /OrigN (ths occurs + %% only if the /N was different to the number of components in the profile). If there + %% is a /OrigN then prefer that to the profile, otherwise they agreed, so just use + %% /N and select a device space. If we can't select a device space with the correct + %% number of components, give up and throw an error. See also 'Cdict' in pdf_ops.ps. + dup type /arraytype eq { + dup 0 get /ICCBased eq { + gsave + dup setcolorspace dup 1 get /N get + 1 sub mark exch 0 1 3 -1 roll + {pop 0} for + {setcolor} stopped + grestore + { + cleartomark + 1 get + dup /OrigN .knownget {exch pop}{/N get} ifelse + [//null /DeviceGray //null /DeviceRGB /DeviceCMYK] exch + {get} stopped + { + ( **** Error: Unable to set an ICCBased colour space, and cannot set an alternate from the number of components.\n) print + /setcolorspace cvx /undefined signalerror + } + { + dup //null eq { + ( **** Error: Unable to set an ICCBased colour space, and cannot set an alternate from the number of components.\n) print + /setcolorspace cvx /undefined signalerror + }{ + ICCProfileNError not { + ( **** Warning : Error setting an ICCBased colour space, using /N to set an alternate device space.\n) print + ( Output may be incorrect.\n) print + } if + } ifelse + }ifelse + /ICCProfileNError true def + }{cleartomark}ifelse + } if + } if + /ColorSpace exch def +} bdef + +/get-smask-in-data { % <dict> -> <int> + /SMaskInData knownoget { + dup dup 1 ne exch 2 ne and { + pop 0 + } if + } { + 0 + } ifelse +} bdef + +/makeimagedict { % <resdict> <newdict> makeimagedict <imagemask?> + % On return, newdict' is currentdict + begin + /Width 2 copy oget def + /Height 2 copy oget def + % Handle missing BitsPerComponent later. + /BitsPerComponent 2 copy knownoget { cvi def } { pop } ifelse + /Interpolate 2 copy knownoget { def } { pop } ifelse + makeimagekeys +} bdef + +/makeimagekeys { % <resdict> makeimagekeys <imagemask> + % newdict is currentdict + % Assumes Width, Height, BPC, Interpolate already copied. + /ImageType 1 def + /ImageMatrix Width 0 0 + % Handle 0-height images specially. + Height dup 0 eq { pop 1 } if neg 0 1 index neg + 6 array astore def + + %% If the image has a rendering intent, get its numeric equivalent + %% from renderingintentdict, and save it in the dictionary we pass + %% on to render images. + dup /Intent knownoget { + //.renderingintentdict exch .knownget { /Intent exch def } if + } if + + dup /ImageMask knownoget dup { and } if { + % Image mask + % Decode is required for the PostScript image operators. + % AI8 writes bogus decode array [0 1 0 0 0 0 0 0] + /Decode 2 copy knownoget { 0 2 getinterval } { //01_1 } ifelse def + % BitsPerComponent is optional for masks. + /BitsPerComponent 2 copy known { pop } { 1 def } ifelse + % Even though we're going to read data, + % pass false to resolvestream so that + % it doesn't try to use Length (which may not be present). + //false resolvestream /DataSource exch def + //true + } { + % Opaque image + dup /Filter knownoget { + dup type /arraytype eq { + dup length + dup 0 gt { + 1 sub get oforce + } { + pop + } ifelse + } if + /JPXDecode eq + } { + //false + } ifelse { + % /JPXDecode tricks + + % Previously we only ran the code to extract the Color Space and Bits Per Component + % from the JOX stream if the image dict had either BPC or ColorSpace undefined. + % However, while this is correct for the ColorSpace, its *not* correct for the BPC. + % According to the spec we should ignore any BPC in the image dicitonary and + % always use the BPC from the JPX stream. + % Now the code in get_jp2_csp always overwrites the ColorSpace (in the image resource dict) + % which technically is fine, because the image dictionary entry must be either not present or the + % same as the JPX stream. However, this doesn't work, so instead we just save the existing + % color space (if any). Then after extracting the color space and BPC from the JPX stream + % we put back the saved color space, but only if there was one previously. + dup /ColorSpace oknown { + dup dup /ColorSpace get /ImageDictColorSpace exch put + } if + dup /IDFlag known { + ( **** Warning: PDF spec bans inline JPX images.\n) pdfformatwarning + % Inline stream is not positionable. Cannot get ColorSpace. + } { + % Drop the last filter (JPXDecode) from the pipeline + dup dup length dict copy + dup /Filter oget + dup type /arraytype eq { + dup length 1 gt { + dup length 1 sub 0 exch getinterval + 1 index exch /Filter exch put + + dup /DecodeParms knownoget { + dup type /arraytype eq { + dup length 1 gt { + dup length 1 sub 0 exch getinterval + 1 index exch /DecodeParms exch put + } { + pop + dup /DecodeParms undef + } ifelse + } { + pop + dup /DecodeParms undef + } ifelse + } if + } { + pop + dup /Filter undef + dup /DecodeParms undef + } ifelse + } { + pop + dup /Filter undef + dup /DecodeParms undef + } ifelse + + //false resolvestream get_jp2_csp + + currentdict /ColorSpace oknown not { + currentdict /JPXICC .knownget { + [ /ICCBased mark + /DataSource 5 -1 roll + /N currentdict /JPXColors .knownget not { + currentdict /JPXComponents get + } if + .dicttomark + ] /ColorSpace exch def + } if + } if + + { /JPXICC /JPXColors /JPXComponents /JPXOpacity /JPXPremult } { + currentdict exch undef + } forall + + } ifelse + + % If we had a Color Space in the image dictionary before we read the JPX + % stream, put it back now. We mujst do this before last-ditch-bpc-csp + % because that resolves any indirect references to the color space. + dup /ImageDictColorSpace known { + dup /ImageDictColorSpace get currentdict /ColorSpace 3 -1 roll put + } if + + //last-ditch-bpc-csp exec + + dup /ColorSpace oknown { + % Propagate known color space to the filter + /ColorSpace currentdict /ColorSpace get //add-to-last-param exec + } if + + /Decode 2 copy knownoget not { + ColorSpace //defaultdecodedict + ColorSpace dup type /arraytype eq { 0 get } if get exec + } if def + + dup get-smask-in-data dup 0 ne { + PDFusingtransparency { + currentdict dup length dict copy begin + {/Mask/SMask/SMaskInData/Name} { currentdict exch undef } forall + 2 eq { + /Matte [ Decode length 2 idiv { 0 } repeat ] def + } if + /Decode //01_1 def + /ColorSpace /DeviceGray def + {/File /FilePosition /Filter /Length /DecodeParms /FFilter /FDecodeParms } { + 2 copy knownoget { + def + } { + pop + } ifelse + } forall + currentdict /Alpha //true //add-to-last-param exec pop + /SMask currentdict end def + } { + pop + } ifelse + } { + pop + } ifelse + } { % not JPX image + //last-ditch-bpc-csp exec + /Decode 2 copy knownoget not { + ColorSpace //defaultdecodedict + ColorSpace dup type /arraytype eq { 0 get } if get exec + } if def + + } ifelse % fi JPX tricks + + % Add a /Height key containing the image height to the DecodeParms + % for any Filters we will apply. If there are no DecodeParms for any + % filter, create one and add a /Height key. This is to solve the problem + % in Bug #695116 where a JPEG image has a bad height, which is later + % fixed up using a DNL marker. By placing the image height from the + % PDF in the DeoceParms we cna use it in the DCTDecode filter to + % work around this. + dup /Filter knownoget { % <<stream dict>> /name or [array] + dup type /arraytype eq { + % <<stream dict>> [array of names] + length % <<stream dict>> number of filters + 1 index /DecodeParms knownoget { + exch pop % drop length of Filter array, the DecodeParams has 1 entry per filter + % <<stream dict>> [array of decodeparams] + } { + % No deocde params, we must make an array of them + % <<stream dict>> number of filters + array % <<stream dict>> [] + dup % <<stream dict>> [] [] + 2 index /DecodeParms exch % <<stream dict>> [] [] /DecodeParms <<stream dict>> + 3 1 roll % <<stream dict>> <<stream dict>> [] /DecodeParms + exch put % <<stream dict>> [] + } ifelse + dup length 1 sub % <<stream dict>> [] arraylength-1 + 0 1 3 -1 roll % <<stream dict>> [] 0 1 arraylength-1 + { % <<stream dict>> [] loopcount + 1 index % <<stream dict>> [] loopcount [] + 2 copy % <<stream dict>> [] loopcount [] loopcount [] + exch + get % <<stream dict>> [] loopcount [] <<>> or -null- + dup null eq { + pop exch % <<stream dict>> [] [] loopcount + <</Height + 5 index /Height oget % <<stream dict>> [] [] loopcount << /Height Height + round cvi + >> + put % <<stream dict>> [] + }{ % + oforce_recursive % resolve any indirect references + dup type /dicttype eq { + % <<stream dict>> [] loopcount [] <<>> + /Height % <<stream dict>> [] loopcount [] <<>> /Height + 5 index /Height oget % <<stream dict>> [] loopcount [] <<>> /Height Height + round + cvi + put pop pop % <<stream dict>> [] + }{ + %% bogus entry, throw it away and create a new one + pop exch % <<stream dict>> [] loopcount [] + <</Height + 5 index /Height oget % <<stream dict>> [] [] loopcount << /Height Height + round cvi + >> + put % <<stream dict>> [] + } ifelse + }ifelse + } for + pop % <<stream dict>> + }{ + pop % <<stream dict>> + dup /DecodeParms knownoget { + oforce_recursive % resolve any indirect references + dup type /dicttype eq { + % <<stream dict>> <<decode parms dict>> + /Height 2 index % <<stream dict>> <<decode parms dict>> /Height <<stream dict>> + /Height oget % <<stream dict>> <<decode parms dict>> /Height ImageHeight + round cvi + put % <<stream dict>> + }{ + %% bogus entry, throw it away and create a new one + pop % <<image dict>> <<stream dict>> [] + <</Height % <<stream dict>> <<image dict>> << /Height + 2 index /Height oget % <<stream dict>> <<image dict>> << /Height Height + round cvi + >> + 1 index exch /DecodeParms exch put % <<stream dict> <<image dict>> + } ifelse + }{ + dup % <<stream dict>> <<stream dict>> + /DecodeParms <</Height % <<stream dict>> <<stream dict>> /DecodeParms << /Height + 3 index % <<stream dict>> <<stream dict>> /DecodeParms << /Height <<stream dict>> + /Height oget + round cvi + >> % <<stream dict>> <<stream dict>> /DecodeParms << /Height ImageHeight>> + put % <<stream dict>> + }ifelse + }ifelse + } if + + % Even though we're going to read data, + % pass false to resolvestream so that + % it doesn't try to use Length (which may not be present). + //false resolvestream /DataSource exch def + //false + } ifelse +} bdef + +currentdict /add-to-last-param undef +currentdict /last-ditch-bpc-csp undef + +/DoImage { + %% Bug #696439. This is incredibly icky. When we find indirect obects we resolve them + %% and store the resolved object in the containing object. This means that we retain + %% the image dicionary here until the end of job. Potentially wasteful. Even worse though + %% is the case where the image has a ColorSpace which is not an indirect object, but *is* + %% an ICCBased colour space. In ths case we end up resolving the colour space and storing it + %% here. Unfortunately, we use a ReusableStreamDecode filter on the ICC profile, which means + %% we end up retaining the memory for that too. ICC profiles can be large, and if there are a + %% lot of places where they get used, we can exhaust memory. + %% Here we check if the ColorSpace is an array object, if it is we *copy* the image dictionary + %% and use the copy instead. The copy is (eventually) discarded so we don't retain the ICC profile + %% and don't exhaust memory. Note that we have to copy the actual colour space array too, copying + %% the dictionary just copies the opriginal array as well. + %% + dup /ColorSpace known { + dup /ColorSpace get dup type /arraytype eq { + exch dup length dict copy exch + dup length array copy /ColorSpace exch 2 index 3 1 roll put + } {pop} ifelse + } if + + checkaltimage dup length 6 add dict % <<image>> <<>> + 1 index /SMask knownoget { % <<image>> <<>> <<sm>> + dup 3 index ne { % <<image>> <<>> <<sm>> <<sm>> + 1 index exch /SMask exch put + } { + pop + ( **** Error: ignoring recursive /SMask attribute.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + } if + 1 index /Mask knownoget { 1 index exch /Mask exch put } if + makeimagedict doimagesmask +} bdef +/makemaskimage { % <datasource> <imagemask> <Mask> makemaskimage + % <datasource> <imagemask>, updates currentdict = + % imagedict + dup type /arraytype eq { + /ImageType 4 def + % Check that every element of the Mask is an integer. + //false 1 index { + type /integertype ne or + } forall { + oforce_array + //false 1 index { + type /integertype ne or + } forall { + (\n **** Error: Some elements of Mask array are not integers.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + [ exch { 0.5 add cvi } forall ] % following AR4, 5, 6 implementation + } if + } if + % Check elements of array are within 0::(2**BitsPerComponent)-1 + % This is a PostScript error, but AR tries to fix the Mask. + 1 BitsPerComponent bitshift 1 sub //false 2 index { + % stack: max_value result_bool value + dup 0 lt exch 3 index gt or or + } forall exch pop { + ( **** Error: Some elements of Mask array are out of range.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + + ColorSpace dup type /arraytype eq { 0 oget } if /Indexed eq + BitsPerComponent 1 eq and { + % AR9 treats Indexed 1 bpc images specially. Bug 692852. + dup 0 oget + dup 0 lt exch 1 BitsPerComponent bitshift ge or { + % First component is invalid - AR9 ignores the mask + pop //null + } { + % Second component is invalid; AR9 replaces it with 1. + [ exch 0 oget 1 ] + } ifelse + } { + % AR5, AR9 do this for most cases. Bug 690786. + [ exch { 1 BitsPerComponent bitshift 1 sub and } forall ] + } ifelse + } if + dup //null ne { + /MaskColor exch def + } { + pop + /ImageType 1 def + } ifelse + } { + % Mask is a stream, another Image XObject. + % Stack: datasource imagemask(false) maskstreamdict + PDFfile fileposition exch + dup length dict makeimagedict pop + % In order to prevent the two data sources from being + % aliased, we need to make at least one a reusable stream. + % We pick the mask, since it's smaller (in case we need to + % read all its data now). + % Stack: datasource imagemask(false) savedpos + % maskdict is currentdict + /DataSource DataSource mark + /Intent 1 + /AsyncRead //true + .dicttomark {.reusablestreamdecode} stopped {pop} if def + PDFfile exch setfileposition + currentdict end currentdict end + 5 dict begin + /ImageType 3 def + /InterleaveType 3 def + /DataDict exch def + /MaskDict exch def + /ColorSpace DataDict /ColorSpace get def + } ifelse +} bdef + +/doimagesmask { % <imagemask> doimagesmask - + PDFusingtransparency { + currentdict /SMask knownoget + } { + //false + } ifelse + { % We are doing transparency and SMask is present in the image + % stack: <imagemask> <SMask> + /PreserveSMask /GetDeviceParam .special_op { + exch pop + }{ + //false + }ifelse + { + pop % pdfwrite will process SMask directly during 'doimage' + } { + .begintransparencymaskimage + PDFfile fileposition exch + gsave //nodict begin + //null /SoftMask gput + 1 .setopacityalpha 1 .setshapealpha + 1 CA 1 ca + /Compatible .setblendmode + DoImage + end grestore + PDFfile exch setfileposition + 0 .endtransparencymask + } ifelse + << /Subtype /Group /Isolated //true + /.image_with_SMask //true % pdfwrite needs : see gs/src/ztrans.c, gs/src/gdevpdft.c + >> 0 0 1 1 .begintransparencygroup + doimage + .endtransparencygroup + % tell the compositor we're done with the SMask. + % Note that any SMask in the ExtGState should be reapplied + % by the next call to setfill(stroke)state AND this relies + % on our lazy evaulation of SMask groups + false << /Subtype /None >> 0 0 0 0 .begintransparencymaskgroup + } { + SoftMask //null ne { + % the image doesn't have an SMask, but the ExtGState does, force a group. + << /Subtype /Group /Isolated //true >> 0 0 1 1 .begintransparencygroup + doimage + .endtransparencygroup + } + { doimage } + ifelse + } ifelse +} bdef + +% For development needs we define a special option for running with a new handler +% for images with a soft mask. +//systemdict /NEW_IMAGE3X .knownget not { //false } if { + /doimagesmask { % <imagemask> doimagesmask - + doimage + } bdef +} if + +/doimage { % <imagemask> doimage - + % imagedict is currentdict, gets popped from dstack + //null checkOPtrans { + % We need to push a non-isolated, non-knockout transparency group and + % perform the operation in CompatibleOverprint mode, then end the + % transparency group. Do the begintransparencygroup step here. + mark /Subtype /Group /Isolated //false .dicttomark 0 0 1 1 .begintransparencygroup + OPsavedict dup /saveBM .currentblendmode put /saveOA .currentopacityalpha put % save current values + /CompatibleOverprint .setblendmode 1 .setopacityalpha + } if + + %% save the current rendering intent + .currentrenderintent exch + + %% Check the image dictionary to see if there is a /Intent + currentdict /Intent known { + %% and set the current rendering intent to match if so + Intent .setrenderingintent + } if + + DataSource exch + currentdict /SMask known PDFusingtransparency and { + /PreserveSMask /GetDeviceParam .special_op { + pop pop + currentdict /SMask oget + makesoftmaskimage + } if + } if + currentdict /Mask knownoget { + makemaskimage + } if + % Stack: datasource imagemask + { currentdict end setfillstate { imagemask } } + { ColorSpace setgcolorspace currentdict end setfillblend { image } } + ifelse + PDFSTOPONERROR { exec //false } { stopped } ifelse { + dup type /dicttype eq { pop } if % Sometimes image fails to restore the stack + $error /errorname get dup /ioerror eq { + pop (\n **** Error: File has insufficient data for an image.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } { + (\n **** Error: File encountered ') + exch 40 string cvs concatstrings + (' error while processing an image.\n) concatstrings + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + } if + % Close the input stream, unless it is PDFfile or + % PDFsource. + dup dup PDFfile eq exch PDFsource eq or { pop } { closefile } ifelse + + %% restore the rendering intent + .setrenderingintent + + .currentblendmode /CompatibleOverprint eq { + .endtransparencygroup + OPsavedict dup /saveOA get .setopacityalpha /saveBM get .setblendmode + } if +} bdef + +/.paintform { % <formdict> <resdict> <stream> .paintform - + 1 index /FormResDict gput % For broken forms that inherit resources from the context. + 3 -1 roll dup /Group known PDFusingtransparency and { + .paintgroupform + } { + pop pdfopdict .pdfruncontext + } ifelse +} bdef + +/IncrementAppearanceNumber { + pdfdict /AppearanceNumber .knownget { + 1 add pdfdict /AppearanceNumber 3 -1 roll .forceput + }{ + pdfdict /AppearanceNumber 0 .forceput + } ifelse +}bdef + +/MakeAppearanceName { + pdfdict /AppearanceNumber get + 10 string cvs + dup length 10 add string dup 0 (\{FormName) putinterval + dup 3 -1 roll + 9 exch putinterval + dup dup length 1 sub (\}) putinterval +} bdef + +/MakeNewAppearanceName { + IncrementAppearanceNumber + MakeAppearanceName +}bdef + +/DoAppearance { +%% Might need to rethink this. The problem is that if the page has a CropBox, we apply +%% that as an initial clip. When we run the form, we don't apply the /Rect from the +%% annotation, which means that the form could be out of the clip, which results in +%% content going missing. Resetting the clip prevents this. + gsave initclip + MakeNewAppearanceName + .pdfFormName + pdfdict /.PreservePDFForm known {pdfdict /.PreservePDFForm get} {//false}ifelse exch + pdfdict /.PreservePDFForm true .forceput + DoForm + pdfdict /.PreservePDFForm 3 -1 roll .forceput + grestore +} bdef + +/DoForm { + %% save the current value, if its true we will set it to false later, in order + %% to prevent us preserving Forms which are used *from* an annotation /Appearance. + pdfdict /.PreservePDFForm known {pdfdict /.PreservePDFForm get} {//false}ifelse exch + + %% We may alter the Default* colour spaces, if the Resources + %% ColorSpace entry contains one of them. But we don't want that + %% to become the new default, we want to revert to any existing + %% definition, or the Device space. The Default* spaces are defined + %% as ColorSpace resources, so the only way to handle them is to + %% save and restore round the definitions + 3 dict dup begin + /saved_DG /DefaultGray /ColorSpace findresource def + /saved_DRGB /DefaultRGB /ColorSpace findresource def + /saved_DCMYK /DefaultCMYK /ColorSpace findresource def + end + exch + + % Adobe 2nd edition of the PDF 1.3 spec makes /FormType + % and /Matrix keys optional. Cope with the missing keys. + begin << + currentdict /FormType known not { /FormType 1 } if + currentdict /Matrix known not + { /Matrix { 1 0 0 1 0 0 } cvlit } + { + 0 1 Matrix length 1 sub + { + dup Matrix exch get type dup + /integertype eq exch + /realtype eq or not + { + (\n **** Error: Invalid element in /Form XObject matrix.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + Matrix exch 0.00 put + } + { pop } + ifelse + } for + } ifelse + currentdict /BBox known not { + (\n **** Error: Required entry /BBox not present in Form.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + /BBox [0 1 0 1] + } if + currentdict end { oforce } forall + >> + dup [ 2 index /Resources knownoget { oforce } { 0 dict } ifelse + + %% Ugly hackery for Default* colour spaces in forms + %% + dup /ColorSpace knownoget { + oforce { + //false 3 1 roll + exch dup /DefaultGray eq + { + pop exec resolvecolorspace dup csncomp 1 eq { + dup type /nametype eq { 1 array astore } if + /DefaultGray exch /ColorSpace defineresource pop + pop //true + }{ + pop + ( **** Error: ignoring invalid /DefaultGray color space.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + }{ + dup /DefaultRGB eq { + pop exec resolvecolorspace dup csncomp 3 eq { + dup type /nametype eq { 1 array astore } if + /DefaultRGB exch /ColorSpace defineresource pop + pop //true + }{ + pop + ( **** Error: ignoring invalid /DefaultRGB color space in Form Resources.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + }{ + /DefaultCMYK eq { + exec resolvecolorspace dup csncomp 4 eq { + dup type /nametype eq { 1 array astore } if + /DefaultCMYK exch /ColorSpace defineresource pop + pop //true + }{ + pop + ( **** Error: ignoring invalid /DefaultCMYK color space in Form Resources.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + }{ + pop + } ifelse + } ifelse + }ifelse + { % if using color space substitution, "transition" the current color space + currentcolorspace dup length 1 eq { % always an array + 0 get + dup /DeviceGray eq 1 index /DeviceRGB eq or 1 index /DeviceCMYK eq or { + /Pattern setcolorspace setcolorspace + } { + pop + } ifelse + } { + pop + } ifelse + } if + } forall + } if + + 3 index //false /resolvestream cvx + /.paintform cvx + ] cvx /PaintProc exch put + % Adjust pdfemptycount since we have an extra dictionary on the stack + pdfemptycount countdictstack 3 -1 roll + /pdfemptycount count 4 sub store + + pdfdict /.PreservePDFForm known {pdfdict /.PreservePDFForm get}{//false} ifelse + { + %% We must *not* preserve any subsidiary forms (curently at least) as PDF + %% form preservation doesn't really work. This is used just for Annotation + %% Appearances currently, and if they should happen to use a form, we do not + %% want to preserve it. + pdfdict /.PreservePDFForm false .forceput + /q cvx /execform cvx 5 -2 roll + }{ + /q cvx /PDFexecform cvx 5 -2 roll + } ifelse + + 4 .execn + % Restore pdfemptycount + 0 + { countdictstack + 2 index le { exit } if + currentdict /n known not { 1 add } if + countdictstack + Q + countdictstack eq {end} if + } loop + 1 gt { + ( **** Error: Form stream has unbalanced q/Q operators \(too many q's\)\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } if + pop + /pdfemptycount exch store + + %% Put back pre-existing Default* ColorSpace definitions. + dup type /dicttype eq { + begin + saved_DG /DefaultGray exch /ColorSpace defineresource pop + saved_DRGB /DefaultRGB exch /ColorSpace defineresource pop + saved_DCMYK /DefaultCMYK exch /ColorSpace defineresource pop + end + } if + pdfdict /.PreservePDFForm 3 -1 roll .forceput +} bdef + +/_dops_save 1 array def + +/DoPS { + DOPS + { + //_dops_save 0 save put + //true resolvestream cvx exec + //_dops_save 0 get restore + } + { pop } + ifelse +} bdef + +currentdict /_dops_save undef + +/ocg_pocs 4 dict begin + /AllOn { + //true exch { + oforce dup type /dicttype eq { + /OFF known not and + } { + pop + } ifelse + } forall + } bdef + /AnyOn { + //false exch { + oforce dup type /dicttype eq { + /OFF known not or + } { + pop + } ifelse + } forall + } bdef + /AnyOff { + //AllOn exec not + } bdef + /AllOff { + //AnyOn exec not + } bdef +currentdict end readonly def + +% Check whether OCG or OCMD is visible +% <dict> oc-is-visible <bool> +/ocg-is-visible { + dup /Type knownoget { + /OCMD eq { + dup /OCGs knownoget not { {} } if % OC OCGs + dup type /dicttype eq { 1 array astore } if + //true 1 index { //null eq and } forall { + pop pop //true % all nulls => show + } { + exch /P knownoget not { /AnyOn } if % OCGs P + //ocg_pocs exch get exec % bool + } ifelse + } { + /OFF known not % OFF is inserted by process_trailer_attrs + } ifelse + } { + /OFF known not % OFF is inserted by process_trailer_attrs + } ifelse +} bdef + +drawopdict begin + /Do { % /Name + %% Bug 695897 This file has nested text blocks and also a Do image inside + %% a text block. Here we attempt to detect and recover from this by setting the + %% CTM to the matrix we saved before the text block. NB we update the 'TextSaveMatrix' + %% or 'qTextSaveMatrix' whenever a 'cm' is issued, even if we are in a text block, so + %% these matrices 'ought' to be correct. + %% Of course, the file is badly broken, but 'Acrobat can open it....' + currentdict /TextSaveMatrix known { + gsave + ( **** Error: Executing Do inside a text block, attempting to recover\n) pdfformaterror + currentdict /TextSaveMatrix get setmatrix + ( Output may be incorrect.\n) pdfformaterror + } if + currentdict /qTextSaveMatrix known { + gsave + ( **** Error: Executing Do inside a text block, attempting to recover\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + currentdict /qTextSaveMatrix get setmatrix + } if + setfillblend + PDFfile fileposition exch % pos /Name + dup Page /XObject rget { + exch pop % pos obj + OFFlevels length 0 eq { + dup /OC knownoget { ocg-is-visible } { //true } ifelse + } { + //false + } ifelse { + dup /Subtype oget //xobjectprocs exch get % pos obj {proc} + % Don't leave extra objects on the stack while executing + % the definition of the form. + 3 -1 roll % obj {proc} pos + 2 .execn % pos + } { + pop % pos + } ifelse + } { + % This should cause an error, but Acrobat Reader can + % continue, so we do too. + ( **** Error: Undefined XObject resource: ) + exch =string cvs concatstrings (\n) concatstrings + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + PDFfile exch setfileposition + } bdef +end + +currentdict /xobjectprocs .undef +currentdict /ocg_pocs .undef + +% ---------------- In-line images ---------------- % + +% Undo the abbreviations in an in-line image dictionary. +% Note that we must look inside array values. +% /I is context-dependent. +/unabbrevkeydict mark + /BPC /BitsPerComponent /CS /ColorSpace /D /Decode /DP /DecodeParms + /F /Filter /H /Height /I /Interpolate /IM /ImageMask /W /Width +.dicttomark readonly def +/unabbrevvaluedict mark + /AHx /ASCIIHexDecode /A85 /ASCII85Decode /CC /CalCMYK + /CCF /CCITTFaxDecode /CG /CalGray /CR /CalRGB + /DCT /DCTDecode /CMYK /DeviceCMYK /Fl /FlateDecode + /G /DeviceGray /RGB /DeviceRGB + /I /Indexed /LZW /LZWDecode /RL /RunLengthDecode +.dicttomark readonly def +/unabbrevtypedict mark + /nametype { + //unabbrevvaluedict 1 index .knownget { exch pop } if + } + /arraytype { + dup 0 1 2 index length 1 sub { + 2 copy get unabbrevvalue put dup + } for pop + } +.dicttomark readonly def +/unabbrevvalue { % <obj> unabbrevvalue <obj'> + oforce //unabbrevtypedict 1 index type .knownget { exec } if +} bdef + +/is_space_dict << 0 0 9 9 10 10 12 12 13 13 32 32 >> readonly def + +drawopdict begin + /BI { mark } bdef + /ID { + gsave + %% Bug 696547, related to Bug 695897 (see /Do above) This file has an inline image inside + %% a text block. Here we attempt to detect and recover from this by setting the + %% CTM to the matrix we saved before the text block. NB we update the 'TextSaveMatrix' + %% or 'qTextSaveMatrix' whenever a 'cm' is issued, even if we are in a text block, so + %% these matrices 'ought' to be correct. + %% Of course, the file is badly broken, but 'Acrobat can open it....' + currentdict /TextSaveMatrix known { + ( **** Error: Executing ID inside a text block, attempting to recover\n) pdfformaterror + currentdict /TextSaveMatrix get setmatrix + ( Output may be incorrect.\n) pdfformaterror + } if + currentdict /qTextSaveMatrix known { + ( **** Error: Executing ID inside a text block, attempting to recover\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + currentdict /qTextSaveMatrix get setmatrix + } if + + counttomark 2 idiv dup 7 add dict begin { + exch //unabbrevkeydict 1 index .knownget { exch pop } if + exch unabbrevvalue def + } repeat pop + /IDFlag //true def % flag for stream processing. + /File PDFsource def + currentdict makeimagekeys + OFFlevels length 0 eq { + doimage + } { + pop Width + currentdict /ImageMask knownoget dup { and } if not { + ColorSpace oforce csncomp mul + BitsPerComponent mul + } if + 7 add 8 idiv Height mul + DataSource exch () /SubFileDecode filter flushfile + end + } ifelse + % The Adobe documentation says that the data following ID + % consists of "lines", and some PDF files (specifically, some files + % produced by PCL2PDF from Visual Software) contain garbage bytes + % between the last byte of valid data and an EOL. + % Some files (PDFOUT v3.8d by GenText) have EI immediately following + % the stream. Some have no EOL and garbage bytes. + % Sometimes (bug 690300) CCITTDecode filter consumes 'E' in 'EI'. + % Therefore, we search for <start>I<sp|end> or <start|sp>EI<sp|end> + PDFsource read not { + /ID cvx /syntaxerror signalerror + } if + dup 73 eq { + pop 10 69 73 % Seed to: <sp>EI + } { + 10 10 3 -1 roll % Seed to: <sp><sp><any> + } ifelse + { PDFsource read not dup { 10 exch } if + //is_space_dict 2 index known + 3 index 73 eq and 4 index 69 eq and + //is_space_dict 6 index known and { + pop pop pop pop pop exit + } { + { + pop pop pop /ID cvx /syntaxerror signalerror + } { + 4 -1 roll pop + } ifelse + } ifelse + } loop + grestore + } bdef +end + +currentdict /is_space_dict undef + +% ================================ Text ================================ % + +drawopdict begin + % Text control + /BT { BT } def + /ET { ET } def + /Tc { Tc } def + /TL { TL } def + /Tr { Tr } def + /Ts { Ts } def + /Tw { Tw } def + /Tz { Tz } def + % Text positioning + /Td { Td } def + /TD { TD } def + /Tm { Tm } def + /T* { T* } def + % Text painting + /Tj { Tj } def + /' { ' } def + /" { " } def + /TJ { TJ } def + + /Tform { Tform } def % Text formatting and painting for AcroForm + % without appearance streams. +end + +% ======================= Invalid operators ============================ % + +drawopdict begin + /QBT { + Q BT + ( **** Error: invalid operator QBT processed as Q BT .\n) + pdfformaterror % Bug 690089 + ( Output may be incorrect.\n) pdfformaterror + } def + + /. { + 0. + ( **** Error: invalid operator . processed as number 0. .\n) + pdfformaterror % Bug 690730 + ( Output may be incorrect.\n) pdfformaterror + } def +end + +% ============================== Annotations ============================== % + +% Create links from separate widget annotations to the parent field nodes. +% Surprisingly, separate widget annotations don't have a link to the parent +% from which they inherit some data. +/link_widget_annots { % <<parent>> <<kid>> -> <<parent>> <<kid>> + dup /Kids knownoget { + { oforce + dup type /dicttype eq { + link_widget_annots + } if + pop + } forall + } if + dup /Parent oknown not { + 2 copy exch /ParentField exch put + } if +} bdef + +% Get and normalize an annotation's rectangle. +/annotrect { % <annot> annotrect <x> <y> <w> <h> + /Rect oget oforce_recursive aload pop + exch 3 index sub dup 0 lt { dup 5 -1 roll add 4 1 roll neg } if + exch 2 index sub dup 0 lt { dup 4 -1 roll add 3 1 roll neg } if +} bdef + +% Set an annotation color. +% If the /C array is empty we don't want to draw the annotation +% +/annotsetcolor { % <annot> annotsetcolor bool + /C knownoget { + dup length 4 eq { + aload pop setcmykcolor true + }{ + dup length 3 eq { + aload pop setrgbcolor true + }{ + dup length 1 eq { + aload pop setgray true + } { + dup length 0 eq { + pop + false + }{ + ( **** Error: invalid color specified for annotation /C entry) + pdfformaterror false + ( Output may be incorrect.\n) pdfformaterror + } ifelse + } ifelse + } ifelse + } ifelse + } + { 0 setgray true} ifelse +} bdef + +% Draw the border. Currently, we ignore requests for beveling, and we +% don't round the corners of rectangles. +/strokeborder { % <annot> <width> <dash> strokeborder - + 1 index 0 ne { % do not draw if border width is 0 + gsave + 2 index annotsetcolor + { + 0 setdash dup setlinewidth + exch annotrect + 2 { 4 index sub 4 1 roll } repeat + 2 { 4 index 0.5 mul add 4 1 roll } repeat + rectstroke pop + grestore + } { + pop pop pop + } ifelse + } { + pop pop pop + }ifelse +} bdef + +% Draw an annotation border. +/drawborder { % <annot> drawborder - + gsave + dup /BS known 1 index /Border known or { + dup /BS knownoget { + dup type /dicttype ne % <annot> <border> <bad?> + } { + dup /Border oget + dup type /arraytype eq { + dup length 3 lt + } { + //true + } ifelse % <annot> [border] <bad?> + } ifelse { + ( **** Error: Invalids annotation border object, border has not been drawn.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + pop { 0 0 0 } + } if + dup type /dicttype eq { + dup /W knownoget not { 1 } if + % Per PDF1.6 Reference table 8.13, /W in the border style dictionary is + % expressed in points (an absolute unit), so compensate here for any + % scaling of the PostScript user space done due to /UserUnit. + % Scaling due to -dPDFFitPage is not undone, to keep the correct border width + % compared to the size of the surrounding marks. + //systemdict /NoUserUnit .knownget not { //false } if not + //systemdict /PDFFitPage known not and { % UserUnit is ignored if -dPDFFitPage + Page /UserUnit knownoget { div } if + } if + {} 2 index /S knownoget { + /D eq { 2 index /D knownoget not { {3} } if exch pop } if + } if 3 -1 roll pop strokeborder + } { + dup 2 get + exch dup length 3 gt { 3 get } { pop {} } ifelse + strokeborder + } ifelse + } { + 1 {} strokeborder + } ifelse + grestore +} bdef + +% +% The PDF annotation F (flags) integer is bit encoded. +% Bit 1 (LSB) Invisible: 1 --> Do not display if no handler. +% Note: We have no handlers but we ignore this bit. +% Bit 2 Hidden: 1 --> Do not display. We will not display if this bit is set. +% Bit 3 Print: 1 --> Display if printing. We will display if this bit set +% (and not hidden) and Printed is true +% Bit 4 NoZoom: 1 --> Do not zoom annotation even if image is zoomed. +% Bit 5 NoRotate: 1 --> Do not rotate annotation even if image is rotated. +% Bit 6 NoView: 0 --> Display if this is a 'viewer'. We will display +% if this bit is not set (and not hidden) and Printed is false +% Bit 7 Read Only - 1 --> No interaction. We ignore this bit +% +% AR8 and AR9 print 3D annotations even if Print flag is off. Bug 691486. +% +/annotvisible { % <annot> annotvisible <visible> + dup /Subtype knownoget { /3D eq } { //false } ifelse % 3D annot + exch /F knownoget not { 0 } if % Get flag value + dup 2 and 0 eq { + /Printed load { + 4 and 4 eq or % Printed or 3D + } { + 32 and 0 eq exch pop % not NoView + } ifelse + } { + pop pop //false % Hidden + } ifelse +} bdef + +/set_bc_color << + 1 { 0 get oforce setgray } bind + 3 { { oforce } forall setrgbcolor } bind + 4 { { oforce } forall setcmykcolor } bind +>> readonly def + +% Get an inherited attribute from a node through /Parent and /ParentField +% links. The latter is set at start-up to access parents of annotations and +% defaults at AcroForm. +/fget % <field> <key> fget <value> -true- + { % <field> <key> fget -false- + { + 2 copy knownoget { + exch pop exch pop //true exit + } { + exch + dup /Parent knownoget { + exch pop exch + } { + /ParentField knownoget { + exch + } { + pop //false exit + } ifelse + } ifelse + } ifelse + } loop + } bind def + +% <annot> foo <annot> +/make_tx_da { + dup /AP << /N 10 dict dup cvx begin >> put + /Subtype /Form def + /BBox [ 0 0 4 index /Rect oget { oforce } forall 3 -1 roll sub abs 3 1 roll sub abs exch ] def + /Resources 1 index /DR fget not { 0 dict } if def + /File 1 index /V fget not { () } if length + 2 index /DA fget not { () } if length add + 500 add 65535 .min string dup 3 1 roll def + /NullEncode filter % <annot> file + + dup (BT ) writestring + 1 index /DA fget not { + 1 index /V fget { + <FEFF> anchorsearch{ + pop pop /FallBackFont /Identity-UTF16-H [/CIDFallBack] composefont 12 scalefont setfont + }{ + pop /Helvetica findfont 12 scalefont setfont + } ifelse + } if + () + }if + + [ exch + { token { + dup /Tf eq { + 2 index 0 eq { + /BBox load 3 get + 0.75 mul % empirical constant + 4 -1 roll pop 3 1 roll + } if + } if + exch + } { + exit + } ifelse + } loop + ] + { 1 index exch write== } forall + dup 2 index /MaxLen fget not { 0 } if write= + dup 2 index /V fget not { () } if write== + dup 2 index /Ff fget not { 0 } if write= + dup 2 index /Q fget not { 0 } if write= + dup (Tform ET) write= + dup .fileposition /Length exch def + /File File 0 Length getinterval def + closefile % <annot> + end +} bdef + +/can-regenerate-ap { % <annot> -> <bool> + //false exch + NeedAppearances { + dup /FT fget { + /Tx eq { + dup /V oknown { + pop not 1 + } if + } if + } if + } if + pop +} bdef + +/drawwidget { % <scalefactor_x> <scalefactor_y> <annot> drawwidget - + +%% This code checks to see if we can geenrate an appearance stream for the +%% given widget, and if we can it ignores the given Appearance stream, so that +%% we generate one instead. This seems wrong to me, if we've been given an +%% appearance stream we should use it, no synthesize something else. Several +%% files in our regression test suite render 'incorrectly' when compared to +%% Acrobat with this removed, clearly Acrobat always ignores appearances. However +%% several other files are rendered better when we *don't* ignore the Appearance +%% So on balance I'm choosing to honour the appearance. +%% +% dup /UpdatedAP known not { +% dup can-regenerate-ap { +% dup /AP undef +% } if +% } if + dup /AP knownoget { + dup /N known not { + ( **** Error: Appearance dictionary (AP) lacks the mandatory normal (N) appearance.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } if + //false + [/N /R /D] { + % stack: scalex scaley annot appearance false key + 2 index exch knownogetdict { + exch not exit + } if + } forall + % stack: scalex scaley annot appearance value true + % stack: scalex scaley annot appearance false + dup { + pop exch pop + % Acrobat Distiller produces files in which this Form + % XObject lacks Type and Subtype keys. This is illegal, + % but Acrobat Reader accepts it. The only way we can + % tell whether this is a Form or a set of sub-appearances + % is by testing for the stream Length or File key. + % If the stream lacks Length key, try File key. + dup /Length knownoget { type /integertype eq } { //false } ifelse + 1 index /File knownoget { type /filetype eq or } if { + % If this is a form then simply use it + //true + } { + 1 index /AS knownoget not { + % If we do not have AS then use any appearance + { exch pop oforce exit } forall //true + } { + % Stack: annot Ndict AS + % Get the specified appearance. If no appearance, then + % display nothing - set stack = false. + knownoget + } ifelse + } ifelse + } { + exch pop % discard useless AP dictionary + } ifelse + + % Stack: scalex scaley annot appearance true + % Stack: scalex scaley annot false + { + dup type /dicttype eq { + % Draw appearance + % Initialize graphic following "7.4.4 Appearance Streams" + q graphicsbeginpage textbeginpage + 1 index annotrect pop pop translate + 3 index 3 index scale % Apply scale factors + dup /BBox knownoget { + 1 index /Matrix knownoget not { {1 0 0 1 0 0} } if + .bbox_transform pop pop + % Compensate for non-zero origin of BBox + neg exch neg exch translate + } if + DoForm Q + } { + ( **** Error: Annotation's appearance is not a dictionary.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + } if + } { + dup /MK knownoget { % mk + dup /BG knownoget { % mk bg + dup length % mk bg len + //set_bc_color exch .knownget { + gsave + exec + 3 index 3 index scale + 1 index annotrect rectfill + grestore + } { + pop + } ifelse + } if + dup /BC knownoget { + dup length + //set_bc_color exch .knownget { + gsave + exec + 1 setlinewidth + 3 index 3 index scale + 1 index annotrect rectstroke + grestore + } { + pop + } ifelse + } if + pop + } if + + dup can-regenerate-ap { + make_tx_da + dup /UpdatedAP //true put + 3 copy drawwidget + } if + } ifelse + pop pop pop +} bdef + +currentdict /set_bc_color undef + +% For annotation object we have to determine the size of the output rectangle +% and the size of the BBox for the form XObject. From these we calculate +% a scale factors for drawing it. +/calc_annot_scale { % <annot> calc_annot_scale <x_scale> <y_scale> + dup /Rect knownoget { + pop dup annotrect 4 2 roll pop pop % get width height size in user space + 2 index /AP knownoget { + /N knownogetdict { % <<Annot>> x y <<N>> + dup 4 index /AS knownoget { + knownoget { + exch pop + } if + } { + pop + } ifelse + dup /Matrix knownoget not { {1 0 0 1 0 0} } if + exch /BBox knownoget { % <<>> x y {matrix} [box] + exch .bbox_transform % <<>> x y x0 y0 x1 y1 + 3 -1 roll sub % <<>> x y x0 x1 y1-y0 + 3 1 roll exch sub % <<>> x y y1-y0 x1-x0 + 2 copy mul 0 eq { + ( **** Error: /BBox has zero width or height, which is not allowed.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + pop pop pop pop 1 1 % zero size -- revert to unity scaling + } { + 3 1 roll div % <<>> x x1-x0 y/(y1-y0) + 3 1 roll div % <<>> y/(y1-y0) x/(x1-x0) + exch % <<>> x/(x1-x0) y/(y1-y0) + } ifelse + } { + pop pop pop 1 1 % default to unity scaling + } ifelse % if we have /BBox + } { + pop pop 1 1 + } ifelse % if we have /N + } { + pop pop 1 1 + } ifelse % if we have /AP + 3 -1 roll pop + } { + ( **** Error: /Annot dict is missing required /Rect entry.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + pop 1 1 + } ifelse +} bdef + +% Draw an annotation. +/drawannottypes 20 dict begin + + % x0 y0 x1 y1 x2 y2 x3 y3 -> x0 y0 x1-x0 y1-y0 x2-x0 y2-y0 + /quadpoints2basis { + 8 { oforce 8 1 roll } repeat + + % The text is oriented with respect to the vertex with the smallest + % y value (or the leftmost of those, if there are two such vertices) + % (x0, y0) and the next vertex in a counterclockwise direction + % (x1, y1), regardless of whether these are the first two points in + % the QuadPoints array. + + 2 { + 2 index 1 index eq { + 3 index 2 index gt { + 4 2 roll + } if + } { + 2 index 1 index gt { + 4 2 roll + } if + } ifelse + 8 4 roll + } repeat + 6 index 3 index gt { + 8 4 roll + } if + + % ^ + % | + % * (x2,y2) * (x3,y3) + % | + % | + % *------------*-> + % (x0,y0) (x1,y1) + + pop pop % x0 y0 x1 y1 x2 y2 + 4 index sub exch % x0 y0 x1 y1 y2-y0 x2 + 5 index sub exch % x0 y0 x1 y1 x2-x0 y2-y0 + 4 2 roll + 4 index sub exch % x0 y0 x2-x0 y2-y0 y1-y0 x1 + 5 index sub exch % x0 y0 x2-x0 y2-y0 x1-x0 y1-y0 + 4 2 roll % x0 y0 x1-x0 y1-y0 x2-x0 y2-y0 + } bdef + + /Link { % <annot> -> <false> + dup drawborder dup calc_annot_scale + 2 copy mul 0 ne + {3 -1 roll drawwidget //false} + { + pop pop + ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + }ifelse + } bdef + + /Ink { % <annot> -> <annot> <true> + % <annot> -> <false> + dup /AP oknown { + //true + } { + 1 setlinewidth + 1 setlinecap + 1 setlinejoin + dup annotsetcolor { + dup calc_annot_scale + 2 copy mul 0 ne + { + 3 index annotrect pop pop translate + scale + /InkList knownoget { + { oforce + mark exch { oforce } forall + .pdfinkpath + stroke + } forall + } if + } + { + pop pop + ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } + ifelse + } if + //false + } ifelse + } bdef + + /Underline { + dup /AP oknown { + //true + } { + 0 setlinecap + dup annotsetcolor { + dup calc_annot_scale + 2 copy mul 0 ne + { + scale + /QuadPoints knownoget { + aload length 8 idiv { + //quadpoints2basis exec + + % Acrobat draws the line at 1/7 of the box width from the bottom + % of the box and 1/16 thick of the box width. /Rect is ignored. + + 2 copy dup mul exch dup mul add sqrt 16 div setlinewidth + 7 div 4 index add exch % x0 y0 x1-x0 y1-y0 (y2-y0)/7+y0 x2-x0 + 7 div 5 index add exch % x0 y0 x1-x0 y1-y0 (x2-x0)/7+x0 (y2-y0)/7+y0 + 2 copy moveto + 2 index add exch + 3 index add exch lineto % x0 y0 x1-x0 y1-y0 + pop pop pop pop + stroke + } repeat + } if + } + { + pop pop + ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } + ifelse + } if + //false + } ifelse + } bdef + + /StrikeOut { + dup /AP oknown { + //true + } { + 0 setlinecap + dup annotsetcolor { + dup calc_annot_scale + 2 copy mul 0 ne + { + scale + /QuadPoints knownoget { + aload length 8 idiv { + //quadpoints2basis exec + + % Acrobat draws the line at 3/7 of the box width from the bottom + % of the box and 1/16 thick of the box width. /Rect is ignored. + + 2 copy dup mul exch dup mul add sqrt 16 div setlinewidth + 0.4285714 mul 4 index add exch % x0 y0 x1-x0 y1-y0 (y2-y0)*3/7+y0 x2-x0 + 0.4285714 mul 5 index add exch % x0 y0 x1-x0 y1-y0 (x2-x0)*3/7+x0 (y2-y0)*3/7+y0 + 2 copy moveto + 2 index add exch + 3 index add exch lineto % x0 y0 x1-x0 y1-y0 + pop pop pop pop + stroke + } repeat + } if + } + { + pop pop + ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } + ifelse + } if + //false + } ifelse + } bdef + + % Connect 2 points with an arc that has max distance from the line + % segment to the ark equal 1/4 of the radius. + /highlight-arc { % x1 y1 x0 y0 -> - + 4 2 roll % x0 y0 x1 y1 + dup 3 index add 2 div % x0 y0 x1 y1 (y1+y0)/2 + 2 index 5 index sub .9375 mul sub % x0 y0 x1 y1 (y1+y0)/2-15/16*dx=yc + 4 index 3 index add 2 div % x0 y0 x1 y1 yc (x0+x1)/2 + 2 index 5 index sub .9375 mul add % x0 y0 x1 y1 yc xc + exch % x0 y0 x1 y1 xc yc + dup 3 index exch sub % x0 y0 x1 y1 xc yc y1-yc + 4 index 3 index sub % x0 y0 x1 y1 xc yc y1-yc x1-xc + dup dup mul 2 index dup mul add sqrt %x0 y0 x1 y1 xc yc y1-yc x1-xc r + 3 1 roll atan % x0 y0 x1 y1 xc yc r a1 + 6 index 3 index sub % x0 y0 x1 y1 xc yc r a1 y0-yc + 8 index 5 index sub % x0 y0 x1 y1 xc yc r a1 y0-yc x0-xc + atan % x0 y0 x1 y1 xc yc r a1 a2 + exch arcn % x0 y0 x1 y1 + pop pop pop pop + } bind def + + /emptydict 0 dict readonly def + + /Highlight { + 0 setlinecap + dup annotsetcolor { + /QuadPoints knownoget { + aload length 8 idiv { + 6 -2 roll + 2 copy moveto + //highlight-arc exec + 2 copy lineto + //highlight-arc exec + closepath + } repeat + PDFusingtransparency { + //emptydict + pathbbox 2 index add exch 3 index add exch .begintransparencygroup + /Multiply .setblendmode + fill + .endtransparencygroup + } { % for -dNOTRANSPARENCY + stroke newpath + } ifelse + } if + } if + //false + } bdef + currentdict /emptydict undef + currentdict /highlight-arc undef + + /Squiggly { + dup /AP oknown { + //true + } { + dup annotsetcolor { + dup calc_annot_scale + 2 copy mul 0 ne + { + scale + /QuadPoints knownoget { + aload length 8 idiv { + gsave + 8 copy moveto lineto + 4 2 roll lineto lineto closepath clip newpath + //quadpoints2basis exec + 6 -2 roll translate % adjust for x0 y0 % x1-x0 y1-y0 x2-x0 y2-y0 + 1 index 56 div 1 index 56 div translate % zigzag box is 1/56 up + 1 index 72 div 1 index 72 div translate % the line in the box is 1/72 up + 2 copy dup mul exch dup mul add sqrt % x1-x0 y1-y0 x2-x0 y2-y0 |p2| + 4 index dup mul 4 index dup mul add sqrt % x1-x0 y1-y0 x2-x0 y2-y0 |p2| |p1| + dup 0 gt 2 index 0 gt and { + div % x1-x0 y1-y0 x2-x0 y2-y0 |p2|/|p1|=p12 + dup 1 exch div 4 mul 1 add cvi exch 6 2 roll % cnt p12 x1-x0 y1-y0 x2-x0 y2-y0 + 4 2 roll % cnt p12 x2-x0 y2-y0 x1-x0 y1-y0 + 4 index mul exch 4 index mul exch % cnt p12 x2-x0 y2-y0 (x1-x0)*p12 (y1-y0)*p12 + 4 2 roll 0 0 6 array astore concat % cnt p12 + 1 40 div 1 72 div scale + pop % cnt + 0 0 moveto + 1 setlinecap + 1 setlinejoin + 1 setlinewidth + { + 5 10 lineto + 10 0 lineto + 10 0 translate + } repeat + stroke + } { + 6 { pop } repeat + } ifelse + grestore + } repeat + } if + } + { + pop pop + ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } + ifelse + } if + //false + } ifelse + } bdef + + /Text { + dup /AP oknown { + //true + } { + dup calc_annot_scale + 2 copy mul 0 ne + { + scale + annotrect 4 2 roll translate + exch pop + + % Draw a page icon + 0.5 exch 18.5 sub translate + 1 setlinewidth + 0.75 setgray + 0.5 -1 moveto 10 -1 lineto 15 4 lineto 15 17.5 lineto stroke + + 0 0 moveto + 9 0 lineto + 14 5 lineto + 14 18 lineto + 0 18 lineto closepath + gsave .5 setgray fill grestore 0 setgray stroke + + 3 8 moveto 7.5 8 lineto + 3 11 moveto 10 11 lineto + 3 14 moveto 10 14 lineto + 9 0 moveto 9 5 lineto 14 5 lineto + stroke + } + { + pop pop + ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } + ifelse + //false + } ifelse + } bdef + + /FreeText { + dup /AP knownoget { + %% Check minimal entriy in /AP dictionary + /N known not { + //true + }{ + //false + }ifelse + } { + //true + }ifelse + %% We either have no appearance, or its invalid, make one up. + { + gsave + + dup annotrect (rectclip from freetext annotation) == flush rectclip + + dup /CA knownoget { + .setopacityalpha + } if + + dup /ca knownoget { + .setopacityalpha + } if + + dup /C knownoget { + dup length 4 eq { + aload pop setcmykcolor true + }{ + dup length 3 eq { + aload pop setrgbcolor true + }{ + dup length 1 eq { + aload pop setgray true + } { + dup length 0 eq { + pop + false + }{ + ( **** Error: invalid color specified for FreeText annotation /C entry) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + false + } ifelse + } ifelse + } ifelse + } ifelse + }{ + false + } ifelse + {dup annotrect + %% Somewhat horrifyingly, rectfill maps directly to the device fill_rectangle + %% method, which bypasses transparency (!!) So we construct the rectangle, + %% and fill it, manually instead.... + gsave 4 2 roll moveto 1 index 0 rlineto + 0 exch rlineto neg 0 rlineto closepath fill grestore + } if + + %% get and process the default appearance string, if we don't have one, use a default + /DA_Action_Dict + << + /Tf {exch dup /Helv eq {pop /Helvetica findfont exch scalefont setfont}{findfont exch scalefont setfont}ifelse} + /r {aload pop setrgbcolor} % Can't find this actually defined anywhere, but Acrobat seems to honour it :-( + /rg {setrgbcolor} + /RG {setrgbcolor} + /G {setgray} + /g {setgray} + /k {setcmykcolor} + /K {setcmykcolor} + >> def + dup /DA knownoget { + length string /tempstr exch def + dup /DA get tempstr copy pop + { + %% This is kind of ugly, we use token to process the string + %% and process each token separately. + tempstr + token { + exch /tempstr exch def + %% If the token is a name + %% + dup type /nametype eq { + %% Is it a name we want to take actionon + dup DA_Action_Dict exch known { + DA_Action_Dict exch get exec + }{ + %% Its not a name we know, is it executable + dup xcheck {exec} if + } ifelse + }{ + %% Not a name, just make it executable and execute it + cvx exec + }ifelse + }{ + exit + }ifelse + } loop + } { + 0 setgray + /Helvetica findfont 12 scalefont setfont + }ifelse + %% draw the border, if we don't have a border style dictionary, draw a default one. + dup /BS knownoget { + pop dup drawborder + }{ + newpath + 0 setgray 1 setlinewidth + dup annotrect 4 -1 roll 1 add 4 -1 roll 1 add 4 -1 roll 2 sub 4 -1 roll 2 sub + 4 2 roll moveto + currentpoint exch 3 index add exch lineto + currentpoint 2 index add lineto + exch currentpoint 3 1 roll exch sub exch lineto + currentpoint 3 -1 roll sub lineto stroke + }ifelse + + %% Start the current point at the top left of the annotation Rect + %% + dup annotrect 4 -1 roll 2 add 4 -1 roll 2 add 4 -1 roll 4 sub 4 -1 roll 4 sub + 3 -1 roll add 2 index exch moveto 1 index add + + %% Get the Contents string, if we don't have one, we're done + %% + 2 index /Contents knownoget { + %% Check for UTF16-BE, we probably don't work properly with this yet. + %% + dup 0 get 254 eq 1 index 1 get 255 eq and + { + /FallBackFont /Identity-UTF16-H [/CIDFallBack] composefont 12 scalefont setfont + dup length 2 div 1 sub 0 1 3 -1 roll { + %% llx urx (string) index + 1 index exch 2 mul 2 getinterval %% llx urx (string) (substring) + dup stringwidth pop currentpoint pop add 3 index gt { + currentpoint exch pop 4 index exch 12 sub moveto + } if + show + } for + pop + } + { + %% Heuristic to determine the height (ascender to descender) of the text + %% for when we move down a line. + gsave + /..TextHeight (Hy) false charpath pathbbox exch pop exch sub exch pop def + grestore + %% and use it immediatley to start the text one line down + %% + currentpoint ..TextHeight sub moveto + + %% Now we process each character code in the string. If we find + %% a /r/ or /n then we drop a line. If the character would end up + %% outside the Annot Rect, then we drop a line before showing it. + %% + dup length 1 sub 0 1 3 -1 roll { + %% llx urx (string) index + 1 index exch get %% llx urx (string) int + dup 10 eq 1 index 13 eq or { + pop + currentpoint exch pop 3 index exch ..TextHeight sub moveto + } { + 1 string dup 0 4 -1 roll + put dup %% llx urx (string) (int) (int) + stringwidth pop currentpoint pop add 3 index gt { + currentpoint exch pop 4 index exch ..TextHeight sub moveto + } if + show + } ifelse + } for + pop + }ifelse + } if + pop pop + //false + grestore + } + { + //true + } ifelse + } bdef + + /frame { + { 255 div } forall setrgbcolor + -95 -25 translate + 2 190 atan rotate + { + 6 0 moveto + 190 0 190 6 6 arct + 190 47 184 47 6 arct + 0 47 0 41 6 arct + 0 0 6 0 6 arct + closepath + + 10 4 moveto + 185 4 185 9 5 arct + 185 43 180 43 5 arct + 5 43 5 38 5 arct + 5 4 9 4 5 arct + closepath + eofill + } + gsave 1 -1 translate 0.75 setgray dup exec grestore + exec + } bdef + + % (text) y h -> - + /text { + /Times-Bold findfont exch scalefont setfont % (text) y + gsave + 0 0 moveto + 1 index //false charpath flattenpath pathbbox + pop exch pop sub 2 div + grestore + 95 add exch moveto + gsave 1 -1 rmoveto 0.75 setgray dup show grestore + show + } bdef + + /red <ef4023> readonly def + /green <3fae49> readonly def + /blue <0072bc> readonly def + + /stamp_dict 14 dict begin + /Approved { + //green //frame exec + (APPROVED) 13 30 //text exec + } bdef + /AsIs { + //red //frame exec + (AS IS) 13 30 //text exec + } bdef + /Confidential { + //red //frame exec + (CONFIDENTIAL) 17 20 //text exec + } bdef + /Departmental { + //blue //frame exec + (DEPARTMENTAL) 17 20 //text exec + } bdef + /Draft { + //red //frame exec + (DRAFT) 13 30 //text exec + } bdef + /Experimental { + //blue //frame exec + (EXPERIMENTAL) 17 20 //text exec + } bdef + /Expired { + //red //frame exec + (EXPIRED) 13 30 //text exec + } bdef + /Final { + //red //frame exec + (FINAL) 13 30 //text exec + } bdef + /ForComment { + //green //frame exec + (FOR COMMENT) 17 20 //text exec + } bdef + /ForPublicRelease { + //green //frame exec + (FOR PUBLIC) 26 18 //text exec + (RELEASE) 8.5 18 //text exec + } bdef + /NotApproved { + //red //frame exec + (NOT APPROVED) 17 20 //text exec + } bdef + /NotForPublicRelease { + //red //frame exec + (NOT FOR) 26 18 //text exec + (PUBLIC RELEASE) 8.5 18 //text exec + } bdef + /Sold { + //blue //frame exec + (SOLD) 13 30 //text exec + } bdef + /TopSecret { + //red //frame exec + (TOP SECRET) 14 26 //text exec + } bdef + currentdict end readonly def + + {/text/frame/red/green/blue} {currentdict exch undef} forall + + /Stamp { + dup /AP oknown { + //true + } { + dup calc_annot_scale + 2 copy mul 0 ne + { + scale + % translate to the center of Rect + dup annotrect + 4 2 roll % dx dy x0 y0 + 2 index 2 div add exch + 3 index 2 div add exch translate % dx dy + + 50 div exch 190 div .min dup scale + + /Name knownoget not { /Draft } if + //stamp_dict 1 index known not { exch pop /Draft exch } if + //stamp_dict exch get exec + } + { + pop pop + ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } + ifelse + //false + } ifelse + } bdef + + currentdict /quadpoints2basis undef +currentdict end readonly def + +/drawannot { % <annot> drawannot - + dup annotvisible { + gsave + dup dup /Subtype knownoget { + //drawannottypes exch .knownget { exec } { //true } ifelse + { + dup calc_annot_scale 2 copy mul 0 ne + { + 3 -1 roll drawwidget + } + { + ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + }ifelse % Draw rejected annots as widgets + } if % type known + } { + pop + ( **** Error: Ignoring /Annot dict without required /Subtype entry.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + grestore + } if pop % annotvisible +} bdef +currentdict /drawannottypes undef + +% Draw an annotation. + +/loadannot { + dup /AP .knownget { % <<Annot dict>> <<Appearance dictionary>> true | false + oforce + + dup { % <<Annot dict>> <<Appearance dict>> /Key <</Key dict>> + oforce % <<Annot dict>> <<Appearance dict>> /Key <<resolved /Key dict>> + + %% + %% Check to see if the apperance key has a simple stream or a dictionary of states + %% + dup /Subtype known % <<Annot dict>> <<Appearance dict>> /Key <<resolved /Key dict>> bool + { + %% Simple appearance stream + DoAppearance % <<Annot dict>> <<Appearance dict>> /Key + 2 index % <<Annot dict>> <<Appearance dict>> /Key <<Annot dict>> + /AP << % <<Annot dict>> <<Appearance dict>> /Key <<Annot dict>> /AP << + 4 -1 roll MakeAppearanceName cvx cvn >> put % <<Annot dict>> <<Appearance dict>> + } { + %% dictionary of states <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> + dup % <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> <<appearance states dict>> + { % <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> /StateKey <<State dictionary>> + oforce % <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> /StateKey <<resolved State dictionary>> + DoAppearance % <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> /StateKey + 1 index exch % <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> <<appearance states dict>> /StateKey + MakeAppearanceName cvx cvn % <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> <<appearance states dict>> /StateKey {} + put % <<Annot dict>> <<Appearance dict>> /Key <<appearance states dict>> + } forall + put % <<Annot dict>> <<Appearance dict>> /Key + dup + }ifelse + } forall + pop % <<Annot dict>> + } if + + %% Parent (or /P) references will be incorrect. Remove them + %% for now as they are optional. + dup /Popup known {dup /Popup undef} if + dup /IRT known {dup /IRT undef} if + dup /RT known {dup /RT undef} if + dup /P known {dup /P undef} if + dup /Parent known {dup /Parent undef} if + + %% Resolve any indirect references. May need further work :-( + { + %% We know /AP doesn't need processing, we handled that above... + 1 index /AP eq not { + dup {oforce} stopped not {exch pop} if + dup type /dicttype eq{ + dup + { + dup {oforce} stopped not {exch pop} if + 2 index 3 1 roll put + } forall + } if + dup type /arraytype eq { + 0 1 2 index length 1 sub{ + dup 2 index exch get dup {oforce} stopped not {exch pop} if + 2 index 3 1 roll put + } for + } if + } if + } forall +} bdef + + +/ApplyCTMToQuadPoints { + %% Nasty hackery here really. We need to undo the HWResolution scaling which + %% is done by pdfwrite. Default is 720 dpi, so 0.1. We also need to make + %% sure that any translation of the page (because its been rotated for example) + %% is also modified by the requisite amount. SO we ned to calculate a matrix + %% which does the scaling and concatenate it with the current matrix. + %% Do this inside a gsave/grestore pair to avoid side effects! + + gsave + currentpagedevice /HWResolution get + aload pop exch 72 exch div exch 72 exch div + matrix 3 1 roll 2 index 3 3 -1 roll put + 1 index 0 3 -1 roll put + matrix currentmatrix exch matrix concatmatrix + setmatrix + + oforce + + %% QuadPoints are given as 'n' sequences of 8 numbers. + + mark exch aload counttomark 1 roll + counttomark 1 sub 2 div cvi { + transform + counttomark 1 sub 2 roll + } repeat + counttomark -1 roll astore + + exch pop % the mark + + grestore +} bdef + +/preserveannottypes 20 dict begin + +/Circle {mark exch loadannot /ANN pdfmark false} bdef +/FileAttachment {mark exch loadannot /ANN pdfmark false} bdef +/FreeText {mark exch loadannot /ANN pdfmark false} bdef + +/Highlight { + mark exch + dup /QuadPoints .knownget { + 1 index /QuadPoints 3 -1 roll + ApplyCTMToQuadPoints + put + } if + loadannot /ANN pdfmark false +} bdef + +/Ink {mark exch loadannot /ANN pdfmark false} bdef + +/Line { + mark exch dup /L .knownget { + aload 5 1 roll transform 4 -2 roll transform 4 2 roll + 5 -1 roll astore + 1 index /L 3 -1 roll put + } if + loadannot /ANN pdfmark false +} bdef + +/Link {mark exch {drawannot} PDFSTOPONERROR {exec}{stopped {(Error: Ignoring invalid annotation, output may be incorrect.\n) pdfformaterror} if} ifelse cleartomark false} bdef + +/Movie {mark exch loadannot /ANN pdfmark false} bdef +/Popup {mark exch loadannot /ANN pdfmark false} bdef +/Sound {mark exch loadannot /ANN pdfmark false} bdef +/Square {mark exch loadannot /ANN pdfmark false} bdef +/Stamp {mark exch loadannot /ANN pdfmark false} bdef + +/StrikeOut { + mark exch + dup /QuadPoints .knownget { + 1 index /QuadPoints 3 -1 roll + ApplyCTMToQuadPoints + put + } if + loadannot /ANN pdfmark false +} bdef + +/Squiggly { + mark exch + dup /QuadPoints .knownget { + 1 index /QuadPoints 3 -1 roll + ApplyCTMToQuadPoints + put + } if + loadannot /ANN pdfmark false +} bdef + +/Text {mark exch loadannot /ANN pdfmark false} bdef +/TrapNet {mark exch loadannot /ANN pdfmark false} bdef + +/Underline { + mark exch + dup /QuadPoints .knownget { + 1 index /QuadPoints 3 -1 roll + ApplyCTMToQuadPoints + put + } if + loadannot /ANN pdfmark false +} bdef + +%% Widget annotations are only used with AcroForms, and since we don't preserve AcroForms +%% we don't want to preserve widget annotations either, because the consumer of the new +%% PDF won't know what values they should take. So we draw widget annotations instead. If we +%% ever preserve AcroForms then we should alter this to preserve Widgets as well. +%% simply chane "drawannot" to "mark exch loadannot /ANN pdfmark" +/Widget {mark exch {drawannot} PDFSTOPONERROR {exec}{stopped {(Error: Ignoring invalid annotation, output may be incorrect.\n) pdfformaterror} if} ifelse cleartomark false} bdef + +currentdict end readonly def + +/preserveannot { % <annot> preserveannot - + dup annotvisible { + gsave + dup dup /Subtype knownoget { + //preserveannottypes exch .knownget { exec } { //true } ifelse + { + dup calc_annot_scale 2 copy mul 0 ne + { + 3 -1 roll drawwidget + } + { + ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + }ifelse % Draw rejected annots as widgets + } if % type known + } { + pop + ( **** Error: Ignoring /Annot dict without required /Subtype entry.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + grestore + } if pop % annotvisible +} bdef + +currentdict /preserveannottypes undef + +% ============================ AcroForm fields ============================ % + +% Get an attribure of the 0th annotation of a node +/annot_oget { % <annot> /Name annot_oget <value> + 1 index /Kids knownoget { + 0 oget exch oget exch pop + } { + oget + } ifelse +} bdef + +% All procedures have the signature: +% <acroform> <field> <annot|field> foo <acroform> <field> <annot|field> +/draw_terminal_field_dict 4 dict begin + +/Btn { + 1 index /Tf pget not { 0 } if + dup 16#20000 and 0 ne { + pop % Push button + dup /AP known { + 1 1 2 index drawwidget + } { + (Push button without appearance stream is not yet implemented) = + } ifelse + } { + 16#10000 and 0 ne { + % Radio button + dup /AP known { + 1 index /Kids oget { + 1 1 3 -1 roll drawwidget + } forall + } { + (Radio button without appearance stream is not yet implemented) = + } ifelse + } { + % Checkbox + dup /AP known { + dup 1 1 3 -1 roll drawwidget + } { + (CkeckBox without appearance stream is not yet implemented) = + } ifelse + } ifelse + } ifelse +} bdef + +/Tx { + dup /AP known { + dup 1 1 3 -1 roll drawwidget + } { + %% If we don't have a NeedApperances, treat as true, because Acrobat + %% always regenerates Appearances anyway. + 2 index /NeedAppearances knownoget not { //true } if { + dup /AP << /N 10 dict dup cvx begin >> put + /Subtype /Form def + /BBox [ 0 0 4 index /Rect oget { oforce } forall 3 -1 roll sub abs 3 1 roll sub abs exch ] def + /Resources 3 index /DR pget not { 0 dict } if def + /File 1000 string dup 3 1 roll def + /Length 1000 def + % <acroform> <field> <annot> (string) + /NullEncode filter % <acroform> <field> <annot> file + + dup (BT ) writestring + 2 index /DA pget not { () } if + [ exch + { token { + dup /Tf eq { + 2 index 0 eq { + /BBox load 3 get + 0.75 mul % empirical constant + 4 -1 roll pop 3 1 roll + } if + } if + exch + } { + exit + } ifelse + } loop + ] + { 1 index exch write== } forall + dup 3 index /MaxLen pget not { 0 } if write= + dup 3 index /V pget not { + 3 index /DV pget not { () } if write== + } if + dup 3 index /Ff pget not { 0 } if write= + dup 3 index /Q pget not { 0 } if write= + dup (Tform ET) write= + end + closefile % <acroform> <field> <annot> + dup 1 1 3 -1 roll drawwidget + } if + } ifelse +} bdef + +/Ch { + (Ch is not yet implemened) //== exec +} bdef + +/Sig { + (Sig is not yet implemened ) //== exec +} bdef + +currentdict end def + +/draw_terminal_field { % <field> draw_terminal_field - + dup /Kids knownoget { 0 oget } { dup } ifelse + dup /P knownoget { + /Page load eq { + //draw_terminal_field_dict 2 index /FT pget not { 0 } if .knownget { + exec + } if + } if + } if + pop pop +} bdef + +% We distinguish 4 types of nodes on the form field tree: +% - non-terminal field - has a kid that refers to the parent (or anywhere else) +% - terminal field with separate widget annotations - has a kid that doesn't have a parent +% - terminal field with a merged widget annotation - has no kids +% - widget annotation - has /Subtype and /Rect +% +% The recursive enumeration of the form fields doesn't descend into widget annotations. + +/draw_form_field { % <field> draw_form_field - + dup /Kids knownoget { % field [] + dup length 0 gt { + dup 0 oget /Parent knownoget { % field [] kid + pop % mon-terminal field % field [] + exch pop % [] + { oforce draw_form_field } forall + } { + pop draw_terminal_field % separate annots % - + } ifelse + } { + ( **** Error: Ignoring empty /Kids array in Form field.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + } { + draw_terminal_field % merged annotation % - + } ifelse +} bdef + +/draw_acro_form { % <form> draw_acro_form - + dup /Fields knownoget { + { oforce draw_form_field } forall + } if + pop +} bdef + +currentdict /draw_terminal_field_dict undef + +end % pdfdict +end % GS_PDF_ProcSet +.setglobal diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps new file mode 100644 index 00000000000..7060dbce6f0 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps @@ -0,0 +1,2526 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% PDF font operations. + +% Since PDF font are not unique and can collide with external font resources +% or each other, use font dictionaries obtained from PDF directly, never +% register them as resources or look them up by name. Use findfont oparator +% for non-embedded fonts only. CIDFont resources still use the old logic +% described below. + +% Finding a font by name can't give a proper result when PDF font names aren't unique. +% But it is only the way to obtain a font in Postscript after a font file is executed. +% Therefore using a FontName (and findfont) is allowed only +% immediately after a font file is executed. +% In all other cases the font to be found by a pointer through PDF structures. +% +% This ideal logics can't work for documents, +% which define a font resource with an embedded font, +% and another font resource with same BaseFont but with no embedded font +% (and possibly with no font descriptor). +% Our testbase does contain such examples. +% In this case we do find font by FontName (with findfont), +% since there is no other way to get a reasonable result. + +/.setlanguagelevel where { pop 2 .setlanguagelevel } if +.currentglobal //true .setglobal +/pdfdict where { pop } { /pdfdict 100 dict def } ifelse +GS_PDF_ProcSet begin +pdfdict begin + +% We cache the PostScript font in an additional element of the +% font resource dictionary, called PSFont. + +% ---------------- Encodings ---------------- % + +/.notdefEncoding 256 { /.notdef } repeat 256 packedarray def + +% Apply a list of differences to an Encoding. +% Note that the differences may cause the array to grow. +/updateencoding { % <encoding|null> <differences> updateencoding <enc'> + % Calculate the length of the result. + % in case the incoming Encoding is null, use .notdefEncoding + exch dup //null eq { pop .notdefEncoding } if + 0 0 3 index { + dup type /nametype ne { exch pop oforce } { pop 1 add } ifelse + % Differences list may not be in order, update the largest_index + % stack: <Differences> <encoding> <largest_index> <at_index> + 2 copy lt { exch pop dup } if % at_index is new largest + } forall + pop 1 index length .max array dup 0 4 -1 roll putinterval + exch 0 exch { + % Stack: enc' code element + dup type /nametype ne + { exch pop oforce } + { 3 copy put pop 1 add } + ifelse + } forall pop +} bdef + +/good_encoding_names << + /MacRomanEncoding 0 /MacExpertEncoding 0 /WinAnsiEncoding 0 +>> readonly def + +/known_symbolic_fonts << + /Wingdings2 0 + /ZapfDingbats 0 +>> readonly def + +% Get the Encoding for a font. +/getencoding % <base-encoding> <font-resource> getencoding <enc> + { dup /Encoding knownoget + { dup type /nametype eq + { + % The published PDF specification says the Encoding name + % "must be" one of the 3 predefined Encodings, implying + % that an error should occur if it isn't. However, Acrobat + % Reader simply ignores unknown names, and since there are + % some buggy applications that rely on this, we do the same. + + //good_encoding_names 1 index known { + exch /BaseFont knownoget not { 0 } if + % Ignore named encodings for known symbolic fonts. See bug 690135. + //known_symbolic_fonts exch known { + pop + } { + exch pop findencoding + } ifelse + } { + pop pop + } ifelse + } + { exch pop + dup type /arraytype eq + { exch pop + ( **** Warning: Encoding is an array, not name or dictionary.\n) pdfformatwarning + } + { dup /BaseEncoding knownoget + { + %% Originally we ignored the specific invalid name '/' here from Bug #687786, however + %% Bug #696942 contains an invalid BaseEncoding '/utf-8', so now we check all BaseEncoding + %% against the permitted names, just as we do for Encodings. + //good_encoding_names 1 index known{ + findencoding 3 -1 roll pop exch + }{ + ( **** Error: Invalid BaseEncoding name ") print 256 string cvs print (" ignoring BaseEncoding.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + }ifelse + } if + /Differences knownoget { updateencoding } if + } + ifelse + } + ifelse + } { + pop + ( **** Error: Encoding not present.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } + ifelse + } bdef + +currentdict /good_encoding_names undef +currentdict /known_symbolic_fonts undef + +/checkGlyphNames2Unicode % <dict> checkGlyphNames2Unicode - +{ + PDFDEBUG { + dup /FontInfo .knownget { + /GlyphNames2Unicode .knownget { + (Has GlyphNames2Unicode) = + pop % { exch //== exec //== exec} forall + } if + } if + } if + pop +} bind def + +% Define a font using it's FontName as the key. +% Adjust a font according to the Encoding and Widths in the font resource. +/adjustfont { % <font-resource> <font> adjustfont <font'> + getfontencoding + 3 copy .processToUnicode + getfontmetrics 5 -1 roll pop .updatefont { + %% Bug #696306 has a broken type 1 font where the eexec encrypted portion simply ends + %% leaving a partial glyph description and, more importantly, the Private dictionary + %% on the operand stack. Ths means the font dictonary does not contain a Private + %% dictionary which causes .buildfont1 to throw an error. .completefont calls .buildfont1 + %% (which is obscured by a definition in gs_type1.ps) so we need to check the reault + %% of .completefont. If it fails we must discard the font dictionary and use a fallback. + {.completefont} stopped { + (\n *** ERROR: The font ) print /FontName get 256 string cvs print ( is damaged and cannot be used. Switching to a\n) pdfformaterror + ( last-ditch fallback, text may not render correctly, or at all.\n\n) pdfformaterror + /Helvetica findfont + }if + } if +} bind def + +% Get the (possibly modified) encoding of a font. +/getfontencoding { % <font-resource> <font> getfontencoding + % <font-resource> <font> <Encoding|null> + % Ignore encoding when TrueType is requested + % and loaded from an embedded stream. + % All other cases are left unchanged. + dup /FontType get 42 eq 1 index /PathLoad known not and + 2 index /Subtype get /TrueType eq and { + //null + } { + % Acrobat appears to be always using StandardEcoding as the + % default encoding for some non-symbolic fonts (rather than, + % as the spec states, the encoding specified by the font). + % As this is contrary to spec, and we only have a CFF + % example, I've restricted this to fonts with Subtype Type1C + % *and* that result in a Type 2 PS font. + 1 index /FontDescriptor knownoget + { + dup + % Unfortunately, Acrobat doesn't enforce the meaning of + % FontFile[23] so whilst, in theory, Type1C should only + % occur in FontFile3, we can't rely on that. + dup /FontFile knownoget not + { + dup /FontFile2 knownoget not + { + dup /FontFile3 knownoget not {1 dict} if + } if + } if + exch pop /Subtype knownoget {/Type1C eq}{//false} ifelse + exch /Flags knownoget {4 and 4 eq not}{false}ifelse and + } {//false} ifelse + + 1 index /FontType get 2 eq and + { + 2 index /Encoding knownoget {pop StandardEncoding 2 index getencoding} { //null } ifelse + } + { + 2 index /Encoding known { + dup /Encoding knownoget { 2 index getencoding } { //null } ifelse + } { + //null + } ifelse + } ifelse + } ifelse +} bdef + +% Returns true if the current glyph is in the Differences array at +% the specified index value. This is needed because the Widths +% array may map to the same glyph at different positions from the +% Encoding. We want to use the Width that was associated with the +% one specified in the Encoding::Differences list. +/match_in_diff % <Differences> <index> <glyphname> match_in_diff <bool> +{ //false 4 1 roll 0 4 -1 roll % stack: false index glyphname at_index==0 Differences + { exch 1 index type /nametype ne { + % stack: false index glyphname Diff_element at_index + pop % Diff_element is new at_index + } { + % stack: false index glyphname Diff_element at_index + exch 2 index eq { + % stack: false index glyphname at_index + dup 3 index eq { + //true 5 1 roll % stack: true false index glyphname at_index + pop exit + } if + } if + 1 add % at_index++ stack: false index glyphname at_index' + } ifelse + } forall + % stack: true false index glyphname + % or : false index glyphname at_index + pop pop pop +} bdef + +/unique_name { % <dict> </root> unique_name </unique> + % + % Note : this function interacts with pdf_write_encoding in src/gdevpdtw.c + % and with copied_drop_extension_glyphs in src\gxfcopy.c + % by adding a reserved substring (~GS~). + % + .namestring % <<>> (root) + 0 1 65535 { + 5 string cvs % <<>> (root) (0) + (~GS~) exch concatstrings + 1 index exch % <<>> (root) (root) (~GS~0) + concatstrings % <<>> (root) (root~GS~0) + dup % <<>> (root) (root~GS~0) (root~GS~0) + 3 index exch % <<>> (root) (root~GS~0) <<>> (root~GS~0) + known not { + exch pop exit % <<>> (root~GS~0) + } if + pop + } for + exch pop cvn % /root0 +} bdef + +% Get the metrics of a font, if specified. +/getfontmetrics { % <font-resource> <font> <Encoding|null> getfontmetrics + % <font-resource> <font> <Encoding|null> + % <Metrics|null> <GlyphMap|null> + + 2 index /Widths oknown { + dup //null eq { pop dup /Encoding get } if + 7 dict begin + dup length dict + /Metrics exch def + /Encoding exch def + /GlyphMap //null def + exch + dup /Widths oget /Widths exch def + % Stack: font font-res + % Note that widths are always based on a 1000-unit + % character space, but the FontMatrix may specify + % some other scale factor. Compensate for this here, + % by scaling the Widths if necessary. + 0.001 2 index /FontMatrix get 0 get + dup 0 eq { + % FontMatrix.xx == 0, so we cannot scale down by xx. + % - FontMatrix[0] == 0 implies either FontMatrix[1] <> 0 or + % FontMatrix cannot be inverted. In the 1st case we have + % FontMatrixNonHV == true and will render text with cshow + xshow. + % In the 2nd case, metrics in the PDF Font object cannot be enforced + % [by altering metrics in PS glyph space]. + % HACK: + % - we scale down by FontMatrix[1]; + % - given the format of Metrics entries we use, wy = 0 in glyph space; + % - as a result, the cshow procedure receives as wy the value we + % need for wx (all of this in PS user space). + pop + 2 index /FontMatrix get 1 get + dup 0 eq { pop 1 } if % sorry, no way to enforce PDF metrics by altering the font + } if + div + % Stack: font font-res mscale + /FirstChar 2 index /FirstChar knownoget not { + ( **** Warning: /FirstChar attribute is missing, assuming 0.\n) pdfformatwarning + 0 + } if def + /LastChar 2 index /LastChar knownoget not { + ( **** Warning: /LastChar attribute is missing, assuming 255.\n) pdfformatwarning + 255 + } if def + + Encoding length LastChar le { + ( **** Warning: Font Encoding array size is smaller than character range.\n) + pdfformatwarning + } if + + 1 index /FontDescriptor knownoget { + /MissingWidth knownoget not { 0 } if + } + { 1000 + } + ifelse /MissingWidth exch def + + Widths length LastChar FirstChar sub le { + ( **** Warning: Font Widths array size is smaller than character range.\n) + pdfformatwarning + /Widths [Widths aload length LastChar FirstChar sub exch sub MissingWidth exch {dup} repeat] def + } if + FirstChar + + 0 Encoding + { % Stack: font font-res mscale first-char index charname + + 1 index FirstChar lt { MissingWidth } { + 1 index LastChar gt { MissingWidth } { Widths 2 index FirstChar sub get } ifelse + } ifelse + oforce + + % Stack: font font-res mscale first-char index charname width + 4 index mul + % The following 'loop' is only context for 'exit'. + { + % Work around a bug in pdfTeX, which can generate Encoding + % vectors containing nulls : + 1 index //null eq { exit } if + Metrics 2 index .knownget { + 1 index ne + } { + //false + } ifelse { + % Two or more Encoding elements refer same glyph name, + % and Widths specify different wihts for it. + % Since a Postscript font can't have different + % Metrics for same glyph name, + % we generate an unique name, and create a new + % Charstrings entry with same glyph value. + GlyphMap //null eq { + /Encoding Encoding dup length array copy def + /GlyphMap 4 dict def + } if + % To prevent too many new names, check whether + % we can use one already created for same glyph. + //true + GlyphMap { % f r s c i n w b n1 n2 + 4 index eq { % f r s c i n w b n1 + dup Metrics exch get % f r s c i n w b n1 w1 + 3 index eq { % f r s c i n w b n1 + 4 3 roll pop % f r s c i w b n1 + 3 1 roll pop % f r s c i n1 w + Encoding 3 index 3 index put + //false % f r s c i n1 w b + exit + } { + pop + } ifelse + } { % f r s c i n w b n1 + pop + } ifelse + } forall % f r s c i n w b + { % Do create a new name. + Metrics 2 index //unique_name exec % f r s c i n w nn + Encoding 4 index 2 index put + GlyphMap 1 index 5 -1 roll put % f r s c i w nn + exch + % Stack: font font-res mscale first-char index new_name width + } if + } if + 2 copy Metrics 3 1 roll put + exit + } loop + pop pop + 1 add + } + forall pop pop pop + exch Encoding Metrics GlyphMap end + } { + //null //null + } ifelse +} bdef + +currentdict /unique_name undef +currentdict /match_in_diff undef + +/ToUnicodeCMapReader 4 dict begin + /defineresource % <name> <dict> <cat-name> defineresource <dict> + { + pop + dup userdict exch /.lastToUnicode exch put + exch pop + } bdef + + /CIDSystemInfo + { + ( **** Warning: ToUnicode CMap has invalid syntax near CIDSystemInfo.\n) pdfformatwarning + /CIDSystemInfo + } bdef % A work around a bug in Altona.Page_3.2002-09-27.pdf - a slash is missed. + + /CMapName + { + ( **** Warning: ToUnicode CMap has no CMapName.\n\ + See the comment to revision 6201 in gs/doc/ps2pdf.htm#Problems .\n) pdfformatwarning + /CMap1 % arbitrary, PDF defineresource tolerates non-unique names + } bdef % A work around incorrect ToUnicode CMap generated by GS before rev. 6201. + + % Split large ranges into smaller chunks to stay withing the limits + % of various PS% objects and speed up operand stack manipulation, + % esp. "counttomatk -3 roll". Bug 691908. + /beginbfrange { + { pop + mark + 256 { + currentfile token not { /endbfrange exit } if + dup /endbfrange eq { exit } if + currentfile token not { pop /endbfrange } if + currentfile token not { pop pop /endbfrange } if + dup ([) eq { + pop [ + { currentfile token not { exit } if + dup (]) eq { pop exit } if + } loop ] + } if + } repeat + dup /endbfrange eq { + pop endbfrange exit + } { + endbfrange + mark + } ifelse + } loop + } bdef +currentdict end readonly def + +/string2number % <string> string2number <number> +{ 0 exch dup 0 exch 1 exch length 1 sub { % n () i + 1 index exch get % n () v + 3 2 roll 256 mul add exch % v+n*256 () + } for + pop % N +} bind def + +/copy&def % <key> <value> <bool> copy&def - +{ + { //true + } { + currentdict gcheck { + dup gcheck not + } { + //false + } ifelse + } ifelse + { currentglobal currentdict gcheck setglobal + exch dup length string copy exch + setglobal + } if + def +} bind def + +/.convert_ToUnicode-into-g2u % <GlyphNames2Unicode> <Encoding|null> <CMap> .convert_ToUnicode-into-g2u - +{ + CMAPDEBUG { + (.convert_ToUnicode-into-g2u beg) = + } if + 3 2 roll begin + /.CodeMapData get % About the data format see gs_cmap.ps, the comment after "CMap operators". + 1 get % code maps + { + CMAPDEBUG { + dup //== exec + } if + dup length 1 sub 0 exch 5 exch { % e [] i + 2 copy get % e [] i (prefix) + string2number % e [] i prefix + 2 index 2 index 1 add get % e [] i prefix (key_size,?is_range,value_type,value_size) + dup 0 get 8 mul % e [] i prefix (key_size,?is_range,value_type,value_size) key_size*8 + 3 2 roll exch bitshift exch % e [] i prefix<<key_size*8 (key_size,?is_range,value_type,value_size) + dup 0 get exch 3 get % e [] i offset key_size value_size + 4 index 4 index 2 add get % e [] i offset key_size value_size (keys) + 5 index 5 index 3 add get % e [] i offset key_size value_size (keys) (values) + CMAPDEBUG { + ( offset=) print 4 index =string cvs print + ( key_size=) print 3 index =string cvs print + ( value_size=) print 2 index = + ( keys=) print 1 index //== exec + ( values=) print dup //== exec + } if + 1 index length 0 eq { + % A single pair. + exch pop exch pop exch pop exch % e [] i (values) offset + 4 index //null ne { + 4 index length 1 index gt { + 4 index exch get + } if + } if % e [] i (values) cid|name + exch + CMAPDEBUG { + ( defined single: ) print 1 index =string cvs print ( ) print dup //== exec + } if + //false copy&def % e [] i + pop % e [] + } { + % A range. % e [] i offset key_size value_size (keys) (values) + dup length string copy % protect the original string from modifications below. + 0 4 index 2 mul 3 index length 1 sub { % e [] i offset key_size value_size (keys) (values) j + 2 index 1 index 6 index getinterval + string2number % e [] i offset key_size value_size (keys) (values) j keyL + 6 index add + CMAPDEBUG { + ( keyL=) print dup =string cvs print + } if + 3 index 2 index 7 index add 7 index getinterval + string2number % e [] i offset key_size value_size (keys) (values) j keyL keyH + 7 index add + CMAPDEBUG { + ( keyH=) print dup = + } if + 3 2 roll 6 index idiv 5 index mul % e [] i offset key_size value_size (keys) (values) keyL keyH J + 3 index exch 6 index getinterval % e [] i offset key_size value_size (keys) (values) keyL keyH (valueL) + 3 1 roll 1 exch { % e [] i offset key_size value_size (keys) (values) (value) k + 9 index //null ne { + 9 index exch get % e [] i offset key_size value_size (keys) (values) (value) name + } if % e [] i offset key_size value_size (keys) (values) (value) cid|name + 1 index % e [] i offset key_size value_size (keys) (values) (value) cid|name (value) + CMAPDEBUG { + ( defined from range: ) print 1 index =string cvs print ( ) print dup //== exec + } if + //true copy&def % e [] i offset key_size value_size (keys) (values) (value) + + %% Calculate the value from the last string + dup dup length 1 sub 0 exch 0 1 3 -1 roll + { + % (string) value index + exch 256 mul exch + 2 index exch get add + } for + + %% and increment the value for the next string + 1 add + + %% Now convert the value into a string of bytes. + 1 index length 1 sub 1 exch 0 1 3 -1 roll + { + % (string) value divisor index + 2 index 2 index idiv 255 and % (string) value divisor index byte + exch 4 index length 1 sub exch sub % (string) value divisor byte string_position + 5 index % (string) value divisor byte string_position (string) + exch 3 -1 roll put % (string) value divisor + 256 mul + } for + pop pop pop + } for % e [] i offset key_size value_size (keys) (values) (value) + } for + pop pop pop pop pop pop pop % e [] + } ifelse + } for + pop % e + } forall + end + pop % + CMAPDEBUG { + (.convert_ToUnicode-into-g2u end) = + } if +} bind def + +/.DoToUnicode? +{ + /IgnoreToUnicode where + {/IgnoreToUnicode get not} + {//true} ifelse +} bind def + +/.processToUnicode % <font-resource> <font-dict> <encoding|null> .processToUnicode - +{ + //.DoToUnicode? exec + { + currentdict count 1 sub /.stackdepth exch .forceput + currentdict countdictstack /.dstackdepth exch .forceput + { + 1 index /FontType get 0 eq + { + 1 index /FDepVector get 0 get + dup /FontType .knownget not + { + dup /CIDFontType .knownget + { dup 2 eq {pop 11} if } + {-1} % just some value that's not a valid font type + ifelse + }if + 11 eq + { /Path known} + {pop //false} + ifelse + } + {//false} ifelse + % Currently pdfwrite is only device which can handle GlyphNames2Unicoide to + % generate a ToUnicode CMaps. So don't bother with other devices. + /WantsToUnicode /GetDeviceParam .special_op { + exch pop + }{ + //false + }ifelse + or + { + PDFDEBUG { + (.processToUnicode beg) = + } if + 2 index /ToUnicode knownoget { + dup type /dicttype eq { dup /File known not } { //true } ifelse { + % We undefine wrong /Length and define /File in stream dictionaries. + % Bug687351.pdf defines /ToUnicode /Identity-H, what is incorrect. + ( **** Warning: Ignoring bad ToUnicode CMap.\n) pdfformatwarning + pop + } { + /PDFScanRules .getuserparam dup //null eq { + pop //PDFScanRules_null + } { + 1 dict dup /PDFScanRules 4 -1 roll put + } ifelse + //PDFScanRules_true setuserparams + PDFfile fileposition + 3 -1 roll + count 1 sub + countdictstack + { //false resolvestream + % Following Acrobat we ignore everything outside + % begincodespacerange .. endcmap. + dup 0 (begincodespacerange) /SubFileDecode filter flushfile + /CIDInit /ProcSet findresource begin + //ToUnicodeCMapReader begin + 12 dict begin + /CMapType 2 def + mark exch % emulate 'begincodespacerange' + 0 (endcmap) /SubFileDecode filter cvx /begincmap cvx exch 2 .execn + endcmap + userdict /.lastToUnicode currentdict put + end end end + } + + PDFSTOPONERROR { + { exec } 0 get + //false + 5 -2 roll + 5 + } { + { stopped } 0 get + 4 2 roll + 4 + } ifelse + array astore cvx exec + + countdictstack exch sub 0 .max { end } repeat + count exch sub 2 sub 0 .max { exch pop } repeat + 3 1 roll % Stach the stop flag. + PDFfile exch setfileposition + setuserparams + { + ( **** Warning: Failed to read ToUnicode CMap.\n) pdfformatwarning + } { + 1 index /FontInfo .knownget not { + currentglobal 2 index dup gcheck setglobal + /FontInfo 5 dict dup 5 1 roll .forceput + setglobal + } if + dup /GlyphNames2Unicode .knownget not { + //true % No existing G2U, make one + } { + dup wcheck { + //false % Existing, writeable G2U, don't make new one + } { + pop //true % Existing read only G2U, make new one + } ifelse + } ifelse + { + currentglobal exch dup gcheck setglobal + dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput + 3 2 roll setglobal + } if % font-res font-dict encoding|null font-info g2u + exch pop exch % font-res font-dict g2u encoding|null + userdict /.lastToUnicode get % font-res font-dict g2u Encoding|null CMap + .convert_ToUnicode-into-g2u % font-res font-dict + //null % font-res font-dict null + } ifelse + } ifelse + } if + PDFDEBUG { + (.processToUnicode end) = + } if + } if + } stopped + { + .dstackdepth 1 countdictstack 1 sub + {pop end} for + .stackdepth 1 count 3 sub + {pop pop} for + } if + pop pop pop + currentdict /.stackdepth .forceundef + currentdict /.dstackdepth .forceundef + } + {pop pop pop} + ifelse + +} bind def + +currentdict /.DoToUnicode? .forceundef + +% ---------------- Descriptors ---------------- % + +% Partial descriptors for the 14 built-in fonts. Note that +% from PDF 1.1 to PDF 1.2, the meaning of the Flag 6 in the FontDescriptor +% object has undergone a subtle change in its meaning which has serious +% consequences for searching with Acrobat: +% In PDF 1.1, the flag meant: Font has StandardEncoding +% In PDF 1.2, the flag means: Font has (subset of) StandardRomanCharacterSet +/standardfontdescriptors mark + /Courier mark /Flags 16#23 .dicttomark + /Courier-Oblique 1 index + /Courier-Bold 1 index + /Courier-BoldOblique 1 index + /Helvetica mark /Flags 16#20 .dicttomark + /Helvetica-Oblique 1 index + /Helvetica-Bold 1 index + /Helvetica-BoldOblique 1 index + /Times-Roman mark /Flags 16#22 .dicttomark + /Times-Bold 1 index + /Times-Italic mark /Flags 16#62 .dicttomark + /Times-BoldItalic 1 index + /Symbol mark /Flags 16#4 .dicttomark + /ZapfDingbats 1 index +.dicttomark readonly def + +% ---------------- Utilities ---------------- % + +/.pdforigfontcache_g 20 dict def +currentglobal //false setglobal +systemdict /.pdforigfontcache_l 20 dict .forceput +setglobal + +% Find an original font, using cache to prevent adjustfont to accumulate changes. +/pdffindcachedfont { % <font_name> pdffindcachedfont <font> + dup //.pdforigfontcache_g exch .knownget { + exch pop + } { + dup .pdforigfontcache_l exch .knownget { + exch pop + } { + dup findfont dup + dup gcheck { //.pdforigfontcache_g } { .pdforigfontcache_l } ifelse + % Stack : font_name font font cache + 4 2 roll .growput + } ifelse + } ifelse +} bind def + +% Add original font to cache to prevent adjustfont to accumulate changes. +/pdfaddcachedfont { % <font_name> pdfaddcachedfont <font> + dup findfont dup % name font font + dup gcheck { //.pdforigfontcache_g } {.pdforigfontcache_l} ifelse + 4 2 roll % font d name font + put % font +} bind def + +/.remove_font_name_prefix { % <name> .remove_font_name_prefix <name> + dup .namestring (+) search { + //true exch + { dup 65 lt exch 90 gt or { + pop //false exit + } if + } forall + { pop exch pop cvn + } { + pop pop + } ifelse + } { + pop + } ifelse +} bind def + +% Find a font (except for embedded ones), and adjust its encoding if necessary. +/.pdfdfndict mark + /defaultfontname /Helvetica +.dicttomark readonly def +/pdffindfont { % <font-resource> <fontname> pdffindfont <font> + % If the font isn't available, synthesize one based on + % its descriptor. + dup /Font resourcestatus { + pop pop pdffindcachedfont + } { + 1 index /FontDescriptor knownoget { + % Stack: font-res fontname fontdesc + dup /Flags oget + dup 16#40 and -6 bitshift % 1, oblique/italic + 1 index 16#40000 and -17 bitshift add % 2, bold + exch 16#2 and 2 bitshift add % 8, serif + % We should look at the fixed flag, too. + % Stack: font-res fontname fontdesc properties + + % Even though /FontName is a required key in FontDescriptor dict + % (As of the PDF 1.4 Reference Manual), In the case of missing + % /FontName key, we substitue /BaseFont for the value of /FontName. + % Yet another case of broken PDF's that Adobe Reader accepts. + 1 index dup /FontName known { + /FontName oget + dup type /nametype ne { + ( **** Error: /FontName in FontDescriptor is not a name.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + cvn + } if + } { + ( **** Error: FontDescriptor missing required /FontName key. BaseFont name used.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + pop 2 index % grab the BaseFont from the stack. + } ifelse + .remove_font_name_prefix + exch + % Analyzes font name and extract "Bold" and "Narrow" properties + % which are not described by the FontDescriptor Flags. + % We also allow the font name analysis to override the Flags setting + % for Italic/Oblique as this gives us results more consistent with + % Acrobat. + 0 2 index .fontnameproperties 7 and or + % Rebind the default font name to Helvetica so that + % fonts with no properties are handled correctly. + //.pdfdfndict begin .substitutefontname end + % Stack: font-res fontname fontdesc substname|null + Fontmap 1 index known + {//false} + { .buildnativefontmap pop NativeFontmap 1 index known not} ifelse + + { + % No available good substitution, use the standard one. + pop 1 index .substitutefont + } if + dup 3 index ne QUIET not and { + (Substituting font ) print dup =only + ( for ) print 2 index =only (.) = flush + } if + pdffindcachedfont + % Stack: font-res fontname fontdesc font + + % Some non-compliant files are missing FirstChar/LastChar, + % despite referencing a non-base14 font + 3 index /FirstChar knownoget + { + 0 % push an initial value for accumating the Widths + 0 string % and an empty string to interrogate the font + 7 index /Widths knownoget + { + 0 1 2 index length 1 sub + { + dup 2 index exch get dup 0 gt % We ignore entries of zero in the widths array + { + exch 5 index add % add FirstChar to the idx to get a char code + dup 64 gt 1 index 91 lt and % we only want to consider A~Z and.... + 1 index 96 gt 2 index 123 lt and or % ... a~z + { + exch + 5 -1 roll add 4 1 roll % add the width to the accumulator on the stack + 1 string dup 0 4 -1 roll put + 3 -1 roll concatstrings exch % add the char code to the string + } + { + pop pop + } ifelse + } + { + pop pop + } ifelse + } for + pop % get rid of the Widths array + 3 -1 roll pop % get rid of the FirstChar value + dup length dup 0 gt + { + 3 -1 roll exch div % calculate an average width from the Widths array + + gsave + 2 index 10 scalefont setfont + exch dup length exch stringwidth + grestore + pop 100 mul exch div div + % Only make the font smaller/narrower, not larger/wider + dup 1.0 lt + { + 0 0 2 index 0 0 6 array astore + exch //true .copyfontdict + dup /FontMatrix get 3 -1 roll matrix concatmatrix + exch dup 3 -1 roll /FontMatrix exch put + % we don't need to definfont here, we can leave that to .completefont below + } + { + pop + } ifelse + } + { + % no suitable Widths entries - carry on and hope for the best...... + pop pop pop + } ifelse + } + { + % Broken file: no Widths array for non-base14 font - carry on and hope for the best...... + ( **** Warning: Widths array missing in FontDescriptor for non-base14 font\n) + pdfformatwarning + pop pop pop + } ifelse + } + { + ( **** Warning: FirstChar value missing in FontDescriptor for non-base14 font\n) + pdfformatwarning + } ifelse + % Stack: font-res fontname fontdesc font + % If this is a small-caps font, replace the CharString + % entries for a..z. + + exch /Flags oget 16#20000 and 0 ne { + //true .copyfontdict + dup /CharStrings 2 copy get dup length dict .copydict + % stack: font-res fontname font font /CharStrings CharStringsdict + 5 index /FirstChar get 97 .max + 6 index /LastChar get 122 .min 1 exch { + % Stack: font-res fontname font' font' /CharStrings charstrings code + % Note that this only remaps a-z, not accented characters. + 6 index /Widths oget 1 index 8 index /FirstChar get sub oget + 1 string dup 0 5 -1 roll put + % Stack: font-res font' font' /CharStrings charstrings code + % width (x) + 2 index exch dup cvn exch + dup 0 2 copy get 32 sub put 4 -1 roll { + % Stack: operand (X) width + 0 setcharwidth exch pop + currentfont /FontMatrix get matrix invertmatrix concat + 0.7 dup scale 0 0 moveto show + } /exec cvx 4 packedarray cvx put + } for put + } if + dup /FontName get 2 index ne { + //true .copyfontdict + 2 copy exch /FontName exch put + } if + exch pop .completefont + } { + % No descriptor available, use the default algorithm. + pdffindcachedfont + } ifelse + } ifelse + exch pop +} bdef + +% ---------------- Type 1 fonts ---------------- % + +/buildType1 % <Type1-font-resource> buildType1 <font> + { dup /BaseFont get pdffindfont + } bdef + +% Read an embedded Type 1 font. +/readfontfilter { % <proc> readfontfilter <filter> + 0 () /SubFileDecode filter +} bdef + +% Adobe Acrobat doesn't skip space characters after eexec +/eexec_pdf_param_dict mark + .eexec_param_dict {} forall + /keep_spaces //true +.dicttomark readonly def + +% When Type 1 font reading procedure is executing, a copy of this dictionary is current. +% We have to do something special about embedded fonts that execute definefont +% more than once -- that is the function of topFontDict. +% The whole type1 stream can be executed directly. There's no need to process +% Length1, 2, 3 keys. + +/readtype1dict 10 dict dup begin + /definefont { + exch pop + + /topFontDict where { + { /FontType % in PLRM order + /FontMatrix + /FontName + /FontInfo + /WMode + /Encoding + /FontBBox + /UniqueID + /XUID + /PaintType + /StrokeWidth + /Metrics + /Metrics2 + /CDevProc + /CharStrings + /Private + /WeightVector + } { + 2 copy .knownget { + % Stack: font topFontDict /key val + 3 index 3 1 roll put + dup /MisplacedKey 0 put + } { + pop + } ifelse + } forall + /MisplacedKey known { + ( **** Warning: Type 1 font defines some of the keys in the external scope.\n) + pdfformatwarning + } if + } if + + dup /UniqueID .knownget { + dup dup 0 lt exch 16#ffffff gt or { + ( **** Warning: Ignoring invalid /UniqueID = ) exch =string cvs + concatstrings (\n) concatstrings pdfformatwarning + dup /UniqueID undef + } { + pop + } ifelse + } if + dup /CharStrings get /.notdef known not { + dup /CharStrings get + /.notdef <9E35CED7FFD3622F09> put + ( **** Warning: Type 1 font has no /.notdef entry in /CharString dictionary.\n) + pdfformatwarning + } if + .completefont + } bdef + + /undef_proc_warning { + /Repaired //true store % flag that we have warnings + UndefProcList exch 2 copy .knownget { 1 add } { 1 } ifelse put + } bdef + + /missing-type1-procs 6 dict begin + /-| { string currentfile exch readstring pop /-| //undef_proc_warning exec } executeonly bdef + /RD { string currentfile exch readstring pop /RD //undef_proc_warning exec } executeonly bdef + /|- { noaccess def /|- //undef_proc_warning exec } executeonly bdef + /ND { noaccess def /ND //undef_proc_warning exec } executeonly bdef + /| { noaccess put /| //undef_proc_warning exec } executeonly bdef + /NP { noaccess put /NP //undef_proc_warning exec } executeonly bdef + currentdict end readonly def + + /eexec { + % Assume the font dictionary is directly below the file on the stack + count 0 gt { /topFontDict 2 index cvlit store } if + //eexec_pdf_param_dict /eexecDecode filter + + //missing-type1-procs begin + /userdict .systemvar begin + //systemdict begin + readtype1dictcopy begin cvx stopped + + currentfile flushfile % Skip the trailer after return from eexec, bug 690701. + { currentdict end //missing-type1-procs eq { exit } if } loop + { stop } if + } bdef + + /readonly-op-dict << + /stringtype 0 + /arraytype 0 + /packedarraytype 0 + /dicttype 0 + >> readonly def + + /readonly { % bug 689617 + dup type //readonly-op-dict exch known not { + ( **** Warning: Type 1 font applies operator readonly to an invalid object type.\n) + pdfformatwarning + } if + } bdef + + /prev_get /get load def + + /get { + dup /FontName eq { + % No warning, probably FontName is defined elsewhere; see definefont above. + .knownget not { /Missing } if + } { + dup /UniqueID eq { + % We don't want fonts to check /UniqueID and do 'restore'. + pop pop 16#FEDCBA98 % Arbitrary and invalid value + } { + prev_get + } ifelse + } ifelse + } bdef + + /prev_begin /begin load def + + /begin { + dup //systemdict eq { pop 0 dict } if + prev_begin + } bdef + + { /undef_proc_warning /missing-type1-procs /readonly-op-dict } + { currentdict exch undef } forall + +end readonly def + +currentdict /eexec_pdf_param_dict .undef + +/readtype1 { % <font-resource> <stream-dict> readtype1 <font|null> + PDFfile fileposition 3 1 roll % pos res stream + dup /PFB known exch % pos res pfb? stream + //true resolvestream % pos res pfb? file + exch { + //false /PFBDecode filter % pos res file' + } if + % Some buggy embedded fonts leave extra junk on the stack, + % so we have to make a closure that records the stack depth + % in a fail-safe way. This code also removes the mark when + % the implied cleartomark is not executed, i.e. Length3 == 0. + % Also restore dictstack depth. + % + //systemdict begin + //readtype1dict dup length 5 add dict copy begin % pos res file' + /file-position 4 -1 roll def % res file' + /stack-count count 3 sub def + 1 index /BaseFont oget /savedFontName exch def + /topFontDict //null def + /readtype1dictcopy currentdict def + cvx stopped + { currentdict /topFontDict known not { end } { exit } ifelse } loop + { /topFontDict //null def } if + PDFfile file-position setfileposition + count stack-count sub { pop } repeat + topFontDict end end + } bdef + +% ---------------- Type 3 fonts ---------------- % + +/buildType3 { % <Type3-font-resource> buildType3 <font> + 8 dict begin + /FontType 3 def + % If the font does not contain a Resources entry, then we use + % the resources from our current context. Page 391 of the PDF + % 1.6 spec says that the Resources dict is optional and if not + % present then we should use the Resources for the page. + % However we have a test file (687989) which uses a Type3 font + % inside a form XObject and the desired Resources are in the + % XObject dict and not in the Page dict. So we are going to + % the parent object to find resources instead of only going to + % the page dict when a font does not specify its required + % resources. + /Resources 1 index /Resources knownoget { + oforce + } { + LocalResources + } ifelse def + /FontBBox 1 index /FontBBox get cvx def + /FontMatrix 1 index /FontMatrix oget def + /CharProcs 1 index /CharProcs oget def + 1 index /Widths knownoget { + /Widths exch def + /FirstChar 1 index /FirstChar oget def + /LastChar 1 index /LastChar oget def + } if + /FontName 1 index /Name knownoget not { /PDFType3Untitled } if def + /Encoding .notdefEncoding 2 index getencoding def + % We have to define BuildChar rather than BuildGlyph: + % there is no PDF equivalent of glyphshow, and we need + % the character code to access the Widths. + /BuildChar { + % Stack: font charcode + 1 index begin 3 dict begin + /Font 3 -1 roll def /CharCode 1 index def + Encoding exch get CharProcs exch knownoget { + { //false resolvestream + % Stack: filepos stream + % Don't let setgcolor set the color inside the BuildGlyph + % procedure, because this causes an /undefined error. + q //null /FillColor gput //null /StrokeColor gput + Font /Resources get exch pdfopdict .pdfruncontext + Q + } PDFfile fileposition 2 .execn % Keep pdfcount valid. + PDFfile exch setfileposition + } { + % PDF Type 3 fonts don't use .notdef + % d1 implementation adjusts the width as needed + 0 0 0 0 0 0 + pdfopdict /d1 get exec + } ifelse + end end + } bdef + dup currentdict Encoding .processToUnicode + currentdict end .completefont exch pop +} bdef +/.adjustcharwidth { % <wx> <wy> .adjustcharwidth <wx'> <wy'> + % Enforce the metrics, in glyph space, to the values found in the PDF Font object + % - force wy == 0 (assumed, and not stored in the PDF font) + % Even though PDF1.3-1.7 specifications state that this must be 0, + % Distiller sometimes creates Type3 fonts with non-zero wy. We set + % it to 0 since this is apparently what Acrobat Reader 4 and 5 do. + % PDF1.2 does not mention this restriction, it only says + % "see setcharwidth/ setcachedevice in the PostScript Reference". + % - get wx from the Widths array (do nothing if not present) + pop 0 + /Widths where { + begin + CharCode FirstChar ge CharCode LastChar le and { + exch pop Widths CharCode FirstChar sub get exch + } if end + } if +} bdef + +% ---------------- TrueType fonts ---------------- % + +/TTfonts mark + /Arial /Helvetica + /Arial,Italic /Helvetica-Oblique + /Arial,Bold /Helvetica-Bold + /Arial,BoldItalic /Helvetica-BoldOblique + /CourierNew /Courier + /CourierNew,Bold /Courier-Bold + /TimesNewRoman /Times-Roman + /TimesNewRoman,Italic /Times-Italic + /TimesNewRoman,Bold /Times-Bold + /TimesNewRoman,BoldItalic /Times-BoldItalic +.dicttomark readonly def + +/buildTrueType { % <TrueType-font-resource> buildTrueType <font> + dup /BaseFont oget + dup /font_name gput + + 1 index /FontDescriptor knownoget + { + /Flags knownoget + { + 4 and 0 ne + { //true } % symbolic + { 1 index /Encoding oknown not} % no encoding => symbolic + ifelse + } + {//false} + ifelse + } + {//false} + ifelse + + /is_symbolic gput + 1 index /Encoding oknown { + StandardEncoding + 3 index getencoding + } { + //null + } ifelse + /prebuilt_encoding gput + //false /.render_notdef gput % set the default + + dup /Font resourcestatus dup { exch pop exch pop } if not + TTfonts 2 index known and { + dup TTfonts exch get + QUIET not { + (Substituting font ) print dup =only + ( for ) print 1 index =only (.) = flush + } if + exch 3 1 roll pdffindfont + //true .copyfontdict + 2 copy exch /FontName exch put + exch pop .completefont + } { + pdffindfont + } ifelse +} bdef + +% Read an embedded TrueType font. +/readtruetype { % <font-resource> <stream-dict> readtruetype <font> + 1 index exch + PDFfile fileposition 3 1 roll + //true resolvestream readfontfilter + % Stack: filepos fontres stream + 1 index /CIDSystemInfo oknown { + 1 index /CIDSystemInfo get dup type /packedarraytype eq {exec}if + 3 1 roll + 1 index /Subtype knownoget { + /CIDFontType2 ne { + ( **** Error: Subtype of a TT CID font is not /CIDFontType2\n) pdfformaterror + 1 index /Subtype /CIDFontType2 put + ( Output may be incorrect.\n) pdfformaterror + } if + } { + ( **** Error: Subtype of a TT CID font is missing.\n) pdfformaterror + 1 index /Subtype /CIDFontType2 put + ( Output may be incorrect.\n) pdfformaterror + } ifelse + + 1 index /BaseFont get % Use the BaseFont name for the font. Otherwise we + % would use the name table, or a manufactured name. + .loadttcidfont + % Stack: filepos fontres cidfont + } { + % filepos fontres stream + 1 index /FontDescriptor oget + /Flags oget 4 and 0 ne { + //true % symbolic + } { + 1 index /Encoding oknown not % no encoding => symbolic + } ifelse + + 2 index /Encoding oknown { + StandardEncoding + 3 index getencoding + } { + //null + } ifelse + + dup 4 index exch % filepos fontres stream is_symbolic Encoding fontres Encoding + /prebuilt_encoding exch put % filepos fontres stream is_symbolic Encoding + 5 index /BaseFont get % Use the BaseFont name for the font. Otherwise we + % would use the name table, or a manufactured name. + .loadpdfttfont + } ifelse + exch pop + PDFfile 3 -1 roll setfileposition + % Ignore both the Encoding and the Widths. + exch pop +} bdef + +% ---------------- Type 0 fonts ---------------- % + +% Predefine the known CMaps, but only create them on demand. +/knownCMaps mark + /Identity-H { /Identity-H 0 makeIdentityCMap } + /Identity-V { /Identity-V 1 makeIdentityCMap } +.dicttomark def + +/makeIdentityCMap { % <cmapname> <wmode> .makeIdentityCMap - + .currentglobal //true .setglobal 3 1 roll + /CIDInit /ProcSet findresource begin + 12 dict begin + begincmap + /WMode exch def + /CMapName exch def + /CIDSystemInfo 3 dict dup begin + /Registry (Adobe) def + /Ordering (Identity) def + /Supplement 0 def + end def + %/CMapName (see above) + /CMapVersion 1 def + /CMapType 1 def + %WMode (see above) + % The PDF documentation says that these CMaps map CIDs + % "1 to 65,536". This is a misprint for 0 to 65,535. + 1 begincodespacerange + % <0001> <00ff> <0100> <ffff> + <0000> <ffff> + endcodespacerange + 1 begincidrange + % <0001> <00ff> 1 <0100> <ffff> 256 + <0000> <ffff> 0 + endcidrange + endcmap + CMapName currentdict /CMap defineresource + knownCMaps CMapName 2 index put + end % CMap + end % CIDInit ProcSet + exch .setglobal +} bdef + +/CMap_read_dict 3 dict begin + /defineresource % <name> <dict> <cat-name> defineresource <dict> + { + pop + /.last_CMap_def 1 index store + exch pop + } bdef + /CIDSystemInfo + { + ( **** Error: CMap has invalid syntax near CIDSystemInfo.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + /CIDSystemInfo + } bdef % A work around a bug in Altona.Page_3.2002-09-27.pdf - a slash is missed. + /CMapName + { + ( **** Error: CMap has no CMapName.\n\ + See the comment to revision 6201 in gs/doc/ps2pdf.htm#Problems .\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + /CMap1 % arbitrary, PDF defineresource tolerates non-unique names + } bdef % A work around incorrect ToUnicode CMap generated by GS before rev. 6201. +currentdict end readonly def + +% Read an embedded stream that we *hope* is a PostScript CMap. According +% to the spec, ths isn't legal, but 'Acrobat opens it'.... +% +/read_CMap { + dup mark exch 0 (begincodespacerange) /SubFileDecode filter cvx exec + cleartomark + {currentdict dup /CMapType known not {end}{pop exit} ifelse} loop + /CMapType 1 def + mark exch % emulate 'begincodespacerange' + 0 (endcmap) /SubFileDecode filter cvx /begincmap cvx exch 2 .execn + endcmap + currentdict end + dup /CMapName get exch + /CMap defineresource end +} bdef + +% Read embedded CMap stream. +% if the <wmode> parameter is null, it indicates there is no WMode, and we +% should not add one. +% Following Acrobat we ignore everything outside +% begincodespacerange .. endcmap. +/read_CMap_stream { % <info> <wmode> <name> <stream> read_CMap <CMap> + dup 0 (begincodespacerange) /SubFileDecode filter flushfile + //CMap_read_dict begin + /CIDInit /ProcSet findresource begin + 12 dict begin + 4 2 roll + dup //null eq { pop } { /WMode exch def } ifelse + dup //null eq { pop } { /CIDSystemInfo exch def } ifelse + /CMapType 1 def + /.last_CMap_def currentdict def % establish binding + mark exch % emulate 'begincodespacerange' + 0 (endcmap) /SubFileDecode filter cvx /begincmap cvx exch 2 .execn + endcmap + /.last_CMap_def load + { currentdict end //CMap_read_dict eq { exit } if } loop + dup /.last_CMap_def undef + /CMap defineresource +} bdef + +currentdict /CMap_read_dict undef + +/buildType0 { % <Type0-font-resource> buildType0 <font> + dup /BaseFont get % FontName + 1 index /Encoding oget + dup type /nametype eq { + dup /CMap resourcestatus { + pop pop /CMap findresource + } { + knownCMaps 1 index .knownget + { exch pop exec } { /undefined signalerror } ifelse + } ifelse + } { + %% Bug #696449 Acrobat will read an embedded PostScript + %% CMap, whcih according to the spec is not valid, it needs + %% to be a PDF CMap stream. Here we check and see if it looks like a CMap + %% dictionary. If it is we proceed, if its some other kind of dictionary, + %% throw an error, if its neither, treat it as a stream and hope for the best. + dup /Type known { + dup /Type get /CMap eq { + PDFfile fileposition exch + dup /CIDSystemInfo knownoget { + << exch { oforce } forall >> + } { + //null + } ifelse exch + dup /WMode knownoget not {//null} if exch + dup /CMapName knownoget not {/null} if exch + //true resolvestream + read_CMap_stream + exch PDFfile exch setfileposition + } { + PDFSTOPONERROR { + /buildType0 cvx /syntaxerror signalerror + } if + } ifelse + }{ + PDFfile fileposition exch + //true resolvestream + read_CMap + exch PDFfile exch setfileposition + } ifelse + } ifelse % CMap + [ + 3 index /DescendantFonts oget { exec resourcefont } forall + ] % subfonts + .composefontdict % composefont must insert FontInfo dictionary - see gs_cmap.ps . + % Stack: fontres name font + 3 copy exch pop //null .processToUnicode + exch pop .completefont % Stack: fontres font + + 1 index /FontMatrix knownoget { + dup aload pop //true {0 0 1 0 0 1} {3 -1 roll eq and} forall { + 1 index exch makefont exch /FontName get exch + exch pop .completefont + } { + pop + } ifelse + } if exch pop +} bdef + +% ---------------- CIDFontType0/2 fonts ---------------- % + +% Insert metrics into a CIDFont, by saving the PDF W, W2, DW, and DW2 +% arrays and using a (currently very inefficient) CDevProc. +% For detail, refer "PDF Reference" 2nd ed., p314 "5.6.3 CIDFonts". +% It notes default DW is 0, but Acrobat Reader uses 1000 as default. +% If DW is 0, currentpoint does not move by default in rendering text +% horizontally, the result is unreadable. You can check it by Acrobat. + +/.pdfDefaultDW 1000 def +/.pdfDefaultDW2 [ 880 -1000 ] def + +/addCIDmetrics { % <CIDFont-resource> <CIDFont> addCIDmetrics <fontdict> + dup length 5 add dict .copydict + dup /FID undef + dup /UniqueID undef + dup /XUID undef + % Insert the widths into the font. + + % Stack: pdfresource newfont + + 1 index /DW knownoget { + 1 index /DW 3 -1 roll put + } { + dup /DW .pdfDefaultDW put + } ifelse + + 1 index /W knownoget { + //false 1 index { xcheck or } forall { + oforce_array + } if + dup 2 index /W 3 -1 roll put + .pdfMakeInternalW 1 index /.internalW 3 -1 roll put + } if + + 1 index /DW2 knownoget { + 1 index /DW2 3 -1 roll put + } { + dup /DW2 .pdfDefaultDW2 put + } ifelse + + 1 index /W2 knownoget { + //false 1 index { xcheck or } forall { + oforce_array + } if + dup 2 index /W2 3 -1 roll put + .pdfMakeInternalW2 1 index /.internalW2 3 -1 roll put + } if + + dup /CDevProc 1 index /CIDWProc load /exec load 3 packedarray cvx put + exch pop +} bdef + +/.pdfMakeInternalMTXArray { % <mtx_array> <item_size> .pdfConvertInternalW <mtx_array'> + % convert /W or /W2 to internal expression + % + % mtx_array: original /W or /W2 array + % item_size: number of metrics values per CID + % + % for detail of the metrics list format in PDF, + % refer PDF Ref. p.317 "Glyph Metrics in CIDFonts". + % + % format of single entry in internal expression + % + % [ + % [cid_begin cid_end] + % value_is_varied (bool) + % [ [values for cid_begin...] + % [values for cid_begin + 1] + % ... ] + % ] + % + + 7 dict + begin + /itemSize exch def + /M exch def % original /W or /W2 + /Msize M length def + /Mi { M i get } def % W[i] + /Mi1 { M i 1 add get } def % W[i + 1] + /putMTXEntry << + /arraytype { + [ + [Mi Mi Mi1 length itemSize idiv add 1 sub] + //true + [ + 0 itemSize Mi1 length 1 sub { + [ exch 1 1 index itemSize add 1 sub { Mi1 exch get } for ] + } for + ] + ] + /i i 2 add def + } + /integertype { + [ + [Mi Mi1] + //false + [[ i 2 add 1 i 1 add itemSize add { M exch get } for ]] + ] + /i i 2 add itemSize add def + } + >> def + + /i 0 def + + [ { putMTXEntry Mi1 type get exec i Msize ge { exit } if } loop ] + end +} def + +/.pdfMakeInternalW { dup length 0 gt { oforce_recursive 1 .pdfMakeInternalMTXArray } if } def +/.pdfMakeInternalW2 { dup length 0 gt { oforce_recursive 3 .pdfMakeInternalMTXArray } if } def + +/.pdfGetMTXByCID { % <internalMTXArray> <cid> + % .pdfGetMTXByCID + % { <MTXEntry> true | false } + + % get values for given CID from internal format of /W or /W2 + + exch + { + { + dup 0 get {} forall % Stack: <cid> <entry> <cid_0> <cid_1> + 3 index lt { pop pop //false exit } if + 2 index exch sub dup 0 lt { pop pop //false exit } if + 1 index 1 get not { pop 0 } if + exch 2 get exch get //true exit + } loop + { exit } if + } forall + dup type /arraytype eq { exch pop //true } { pop //false } ifelse +} def + +% Apply the [D]W[2] metrics to a character before displaying. +/CIDWProc { % <w0x> <w0y> <llx> <lly> <urx> <ury> + % <w1x> <w1y> <vx> <vy> <cid> <font> CIDWproc + % <w0x'> ... <vy'> + begin % push <font> to currentdict + % <w1x> <w1y> <vx> <vy> won't be used and replaced, discard now + 5 1 roll pop pop pop pop + + % get FontMatrix that applies to this CID + % (needs to convert [D]W[2] values to glyph space) + currentdict /FontMatrix get + % if the currentfont is a CIDFontType 0 CIDFont, + % we need FDArray font's FontMatrix too + FontType 9 eq { + currentdict 2 index .type9mapcid + % <w0x> <w0y> <llx> <lly> <urx> <ury> <cid> <FontMatrix> (charstring) <FDArray#> + exch pop currentdict /FDArray get exch get /FontMatrix get + % <w0x> <w0y> <llx> <lly> <urx> <ury> <cid> <FontMatrix> <FontMatrix2> + matrix concatmatrix + } if + % preserve this FontMatrix at bottom of the stack + 8 1 roll + % Stack: <FontMatrix> <w0x> <w0y> <llx> <lly> <urx> <ury> <cid> + + { + currentdict /DW .knownget not { % no DW + .pdfDefaultDW exit % replace <w0x> by defaultDW + } if + + currentdict /.internalW .knownget not { % no W + exit % use already-stacked DW + } if + + dup length 0 eq { % W is null array + pop % discard unusable W + exit % use already-stacked DW + } if + + % W is finite array, try to get W_cid + 2 index .pdfGetMTXByCID { % got W, discard DW + exch pop {} forall + exit + } if + + exit + } loop + 0 % <w0y'> + + % Stack: <FontMatrix> <w0x> <w0y> <llx> <lly> <urx> <ury> <cid> <w0x'> <w0y'> + 9 -2 roll pop pop % discard <w0x> <w0y> + 7 2 roll % put <w0x'> <w0y'> + + % Stack: <FontMatrix> <w0x'> <w0y'> <llx> <lly> <urx> <ury> <cid> + 0 % <w1x'> + exch % put <w1x'> + + % Stack: <FontMatrix> <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> <cid> + { + currentdict /DW2 .knownget not { % no DW2, use defaultDW2 + .pdfDefaultDW2 exit + } if + + currentdict /.internalW2 .knownget not { % has DW2, no W2 + exit % use already-stacked DW2 + } if + + dup length 0 eq { % W2 is null array + pop % discard unusable W2 + exit % use already-stacked DW2 + } if + + 2 index .pdfGetMTXByCID { % got W2_cid, discard DW2 + exch pop + exit + } if + + % could not get W2_cid + exit + + } loop + + exch pop % discard <cid> + + % Stack: <FontMatrix> <w0x'> <w0y'> <llx> <lly> <urx> <ury> + % <w1x'> { [<vy'> <w1y'>] | [<w1y'> <vx'> <vy'>] } + dup length 2 eq { % this is DW2 + aload pop + exch 8 index 2 div % <vx'> = <w0x'> / 2 + exch + } { % assume W2 + aload pop + } ifelse + % Stack: <FontMatrix> <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> <w1y'> <vx'> <vy'> + + % now, convert each metrics valude (1000th of text space) to glyph space + 10 -2 roll + % Stack: <FontMatrix> <llx> <lly> <urx> <ury> <w1x'> <w1y'> <vx'> <vy'> <w0x'> <w0y'> + 3 { + 10 index idtransform exch 1000 div exch 1000 div + 6 2 roll + } repeat + 10 2 roll + % Stack: <FontMatrix> <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> <w1y'> <vx'> <vy'> + 11 -1 roll pop + % Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> <w1y'> <vx'> <vy'> + end % recover currentdict +} def + +% <string> <match> tailmatch ==> <pre> true +% ==> <string> false +/tailmatch { + 2 copy length 1 index length .min + dup 2 index length exch sub exch getinterval + 1 index eq { + length 1 index length exch sub + 0 exch getinterval //true + } { + pop //false + } ifelse +} bind def + +/makeboldfont { + 16 dict begin + /strokewidth exch def + /basecidfont exch def + /FontMatrix [ 1 0 0 1 0 0 ] def + + /CIDFontName /.boldfont def + /CIDFontType 1 def + + /basefont-H /.basefont-H /Identity-H [ basecidfont ] composefont def + /basefont-V /.basefont-V /Identity-V [ basecidfont ] composefont def + + /CIDSystemInfo dup basecidfont exch get def + /FontBBox [ basecidfont /FontBBox get cvx exec + 4 2 roll basecidfont /FontMatrix get transform + 4 2 roll basecidfont /FontMatrix get transform + ] def + + /tmpstr 2 string def + /BuildGlyph { + gsave + exch begin + dup 256 idiv tmpstr exch 0 exch put + 256 mod tmpstr exch 1 exch put + rootfont /WMode known { rootfont /WMode get 1 eq } { //false } ifelse + { basefont-V } { basefont-H } ifelse setfont + strokewidth setlinewidth + 1 setlinejoin + newpath + 0 0 moveto tmpstr //false charpath stroke + 0 0 moveto tmpstr show + currentpoint setcharwidth + end + grestore + } bind def + + currentdict + end + dup /CIDFontName get exch /CIDFont defineresource +} bind def + +% <CIDFont-resource> <CIDFontName> findCIDFont <CIDFont-resource> <font> +% CIDFont-resource is not modified. +/findCIDFont { + { + dup /CIDFont resourcestatus { + pop pop /CIDFont findresource + exit + } if + .remove_font_name_prefix + dup dup length string cvs + + (,Bold) tailmatch { + exch pop + % If we're substituting a standard weight font for a + % "Light,Bold" font, don't artificially bolden further + dup (Light) tailmatch + { + pop cvn findCIDFont dup /FontName .knownget + { + (Light) tailmatch exch pop + } + { + //true + } ifelse + + { + 0.03 makeboldfont + } if + } + { + pop + cvn findCIDFont 0.03 makeboldfont + } ifelse + exit + } if + (,Italic) tailmatch { + exch pop + cvn findCIDFont + [ 1 0 0.3 1 0 0 ] makefont + exit + } if + (,BoldItalic) tailmatch { + exch pop + % see above + dup (Light) tailmatch + { + pop cvn findCIDFont dup /FontName .knownget + { + (Light) tailmatch exch pop + } + { + //true + } ifelse + + { + 0.03 makeboldfont + } if + } + { + pop + cvn findCIDFont 0.03 makeboldfont + } ifelse + [ 1 0 0.3 1 0 0 ] makefont + exit + } if + QUIET not { + (Can't find CID font ") print dup =string cvs print (".) = flush + } if + pop + + 1 index /CIDSystemInfo oget begin Registry (-) Ordering end + concatstrings concatstrings + cvn + QUIET not { + (Attempting to substitute CID font ) print dup ==only + ( for ) print 1 index ==only (, see doc/Use.htm#CIDFontSubstitution.) = flush + } if + exch pop + dup /CIDFont resourcestatus { + pop pop /CIDFont { findresource } stopped + {pop}{exit} ifelse + } if + QUIET not { + (The substitute CID font ") print dup =string cvs print + (" is not provided either. ) print + } if + + PDFNOCIDFALLBACK { + PDFSTOPONERROR { + (Will exit with error.) = flush + } + { + (Will attempt to continue, but content may be missing.) = flush + } ifelse + exit + } if + + QUIET not { + (attempting to use fallback CIDFont.) print + (See doc/Use.htm#CIDFontSubstitution.) = flush + } if + + PDFNOCIDFALLBACK not { + % This previously worked by loading the substitute font, and using that + % as a "template" to create a new CIDFont dictionary with the CIDSystemInfo + % dict appropriate for the requested font. + % This, however, caused problems with the CIDMap and thus broke pdfwrite. + % Hence, we now modify the CIDFont resource .map dictionary on the fly + % so it includes an appropriate mapping, so the subsitute font is loaded + % from the beginning with the correct ordering and supplement settings. + /CIDFont /Category findresource /.map get dup /CIDFallBack .knownget { + dup type /dicttype eq { + dup /FileType get /TrueType eq { + currentglobal + 4 1 roll + dup gcheck setglobal + dup length dict copy dup + 6 index /CIDSystemInfo oget dup /Ordering oget exch /Supplement get + % we have to copy the string, for VM correctness + exch dup length string copy exch 2 array astore + /CSI exch put 2 index exch .forceput + exch setglobal + { + % This *should* not execute arbitrary Postscript, so we ought to + % be safe running in a stopped context, in knowledge we know how + % to clean up afterwards - this would not be safe if CIDFallBack + % were a "real" CIDFont. + /CIDFont findresource + } + % if the above fails, try just using the CIDFallBack font directly + stopped + { + pop + % First, since it didn't work, remove the entry from the CIDFont category + % .map dictionary. + currentglobal exch + /CIDFont /Category findresource /.map get + dup gcheck setglobal + exch undef + setglobal + + (Warning: falling back to Identity ordering\n) print flush + /CIDFallBack /CIDFont findresource + } if + exit + } if + } if + } if + + pop pop pop + /CIDFallBack + + QUIET not { + (The fallback CID font ") print dup =string cvs print + (" is not provided. ) print + ( Finally attempting to use ArtifexBullet.\n) print flush + }if + + % We'll just use Identity for this, we have only one glyph anyway. + /ArtifexBullet /CIDFont resourcestatus { + pop pop pop + /ArtifexBullet /CIDFont findresource + exit + } + { + pop /ArtifexBullet + } ifelse + + QUIET not { + (The CID font ") print dup =string cvs print + (" is not provided. ) print + PDFSTOPONERROR + { + (Will exit with error.) = flush + } + { + (Will continue, but content may be missing.) = flush + } ifelse + } if + } if + /findresource cvx /undefined signalerror + } loop +} bdef + +/buildCIDType0 { % <CIDFontType0-font-resource> buildCIDType0 <font> + dup /BaseFont get findCIDFont exch pop +} bdef + +/buildCIDType2 { % <CIDFontType2-font-resource> buildCIDType2 <font> + dup /BaseFont get findCIDFont exch pop +} bdef + +/processCIDToGIDMap { % <fontres> <cidfont> processCIDToGIDMap <fontres> <cidfont> + 1 index /CIDToGIDMap knownoget { + PDFfile fileposition 4 1 roll + dup /Identity eq { + pop + } { + //true resolvestream + % Stack: filepos fontres font mapstream + [ + { counttomark 1 add index 32768 string readstring not { + counttomark 1 eq { + exch pop dup length + } { + ] dup 0 exch { length add } forall + } ifelse + exit + } if + } loop + 2 idiv + % Stack: filepos fontres font mapstream array/string CIDCount + dup 0 ne { + 3 index exch /CIDCount exch put + exch closefile exch + dup /CIDMap 4 -1 roll put + }{ + % If CIDCount is zero, ignore it + pop pop closefile + }ifelse + } ifelse + 3 2 roll PDFfile exch setfileposition + } if +} bdef + +% Adjust a CIDFontType0 DW[2] in the font resource. +/adjustCIDType0 { % <font-resource> <font> adjustfont <font'> + dup /FontType get 1 eq { + ( **** Error: Font resource has a wrong /Subtype.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + adjustfont + } { + addCIDmetrics + dup /CIDFontName get exch /CIDFont defineresource + } ifelse +} bind def + +% Adjust a CIDFontType2 DW[2] and CIDToGIDMap in the font resource. +/adjustCIDType2 { % <font-resource> <font> adjustfont <font'> + dup /FontType get 1 eq { + ( **** Error: Font resource has a wrong /Subtype.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + adjustfont + } { + addCIDmetrics + dup /CIDFontType get 2 eq { % OpenType CFF font converts to CIDFontType 0 + processCIDToGIDMap % that ignores CIDMap. + } if + dup /CIDFontName get exch /CIDFont defineresource + } ifelse +} bind def + +% ---------------- Other embedded fonts ---------------- % + +% Read an embedded compressed font. +/readType1C { % <font-resource> <stream-dict> readType1C <font> + 1 index exch + PDFfile fileposition 3 1 roll + dup //true resolvestream dup readfontfilter + % Stack: pos resource streamdict stream filter + 3 index /FontDescriptor oget /FontName oget + 1 index + /FontSetInit /ProcSet findresource begin //true //false ReadData + %% We need to be careful not to corrupt the stack if something went wrong. + %% Previously, if the dict was length 0 (an error occured) we would end up + %% unable to recover the stack in the calling procedure. + %% Bug #695819. + dup length 0 ne { + { exch pop exit } forall + 7 1 roll + }{ + /invalidfont signalerror + } ifelse + closefile closefile pop + PDFfile 3 -1 roll setfileposition + pop pop +} bdef + +% Read an embedded CFF CIDFont. +/readCIDFontType0C { % <font-resource> <stream-dict> readCIDFontType0C <font> + PDFfile fileposition 3 1 roll + dup //true resolvestream dup readfontfilter + % Stack: pos resource streamdict stream filter + 3 index /FontDescriptor oget /FontName oget + 1 index + /FontSetInit /ProcSet findresource begin //true //true ReadData pop + closefile closefile pop + PDFfile 3 -1 roll setfileposition + % Some broken Adobe software produces PDF files in which + % the FontName of the CFF font and the FontName in the + % FontDescriptor don't match the BaseFont in the font. + % Use the FontName, rather than the BaseFont, here. + dup /FontDescriptor oget /FontName oget /CIDFont findresource + addCIDmetrics dup /CIDFontName get exch /CIDFont defineresource +} bdef + +% Read an embedded OpenType font. +/readOTTOfont { % <font-resource> <stream-dict> readOTTOfont <font> + 1 index exch % res res strdict + PDFfile fileposition 3 1 roll % res pos res strdict + dup //true resolvestream % res pos res strdict stream + dup readfontfilter % res pos res strdict stream filter + 3 index /FontDescriptor oget + /FontName oget % res pos res strdict stream filter /name + 1 index .init_otto_font_file % res pos res strdict stream filter /name filter' + //true + 6 index /CIDSystemInfo known % res pos res strdict stream filter /name filter' bool bool + ReadData % res pos res strdict stream filter fontset + { exch pop exit } forall % res pos res strdict stream filter font + dup /FontType get 9 eq { + % OpenType may contain simple CFF font, which is accesed as a CIDFont by PDF. + % The font is converted to Type 9 CIDFont resource, which ignores CIDMap attribute. + % The following code just shuffles GlyphDirectory to the same effect. + 4 index /CIDToGIDMap knownoget { + dup type /dicttype eq { + 1 index /GlyphDirectory get exch % res pos res strdict stream filter font dir c2g + //true resolvestream % res pos res strdict stream filter font dir c2g_file + 256 dict begin + 0 2 index 0 get def % copy .notdef + 0 1 16#7fffffff { + 1 index read not { pop exit } if % res pos res strdict stream filter font dir c2g_file cid hi + 256 mul % res pos res strdict stream filter font dir c2g_file cid hi + 2 index read not { pop pop exit } if % res pos res strdict stream filter font dir c2g_file cid hi lo + add % res pos res strdict stream filter font dir c2g_file cid gid + dup 0 ne { + dup 4 index length lt { + 3 index exch get % res pos res strdict stream filter font dir c2g_file cid charstr + def % res pos res strdict stream filter font dir c2g_file + } { + pop pop + } ifelse + } { + pop pop + } ifelse + } for + closefile pop % res pos res strdict stream filter font + dup length dict copy % res pos res strdict stream filter font' + dup /GlyphDirectory currentdict put % res pos res strdict stream filter font' + end + dup /GlyphDirectory get 0 exch { + pop .max + } forall + 1 index exch /CIDCount exch 1 add put + } { + pop + } ifelse + } if + } if + 7 1 roll % font res pos res strdict stream filter + closefile closefile pop pop % font res pos + PDFfile exch setfileposition % font res + pop % font +} bdef + +% ---------------- Font lookup ---------------- % + +% Some PDF files mis-identify font type of the embedded font streams or +% include raw PFB font streams. Length1, Length2, Length3 may be wrong or +% missing. Adobe Acrobat corrects these errors transparently to the user. +% +% We ignore the font type keys and recognize the font type by the 1st 4 bytes +% of the font stream. The PFB stream is recognized by the 1st 2 bytes. + +/fonttypeprocs mark % <font-resource> -proc- <font> + /Type0 //buildType0 + /Type1 //buildType1 + /MMType1 //buildType1 + /Type3 //buildType3 + /TrueType //buildTrueType + /CIDFontType0 //buildCIDType0 + /CIDFontType2 //buildCIDType2 +.dicttomark readonly def + +/adjustfonttypes mark + /Type1 //adjustfont + /MMType1 //adjustfont + /TrueType //adjustfont + /CIDFontType0 //adjustCIDType0 + /CIDFontType2 //adjustCIDType2 +.dicttomark readonly def + +% Bind a proc and define n names +% /name ... /name {proc} n bndef - +/bndef + { exch bind exch + { dup 3 1 roll def } repeat + pop + } bdef + +% <res> run-fonttypeproc <font> +/run-fonttypeproc { + dup /Subtype knownoget not { 0 } if % res /subtype + //fonttypeprocs 1 index known not { + ( **** Error: Font /Subtype attribute is wrong or missing, /Type1 assumed.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + pop /Type1 + 2 copy /Subtype exch put + } if + //fonttypeprocs exch get exec +} bdef + +% Prototype for all procedures: <res> <desc> <stream> foo <font> +/font_tag_dict 13 dict begin + + % When the font stream is absent or cannot be read we load the font by the name. + /no_stream + { pop pop + run-fonttypeproc + } bdef + + /bad_stream + { ( **** Error: Error reading font stream, attempting to load the font using its name\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + //no_stream exec + } bdef + + <8001> % PFB + { dup /PFB //true put + exch pop readtype1 + } bdef + + (%!PS) (%!Fo) % Type1 + { exch pop readtype1 + } 2 bndef + + <01000401> <01000402> <01000403> <01000404> % Type 1C + <01000C02> <01000C03> + { exch pop + 1 index /Subtype knownoget dup { pop /CIDFontType0 eq } if { + readCIDFontType0C + } { + readType1C + } ifelse + } 6 bndef + + <00010000> (true) (typ1) (ttcf) % TrueType OpenType + { exch pop readtruetype + } 4 bndef + + (OTTO) + { exch pop + readOTTOfont + } bdef + +currentdict end readonly def +currentdict /bndef undef + +% Used to create a hash for the XUID, ths combines the input PDF file name and the +% object number (currently the object number of the FontDescriptor). NB we *must* +% use an object number, as otherwise all fonts will have the same +% XUID and Ghostscript will think they are the same font. Ths routine must not +% be used unless we have an object number which is believed to be uniqe to +% a particular font instance. +/.CRCHashFilenameAndObject % object_number (filename) CRCHasFilename integer +{ + dup % object_number (filename) (filename) + length % object_number (filename) length + 0 exch % object_number (filename) hash length + 1 sub % object_number (filename) hash length-1 + 0 1 3 -1 roll % object_number (filename) hash 0 1 length-1 + { % object_number (filename) hash index + 2 index exch get % object_number (filename) hash char + exch % object_number (filename) char hash + dup 16#F8000000 and % object_number (filename) char hash top5bits + -27 bitshift % object_number (filename) char hash top5>>27 + exch 5 bitshift % object_number (filename) char top5>>27 hash<<5 + 16#7FFFFFFF and + xor % object_number (filename) char CRC<hash> + xor % object_number (filename) newhash + } for + exch pop % object_number newhash + dup 16#F8000000 and % object_number newhash top5bits + -27 bitshift % object_number newhash top5>>27 + exch 5 bitshift % object_number top5>>27 newhash<<5 + 16#7FFFFFFF and + xor % object_number CRC<newhash> + xor % final hashed value +}bind def + +% Either patch or create a new XUID based on the existing +% XUID or UniqueID and incorporating the PDF object number +% so we get an XUID we can use to improve cache efficiency +% in multipage documents. +/patch_font_XUID % <font dict> <patch> patch_font_XUID <font dict'> +{ + %% Allow users to specify that we should not care about font object numbers + %% that is, don't patch the XUID with the object number and filename. + /PDFDontUseFontObjectNum where {/PDFDontUseFontObjectNum get}{//false}ifelse + %% Do not modify the XUID if we don't have an object number (see above) + 1 index //null eq + or + {pop} + { + pdfdict /InputPDFFileName .knownget {.CRCHashFilenameAndObject} if + exch dup /.OrigUniqueIDXUID .knownget not + { + dup /XUID .knownget not + { + dup /UniqueID .knownget + {1 array astore}{ [] } ifelse + } if + } if + + dup //null eq + { + pop exch pop + } + { + [ 1000000 3 -1 roll 4 index exch {exch} forall ] + exch //true .copyfontdict + dup 3 -1 roll /XUID exch put + exch pop + .completefont + } ifelse + } ifelse +} bind def + +/resourcefont % <font-resource> resourcefont <font> +{ + dup /PSFont .knownget dup { + pop /FID knownoget dup { pop type /fonttype eq } if + } if { + /PSFont get + } { + + dup /Subtype get /Type0 eq { + % if the font was defined in-line, we won't have a object number + dup /.gs.pdfobj# .knownget not { //null } if + } { + dup /FontDescriptor knownoget { + % if the font was defined in-line, we won't have a object number + dup /.gs.pdfobj# .knownget not { //null }if + dup //null eq { + exch pop + }{ + exch dup /FontFile knownoget not { + dup /FontFile2 knownoget not { + dup /FontFile3 knownoget not { + pop pop //null + } {pop pop}ifelse + } {pop pop}ifelse + }{pop pop}ifelse + }ifelse + }{ + //null + } ifelse + } ifelse + 3 1 roll + + % In the event we have a Type 0 dictionary with a spurious + % FontDescriptor object, remove it here to prevent confusion + % later on. + % Bug 691589 + dup /Subtype get /Type0 eq 1 index /FontDescriptor known and + { + dup /FontDescriptor undef + }if + dup /CIDSystemInfo .knownget + { + oforce_recursive + 1 index exch /CIDSystemInfo exch put + } if + + dup dup /FontDescriptor knownoget { + % font-res font-res font-desc + % The same font descriptor can be reused in a CID and non-CID contexts. + % Store CID and non-CID fonts under different keys. Bug 689301 + 1 index /Subtype knownoget dup { + pop dup /CIDFontType0 eq exch /CIDFontType2 eq or + } if { /CIDFontObject } { /FontObject } ifelse + % font-res font-res font-desc /key + 2 index 1 index .knownget { + 4 1 roll pop pop pop % font-res obj + } { + 4 1 roll % /key font-res font-res font-desc + + dup /FontFile knownoget not { + dup /FontFile2 knownoget not { + dup /FontFile3 knownoget not { + //null + } if + } if + } if + % /key res res desc stream + dup //null ne { + PDFfile fileposition + mark { + 2 index //true resolvestream dup + 4 string readstring pop + exch closefile + } stopped { + cleartomark /bad_stream + } { + exch pop + } ifelse + PDFfile 3 -1 roll setfileposition + dup length 4 lt { pop /bad_stream } if + } { + /no_stream + } ifelse + % /key res res desc stream tag + + //font_tag_dict 1 index known not { + dup 0 2 getinterval <8001> eq { + 0 2 getinterval % /key res res desc stream pfb_tag + } { + (12345678>\n) dup /ASCIIHexEncode filter dup 4 -1 roll writestring closefile + ( **** Error: unrecognized font file starts with <) exch concatstrings + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + /no_stream % /key res res desc stream unknown_tag + } ifelse + } if + //font_tag_dict exch get % /key res res desc stream {proc} + { stopped } 0 get % /key res res desc stream {proc} --stopped-- + count % /key res res desc stream {proc} --stopped-- # + countdictstack % /key res res desc stream {proc} --stopped-- # ## + PDFfile fileposition % /key res res desc stream {proc} --stopped-- # ## ### + 5 array astore cvx % /key res res desc stream {{proc} --stopped-- # ## ###} + exec + 4 -1 roll { + PDFSTOPONERROR not { + PDFfile exch setfileposition + countdictstack exch sub 0 .max { end } repeat + count 4 add exch sub 0 .max { pop } repeat + //null + } { + /resourcefont cvx /undefinederror signalerror + } ifelse + } { + PDFfile exch setfileposition + countdictstack exch sub 0 .max { end } repeat + count 3 sub exch sub 0 .max { pop } repeat + } ifelse + dup //null eq { + PDFSTOPONERROR not { + pop + ( **** Error: can't process embedded font stream,\n attempting to load the font using its name.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + dup run-fonttypeproc % /key res font + } { + /resourcefont cvx /undefinederror signalerror + } ifelse + } if + 1 index % /key res font res + 4 -1 roll 2 index % res font desc /key font + put % Save pointer to the font. + } ifelse + } { + run-fonttypeproc + } ifelse + % Stack: font-res font + 1 index exch + 1 index /Subtype get + //adjustfonttypes exch .knownget { exec } { exch pop } ifelse + 4 -1 roll patch_font_XUID + dup 3 1 roll /PSFont exch put + } ifelse + dup checkGlyphNames2Unicode +} bdef + +currentdict /font_tag_dict .undef +currentdict /fonttypeprocs .undef +currentdict /adjustfonttypes .undef + +drawopdict begin + /d0 { + currentcolor currentcolorspace .swapcolors setcolorspace setcolor .swapcolors + .adjustcharwidth setcharwidth + } bdef + /d1 { + 2 copy % ... llx lly urx ury | urx ury + 0 ne exch 0 ne % ... llx lly urx ury | ury!=0 urx!=0 + 3 index 6 index eq and % ... llx lly urx ury | ury!=0 (urx!=0 && llx==urx) + exch 2 index 5 index eq and or { % ... llx lly urx ury | (urx!=0 && llx==urx) || (ury!=0 && lly==ury) + % The bounding box is empty and likely incorrect. Don't cache. + pop pop pop pop + //d0 exec + } { + 6 -2 roll .adjustcharwidth 6 2 roll setcachedevice + } ifelse + } bdef + /Tf { + 1 index Page /Font rget { + dup type /dicttype eq { + resourcefont exch + Tf pop + } + { + PDFSTOPONERROR + { + /typecheck cvx signalerror + } + { + % Bug 689450 + type + ( **** Error: Tf refers to a resource key with an invalid value type: ) pdfformaterror + .namestring pdfformaterror + (. Assuming resource key: ) pdfformaterror + 1 index .namestring pdfformaterror + ( is a font name.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + Tf + } ifelse + }ifelse + } + { + PDFSTOPONERROR + { + pop /undefined cvx signalerror + } + { + % Bug 689037 + ( **** Error: Tf refers to an unknown resource name: ) pdfformaterror + 1 index .namestring pdfformaterror + ( Assuming it's a font name.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + Tf + } ifelse + } ifelse + } bdef +end + +end % pdfdict +end % GS_PDF_ProcSet +.setglobal diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps new file mode 100644 index 00000000000..85b5848e160 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps @@ -0,0 +1,3112 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% pdf_main.ps +% PDF file- and page-level operations. + +/.setlanguagelevel where { pop 2 .setlanguagelevel } if +.currentglobal //true .setglobal +/pdfdict where { pop } { /pdfdict 100 dict def } ifelse +pdfdict begin + +% Patch in an obsolete variable used by some third-party software. +/#? //false def + +% Test whether the current output device handles pdfmark. +/.writepdfmarkdict 1 dict dup /pdfmark //null put readonly def +/.writepdfmarks { % - .writepdfmarks <bool> + currentdevice //.writepdfmarkdict .getdeviceparams + mark eq { //false } { pop pop //true } ifelse + systemdict /DOPDFMARKS known or +} bind def + +% For simplicity, we use a single interpretation dictionary for all +% PDF graphics execution, even though this is too liberal. +/pdfopdict mark + objopdict { } forall + drawopdict { } forall + /endstream { exit } bind + (%%EOF) cvn { exit } bind % for filters + /obj { ( **** Error: Content stream is not terminated by 'endstream'.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } bind + % PDF 1.1 operators + /BX { /BXlevel BXlevel 1 add store } bind + /EX { /BXlevel BXlevel 1 sub store } bind + /PS { cvx exec } bind + % PDF 1.2 operators + /BMC { + /BMClevel BMClevel 1 add store + pop + } bind + /BDC { + /BMClevel BMClevel 1 add store + exch /OC eq { + dup type /nametype eq { + PDFfile fileposition exch % pos /Name + Page /Properties rget { + ocg-is-visible not { + OFFlevels BMClevel dup put + } if + } if + PDFfile exch setfileposition + } { + pop + } ifelse + } { + pop + } ifelse + } bind + /EMC { + OFFlevels BMClevel + 2 copy known { + 2 copy undef + } if + 1 sub /BMClevel exch store + pop + } bind + /MP { pop } bind + /DP { pop pop } bind + /- { 0 % Bug 690016 + ( **** Error: Invalid operator '-' is assumed to be the number 0.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } bind +.dicttomark readonly def + +% ======================== Main program ======================== % + +end % pdfdict +userdict begin + +/defaultfontname /Times-Roman def + +% Make sure the registered encodings are loaded, so we don't run the risk +% that some of the indices for their names will overflow the packed +% representation. (Yes, this is a hack.) +SymbolEncoding pop +DingbatsEncoding pop + +% Redefine 'run' so it recognizes PDF files. +systemdict begin +/.runps /run load def +/run { + dup type /filetype ne { (r) file } if + % skip leading whitespace characters (actually anything less than or equal to <sp>) + { dup ( ) .peekstring not { //false exit } if + dup 0 get 32 le { pop dup read pop pop } { //true exit } ifelse + } loop + exch pop + { + % Appletalk PAP sends short strings with %! header expecting a response. + % 'gv' swallows the %!PS line, then sends DSC comments beginning with %% + % and also waits for a response. The following avoids those hangs. + dup 2 string .peekstring pop dup (%!) eq exch (%%) eq or { + cvx .runps + } { + dup 1023 string .peekstring pop + % "1024 string" exceeds current %stdin buffer + % Valid PDF file cannot be smaller than 400 bytes. + (%PDF-) search { + 3 1 roll pop pop + dup (%!PS) search not { + length 0 ne { + 1 index exch readstring pop pop + (%stderr) (w) file dup + ( **** Warning: File has some garbage before %PDF- .\n) + writestring flushfile + } { + pop + } ifelse + dup (%stdin) (r) file eq { + % Copy PDF from stdin to temporary file then run it. + //null (w+) /.tempfile .systemvar exec exch 3 1 roll + % stack: tempname stdin tempfile + 64000 string + { + % stack: tempname stdin tempfile string + 2 index 1 index readstring + exch 3 index exch writestring + not { exit } if + } + loop + pop exch closefile + % stack: tempname tempfile + dup 0 setfileposition + dup + runpdf + closefile deletefile + } { + runpdf + } ifelse + } { + pop pop pop pop cvx .runps % (%!PS) found first + } ifelse + } { + pop cvx .runps % (%PDF-) not found + } ifelse + } ifelse + } { + closefile % file was empty + } ifelse +} bind odef +currentdict /runpdfstring .undef + +/runpdfbegin { % <file> runpdfbegin - + userdict begin + % It turns out that the PDF interpreter uses memory more + % effectively if it is run under at least one level of save. + % This is counter-intuitive, and we don't understand why it happens, + % but the improvement is significant. + /PDFTopSave save def + <</ProcessDSCComment //null>> setuserparams + <</ProcessComment //null>> setuserparams + %% Bug #696487, allow dict stack to grow without limit, as these PDF + %% files have stupidly deep gsave nesting and we need a dictionary per gsave + %% at the moment. + %% Remove ths if bug #696511 is ever completed (move ExtGstate parameters into gstate) + <</MaxDictStack -1>> setuserparams + %% Bug #696567, same customer as above. Ths time they have a file with a page whch has + %% 447000 ExtGState references (all of hwch contain no gstate!) Because we allocate + %% these on the stack, allow the stack to grow indefinitely in order to accomodate + %% such stupid files. Also move these lines from the end of the routine, so that + %% the increases are in place before we call odfopen, which will build the + %% resources and needs this definition in place. + <</MaxOpStack -1>> setuserparams + + 0 setobjectformat + /Page# //null def + /Page //null def + /DSCPageCount 0 def + /PDFSave //null def + GS_PDF_ProcSet begin + pdfdict begin + pdfopen begin + /CumulativePageCount currentpagedevice /PageCount get def +} bind def + +/runpdfpagerange { % - runpdfpagerange <firstpage#> <lastpage#> +<</DisablePageHandler true>> setpagedevice + /PortfolioPage where { + pop + PortfolioPage cvi dup pdfpagecount add % a b+1 + /PortfolioPage dup load % a b+1 /P () + ( ) 1 index copy pop + dup 3 index exch cvs pop % a b+1 /P (b+1) + store + 1 sub % a b + /FirstPage where { pop FirstPage <</DisablePageHandler true>> setpagedevice} { 1 } ifelse + /LastPage where { pop LastPage <</DisablePageHandler true>> setpagedevice} {2000000000} ifelse % a b fp lp + 2 index 2 index lt { % b < fp + 1e10 + } { + 3 index 2 index gt { % a > fp + 1 + } { + 1 index 4 index sub 1 add + } ifelse + } ifelse % a b fp lp f + 3 index 2 index lt { % b < bp + 3 index 5 index sub 1 add % b-a+1=count + } { + 4 index 2 index gt { + 0 + } { + 1 index 5 index sub 1 add + } ifelse + } ifelse % a b fp lp f l + 6 2 roll pop pop pop pop + + QUIET not { + 1 index 1 index gt { + (Skipping the subfile.) = flush + } { + (Processing pages ) print 1 index =only ( through ) print dup =only + (.) = flush + } ifelse + } if + } { + /PageList where { + pop PageList + (even) anchorsearch { + pop length 0 gt { + /runpdfpagerange /syntaxerror cvx signalerror + } if + /PDFPageList pdfpagecount 1 add array def + 2 2 pdfpagecount { + PDFPageList exch 1 put + } for + 1 pdfpagecount + QUIET not { + (Processing even-numbered pages\n) print + (.) = flush + } if + } { + (odd) anchorsearch { + pop length 0 gt { + /runpdfpagerange /syntaxerror cvx signalerror + } if + /PDFPageList pdfpagecount 1 add array def + 1 2 pdfpagecount { + PDFPageList exch 1 put + } for + 1 pdfpagecount + QUIET not { + (Processing odd-numbered pages\n) print 1 index =only ( through ) print dup =only + (.) = flush + } if + } { + %% validate string contents, check for digit comma or minus + dup + { + dup 44 eq not { + dup 45 eq not { + dup 48 lt 1 index 57 gt or { + /runpdfpagerange /syntaxerror cvx signalerror + } if + } if + } if + pop + } + forall + <</DisablePageHandler true>> setpagedevice + /PDFPageList pdfpagecount 1 add array def + { + (,) search { + %% We now have (post) (,) (pre) + exch pop %% get rid of the (,), leave the (post) as the string for the next iteration, deal with the section up to the comma + (-) search { + %% Now we have (end) (-) (start) + exch pop %% get rid of the minus (end) (start) + 0 exch {48 sub exch 10 mul add} forall + %% Make sure the start of the range is inside the number of available pages + dup pdfpagecount le { + exch + %% deal with a trailing '-' by replacing it with the number of pages in the file + dup length 0 eq { + pop pdfpagecount + }{ + 0 exch {48 sub exch 10 mul add} forall + } ifelse + 1 exch %% start 1 end + %% Make sure the end of the range is inside the number of available pages + dup pdfpagecount gt {pop pdfpagecount} if + {PDFPageList exch 1 put} for + } { + %% start of range invalid, drop this range. + pop pop + }ifelse + }{ + %% no minus signs, must be a simple page number + 0 exch {48 sub exch 10 mul add} forall + %% ensure its in the valid range of pages + dup pdfpagecount le { + PDFPageList exch 1 put + } { + pop + } ifelse + } ifelse + }{ + %% no commas separating pages, just the original string (), deal with its as a section, then exit the loop + (-) search { + %% Now we have (end) (-) (start) + exch pop %% get rid of the minus (end) (start) + 0 exch {48 sub exch 10 mul add} forall + %% Make sure the start of the range is inside the number of available pages + dup pdfpagecount le { + exch + %% deal with a trailing '-' by replacing it with the number of pages in the file + dup length 0 eq { + pop pdfpagecount + }{ + 0 exch {48 sub exch 10 mul add} forall + } ifelse + 1 exch %% start 1 end + %% Make sure the end of the range is inside the number of available pages + dup pdfpagecount gt {pop pdfpagecount} if + {PDFPageList exch 1 put} for + } { + %% start of range invalid, drop this range. + pop pop + }ifelse + }{ + %% no minus signs, must be a simple page number + 0 exch {48 sub exch 10 mul add} forall + %% ensure its in the valid range of pages + dup pdfpagecount le { + PDFPageList exch 1 put + } { + pop + } ifelse + } ifelse + exit %% done all the sections. + } ifelse + } loop + QUIET not { + (Processing pages ) print PageList =only + (.) = flush + } if + } ifelse + } ifelse + 1 pdfpagecount + }{ + /FirstPage where { + <</DisablePageHandler true>> setpagedevice + pop FirstPage dup pdfpagecount gt { + (\nRequested FirstPage is greater than the number of pages in the file: ) print + pdfpagecount = flush + } if + } { + 1 + } ifelse + /LastPage where {<</DisablePageHandler true>> setpagedevice pop LastPage pdfpagecount .min } { pdfpagecount } ifelse + 1 index 1 index gt { + ( No pages will be processed \(FirstPage > LastPage\).) = flush + } { + QUIET not { + (Processing pages ) print 1 index =only ( through ) print dup =only + (.) = flush + } if + } ifelse + } ifelse + }ifelse +} bind def + +/dopdfpages { % firstpage# lastpage# dopdfpages - + << /PDFScanRules //true >> setuserparams % set scanning rules for PDF vs. PS + << /RenderTTNotdef systemdict + /RENDERTTNOTDEF get >> setuserparams % Should we render TT /.notdef + 1 exch + { + %% If we have a array of pages to render, use it. + /PDFPageList where { + pop dup PDFPageList exch get 1 eq + } + {true} ifelse + + { + dup /Page# exch store + QUIET not { (Page ) print dup //== exec flush } if + pdfgetpage pdfshowpage + }{ + pop + }ifelse + } for + % Indicate that the number of spot colors is unknown in case the next page + % imaged is a PS file. + currentpagedevice /PageSpotColors known { << /PageSpotColors -1 >> setpagedevice } if + << /PDFScanRules //null >> setuserparams % restore scanning rules for PS +} bind def + +/runpdfend { + RepairedAnError + { + printrepairederror + } { + Repaired { printrepaired } if + } ifelse + currentdict pdfclose + end % temporary dict + end % pdfdict + end % GS_PDF_ProcSet + PDFTopSave restore + end % userdict + 2 vmreclaim % couldn't hurt +} bind def + +% Copy stream to an external temporary file and +% return the file name as PS name. +/copy_embedded_file { + //true resolvestream % strm + dup 1023 string .peekstring pop % "1024 string" exceeds current %stdin buffer + dup length 400 ge { % Valid PDF file cannot be smaller than 400 bytes. + (%PDF-) search { + pop pop pop //true + } { + pop //false + } ifelse + } { + pop //false + } ifelse { + //null (w) /.tempfile % strm (name) null (w) /.tempfile + .systemvar exec % strm (name) file + 3 -1 roll % (name) file strm + 32768 string % (name) file strm (buf) + { 3 copy readstring % (name) file strm (buf) file (data) bool + 3 1 roll % (name) file strm (buf) bool file (data) + writestring % (name) file strm (buf) bool + not { exit } if + } loop + pop closefile % (name) file + closefile % (name) + cvn % /name + } { + closefile + } ifelse +} bind def + +% Recursively enumerate /Names entries +% <node> pdf_collection_names /temp_file_name ... +/pdf_collection_names { + dup /Names knownoget { + exch pop + { oforce + dup type /dicttype eq { + /EF knownoget { + /F knownoget { + copy_embedded_file + } if + } if + } { + pop + } ifelse + } forall + } { + /Kids knownoget { + { oforce + dup //null ne { + pdf_collection_names + } { + pop + } ifelse + } forall + } if + } ifelse +} bind def + +% Copy selected subfiles to temporary files and return the file names +% as a PostScript names to protect them from restore. +% Currently, all PDF files in the Portfolio are extracted and returned. +% +% - pdf_collection_files [ /temp_file_name ... /temp_file_name +/pdf_collection_files { + mark + Trailer /Root knownoget { + dup /Collection oknown { + /Names knownoget { + /EmbeddedFiles knownoget { + pdf_collection_names + } if + } if + } { + pop + } ifelse + } if +} bind def + +/runpdf { % <file> runpdf - + %% Get the PDF filename (it *must* be a file even if it came from stdin it gets + %% copied to a temporary file) and store it in pdfdict. We will use this for + %% hashing fonts to detect if fonts with the same name are from different files. + %% + dup currentglobal exch true setglobal .getfilename exch setglobal /InputPDFFileName exch pdfdict 3 1 roll .forceput + + //runpdfbegin exec + //pdf_collection_files exec + dup mark eq { + pop + process_trailer_attrs + //runpdfpagerange exec + //dopdfpages exec + //runpdfend exec + } { + //runpdfend exec + ] + (1 ) 10 string copy exch + { + dup type /filetype eq { + //runpdfbegin exec + dup /PortfolioPage exch def + process_trailer_attrs + //runpdfpagerange exec + //dopdfpages exec + //runpdfend exec + closefile + } { + .namestring dup (r) file + //runpdfbegin exec + /PortfolioPage 2 index def + process_trailer_attrs + //runpdfpagerange exec + //dopdfpages exec + //runpdfend exec + deletefile + } ifelse + } forall + pop + } ifelse +} bind def + +currentdict /pdf_collection_files .undef + +end % systemdict +% Redefine the procedure that the C code uses for running piped input. +% It is OK to use { (%stdin) run } here, because a startjob cannot occur. +/.runstdin { + { (%stdin) run } execute0 +} bind def + +end % userdict +pdfdict begin + +% ======================== File parsing ======================== % + +% Read the cross-reference and trailer sections. + +% I believe the definitions here are only used when parsing the trailer +% dictionary and cross-reference table. So, following on from bug 697351 +% we will validate the operands to /R here, because the trailer and xref +% are comparatively small. Note that the bug does not expose a problem +% here, but we probably ought to validate the operands. Of course, if +% they are invalid, the PDF file is probably unreadable anyway. + +/traileropdict mark + (<<) cvn { /dictlevelcount dictlevelcount 1 add store mark } bind + (>>) cvn { { .dicttomark } stopped { + ( **** Warning: File has unbalanced >> in trailer.\n) pdfformatwarning + } if + /dictlevelcount dictlevelcount 1 sub def + dictlevelcount 0 eq { exit } if + } bind + ([) cvn { mark } bind % ditto + (]) cvn dup load +% /true true % see .pdfexectoken in pdf_base.ps +% /false false % ibid. +% /null null % ibid. + /R { + 1 index type /integertype eq 1 index type /integertype eq and { + /resolveR cvx 3 packedarray cvx + } { + ( **** Error: indirect object reference \(R\) encountered with invalid arguments.) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + } bind % see Objects below +.dicttomark readonly def + +% After reading entry count: skip whitespace, exit on a digit +% (presumably the object offset, otherwise throw /syntaxerror +/xref-char-dict << + 0 {} % \000 + 9 1 index % \t + 10 1 index % \r + 12 1 index % \f + 13 1 index % \n + 32 1 index % ' ' + + 48 { exit } bind % '0' + 49 1 index % '1' + 50 1 index % '2' + 51 1 index % '3' + 52 1 index % '4' + 53 1 index % '5' + 54 1 index % '6' + 55 1 index % '7' + 56 1 index % '8' + 57 1 index % '9' + 116 { % 't'railer + PDFfile 7 string .peekstring not { () } if + dup /trailer eq { + % Empty xref section + pop exit + } { + ( **** Warning: Invalid string \() exch concatstrings + (\) follows xref section header.\n) concatstrings + pdfformatwarning + /setxrefentry cvx /syntaxerror signalerror + } ifelse + } bind +>> readonly def + + % Read original version (pre PDF 1.5) of the xref table. + % Note: The position is the location of 'xref'. The current PDFfile + % position is just after the 'XREF'. +/readorigxref % <pos> readorigxref <trailerdict> + { + pop % We do not need the position. + + % First we search this (and any Previous) trailers, looking for + % the /Size of the xref. We use ths to initialise our storage + % of xref and similar objects. This avoids us havign to continually + % resize these objescts which is very wasteful, and leads to us + % spending much time in memory amanagement. + % Bug #696454 + PDFfile fileposition + /dictlevelcount 0 def + /TrailerSizeError false def + /ICCProfileNError false def + /TrailerSize 0 def + + { + % Throw away the 'xref' data up to the trailer dictionary + PDFfile 0 (trailer) /SubFileDecode filter flushfile + % Now read the trailer dictionary + PDFfile traileropdict .pdfrun + + dup /Size known { + % If we have a /Size then use it and exit this loop + /Size get /TrailerSize exch def + exit + }{ + dup /Prev known { + % We don't have a Size, but we have a Previous, set up to read it. + /Prev get PDFfile exch setfileposition + }{ + % No size and no Prev with a Size. Fall back to resizing the xref as we go. + pop + (*** Warning: No trailer dictionary with a Size detected, xref processing will be dynamic and slower) pdfformatwarning + /TrailerDict 0 def + exit + } ifelse + }ifelse + }loop + + % Initialise the objects with the detected Size. + TrailerSize growPDFobjects + PDFfile exch setfileposition + 0 % Initialize xref table error counter + false % Have we seen at least one section entry in this xref ? Bug #694342 + { PDFfile token pop % first object # or trailer + dup /trailer eq { + %% check to see if we have seen at least an empty section for this xref + pop {exit} + { + %% we have not seen any section entries in an xref, not even an empty section (xref 0 0) + %% Bug 694342, treat this as an error and rebuild the xref. + /setxrefentry cvx /syntaxerror signalerror + } ifelse + } + { + %% remove the boolean telling us if we have a section or not, leaving the first object number + exch pop + } ifelse + PDFfile token pop % entry count + + % remaining must be whitespace only (otherwise this xref Size was invalid. + { PDFfile (0) .peekstring not { pop exit } if + 0 get //xref-char-dict exch .knownget { + exec + } { + ( **** Warning: xref subsection header has extra characters.\n) + pdfformatwarning + /setxrefentry cvx /syntaxerror signalerror + } ifelse + PDFfile read { pop } { exit } ifelse + } loop + % This section might be adding new objects: + % ensure that Objects and Generations are big enough. + % stack: <err count> <first obj> <entry count> + 2 copy add + TrailerSize gt { + TrailerSizeError not { + /TrailerSizeError true def + PDFSTOPONERROR not { + (**** Warning: Discovered more enties in xref than declared in trailer /Size\n) pdfformatwarning + } { + /readorigxref cvx /rangecheckerror signalerror + } ifelse + } if + % We now know that the /Size was wrong. We could read the whole table + % resizing on every section, but if there are a lot of sections we + % end up spending lots of time in memory management (Bug #696454) so + % instead add 64k to the first object number in the section. This will + % waste some memory, but is faster in ths case. + 1 index 65534 add dup /TrailerSize exch def + growPDFobjects + } if + { % stack: <err count> <obj num> + % Read xref line + PDFfile 20 string readstring pop % always read 20 chars. + token pop % object position + exch token pop % generation # + exch token pop % n or f + exch % stack: <err count> <obj#> <loc> <gen#> <tag> <remainder of line> + % check to make sure trailing garbage is just white space + //false 1 index { 32 gt or } forall { + 6 -1 roll 1 add 6 1 roll % bump error count on garbage + dup (\n) search { + exch pop exch pop + } { + (\r) search { + exch pop exch pop + } if + } ifelse + length + PDFfile fileposition exch sub PDFfile exch setfileposition + } if + pop % Stack: <err count> <obj#> <loc> <gen#> <tag> + dup /n eq { % xref line tag is /n + pop % pop dup of line tag + 1 index 0 eq { + ( **** Warning: considering '0000000000 XXXXX n' as a free entry.\n) + pdfformatwarning + } { + 0 3 1 roll % Set ObjectStream object number = 0 + //false setxrefentry % Save xref entry, don't change existing entries + 3 -1 roll pop % Remove ObjectStream object onumber + } ifelse + } + { % xref line tag was not /n + /f ne % verify that the tag was /f + { /setxrefentry cvx /syntaxerror signalerror + } if + } ifelse + pop pop % pop <obj location> and <gen num> + % stack: <err count> <obj num> + 1 add % increment object number + } repeat + pop % pop <obj #> + true % We have seen at least one entry in an xref section Bug #694342 + } loop + 0 ne { + ( **** Warning: length of some xref entries is not equal to 20 bytes.\n) + pdfformatwarning + } if + PDFfile traileropdict .pdfrun + } bind def + +currentdict /xref-char-dict undef + + % This dicitonary is used to read the xref dictionary. It should work for + % reading any dictionary. dictlevelcount must contain 0. +/xrefopdict mark + (<<) cvn { /dictlevelcount dictlevelcount 1 add def mark } bind + (>>) cvn { .dicttomark /dictlevelcount dictlevelcount 1 sub def + dictlevelcount 0 eq { exit} if } bind + ([) cvn { mark } bind % ditto + (]) cvn dup load +% /true true % see .pdfexectoken in pdf_base.ps +% /false false % ibid. +% /null null % ibid. + /R { /resolveR cvx 3 packedarray cvx } bind % see Objects below +.dicttomark readonly def + +% Get a variable length positive integer value from a stream. A value +% of zero is returned if the count is zero. +/getintn { % <stream> <count> getintn int + 0 exch { 256 mul 1 index read pop add } repeat + exch pop % Discard stream +} bind def + +% This array contains handlers for processing the different types of +% entries in the XRef stream. +% Stack: <Xrefdict> <xref stream> <Index array> <pair loc> <obj num> +% <field 2> <field 3> +% The handlers leave the stack unchanged. +/xref15entryhandlers [ + { % XRef entry type 0 - free or f type xref entry +% (free ) print +% (obj num: ) print 2 index pdfstring cvs print ( ) print +% (loc: ) print 1 index pdfstring cvs print ( ) print +% (gen: ) print dup === flush + } bind % Do nothing for free xref entries + % XRef entry type 1 - normal or n type xref entry + { % field 2 = obj loc, field 3 = gen num +% (normal ) print +% (obj num: ) print 2 index pdfstring cvs print ( ) print +% (loc: ) print 1 index pdfstring cvs print ( ) print +% (gen: ) print dup === flush + 0 3 1 roll % set stream number = 0 + //false setxrefentry + 3 -1 roll pop % remove stream number + } bind + % XRef entry type 2 - compressed object type xref entry + { % field 2 = object stream num, field 3 = index into object stream +% (Compressed objects: ) print +% (obj num: ) print 2 index pdfstring cvs print ( ) print +% (field 2: ) print 1 index pdfstring cvs print ( ) print +% (field 3: ) print dup === flush + 0 //false setxrefentry pop % set generation number = 0 + } bind +] def + + % Read the PDF 1.5 version of the xref table. + % Note: The position is the location of the start of the dictionary object + % In PDF 1.5, the XRef dictionary also serves as the trailer dictionary +/readpdf15xref % <pos> readpdf15xref <trailerdict> + { + /Classic-xref //false store + PDFfile exch setfileposition % move to start of object + % Get object number, revision, and 'obj' and discard + //false PDFfile token { + type /integertype eq { + PDFfile token { + type /integertype eq { + PDFfile token { + /obj eq or + } if + } if + } if + } if + } if + not { + /readpdf15xref cvx /syntaxerror signalerror + } if + % Get the XRef dicitionary + /dictlevelcount 0 def PDFfile xrefopdict .pdfrun + % Verify that we have an XRef dictionary + dup /Type get /XRef ne { + /readpdf15xref cvx /syntaxerror signalerror + } if + % Ensure that we we have room in the objects array, etc. + dup /Size get 1 index /Index .knownget { + %% if we have a /Index, remember to add the starting index on to the size + dup 0 get 3 -1 roll add exch + %% Get the staring index and number of entries from the Index array + %% add them, and see if the result is larger than the starting index plus + %% Size entry (yes they are *supposed* to be consistent.....) + %% Bug #696365 + dup 0 get exch 1 get add 2 copy gt { + pop + }{ + exch pop + } ifelse + } if + growPDFobjects + % Create a stream for the XRef data + PDFfile token pop pop % Skip over 'stream' + dup stream //false resolvestream + % Stack: <XRefdict> <xref stream> + % The Index array defines the ranges of object numbers in the + % XRef stream. Each value pair is consists of starting object + % number and the count of consecutive objects. + % Get the Index array, if present + 1 index /Index .knownget not { % If no Index array ... + [ 0 3 index /Size get ] % Default = [ 0 Size ] + } if + % Loop through the Index array + 0 2 2 index length 1 sub { + % Get start and end of object range + 2 copy get % Start of the range + dup 3 index 3 index 1 add get % Number of entries in range + % Loop through the range of object numbers + add 1 sub 1 exch { % Form end of range, set increment = 1 + % Stack: <Xrefdict> <xref stream> <Index array> <pair loc> <obj num> + % Get xref parameters. Note: The number of bytes for each parameter + % is defined by the entries in the W array. + 4 index /W get aload pop % Get W array values + % The first field indicates type of entry. Get first field value. + % If the num. of bytes for field 1 is 0 then default field value is 1 + 3 -1 roll dup 0 eq { pop 1 } { 6 index exch getintn } ifelse + % Get the handler for the xref entry type. We will execute the + % handler after we get the other two field values. + xref15entryhandlers exch get + 3 -1 roll 6 index exch getintn % Get second field + 3 -1 roll 6 index exch getintn % Get third field + 3 -1 roll exec % Execute Xref entry handler + pop pop pop % Remove field values and obj num + } for % Loop through Xref entries + pop % Remove Index array pair loc + } for % Loop through Index array entries + pop pop % Remove Index array and xref stream + } bind def + +% Read the cross-reference table. +% <pos> is the position either from the startxref statement or the /Prev +% entry in the prior trailer dictionary. +/readxref % <pos> readxref <trailerdict> + { + PDFoffset add PDFfile exch + % Check that the given location is within the file. + dup PDFfilelen gt { + ( **** Warning: Specified xref location is beyond end of file.\n) + pdfformatwarning + /readxref cvx /invalidaccess signalerror + } if + setfileposition + % In some PDF files, this position actually points to + % white space before the xref line. Skip over this here. + { + PDFfile fileposition PDFfile read pop 32 gt { exit } if pop + } loop + dup % Make copy of the file position (before last char was read). + PDFfile exch setfileposition + % The PDF specification says that the 'xref' must be on a line + % by itself. The code here formerly used readline and linene to + % check this. However, Acrobat Reader only requires the line to + % begin with 'xref', and there are enough applications producing + % non-compliant PDF files that we have to do this too. + PDFfile pdfstring 0 4 getinterval readstring pop + (xref) eq + { + readorigxref % 'xref' -> original xref table + % if hybrid-reference PDF, also fetch the entries + % found in the XRef stream pointed by /XRefStm + dup /XRefStm knownoget { + %% Bug #695883 the test file has an XRefStm which points beyond the end of the file. + %% We check that here and simply fall back to thje classic xref if this error occurs. + dup PDFfilelen lt{ + readpdf15xref pop + } { + ( **** Error: This hybrid file's XRefStm points beyond the end of file.\n Ignoring error, output may be incorrect.\n) pdfformaterror + pop + }ifelse + } if + } + { readpdf15xref } % otherwise assume PDF 1.5 xref stream + ifelse + } bind def + +% Open a PDF file and read the header, trailer, and cross-reference. +/pdfopen { % <file> pdfopen <dict> + % Color space substitution in PDF is handled somewhat differently + % than in PostScript. A given device color space will be substituted + % if the corresponding "Default..." entry exists in the Page's + % Resource dictionary (which might be inhereted); there is no + % UseCIEColor to enable/disable color mapping. + % + % This behavior is achieved by always setting UseCIEColor to true + % in the page device dictionary. If the value of this parameter was + % originally false (i.e.: the output device does not perform color + % space substitution by default), the instances DefaultGray, + % DefaultRGB, and DefaultCMYK of the (local) ColorSpace category + % are redefined to be DeviceGray, DeviceRGB, and DeviceCMYK, + % respectively. This is not done if UseCIEColor is true by default, + % as in that case color substitution is presumably desired even + % if the file does not request it. + currentpagedevice /UseCIEColor .knownget dup { pop } if not + { .currentglobal //false .setglobal + /DefaultGray { /DeviceGray } cvlit /ColorSpace defineresource pop + /DefaultRGB { /DeviceRGB } cvlit /ColorSpace defineresource pop + /DefaultCMYK { /DeviceCMYK } cvlit /ColorSpace defineresource pop + .setglobal + } + if + pdfopenfile begin + pdfopencache + currentdict end +} bind def + +/process_trailer_attrs { % - process_trailer_attrs - + writeoutputintents + .writepdfmarks { + % Copy bookmarks (outline) to the output. + Trailer /Root knownoget { + /Outlines knownoget { + /NO_PDFMARK_OUTLINES where {pop NO_PDFMARK_OUTLINES not}{true}ifelse + { + /First knownoget { + dup type /dicttype eq { + { dup writeoutline /Next knownoget not { exit } if + dup type /dicttype eq not {exit} if + } loop + } + {pop} ifelse + }if + } { + pop + }ifelse + } if + } if + count /pdfemptycount exch def + Trailer /Info {knownoget} stopped { + ( **** Error: Unable to read Info dictionary from Trailer, Info will not be preserved.\n) pdfformaterror + count pdfemptycount sub {pop} repeat + } + { + { + mark exch + { /Author /Creator /Title /Subject /Keywords + % /Producer is Ghostscript; /CreationDate is now; /ModDate is also now. + } { + 2 copy knownoget { 3 -1 roll } { pop } ifelse + } forall + pop + dup mark ne { {/DOCINFO pdfmark} stopped {cleartomark} if } { pop } ifelse + } if + } ifelse + } if + % Initialize OC groups + Trailer /Root knownoget { + /OCProperties knownoget { + % By default, OCGs are 'on'; mark only 'off' OCGs. + % If, contrary to the spec, BaseState is OFF, mark all OCGs + % and unmark ON ones. Bug 691491. + dup /OCGs knownoget not { {} } if exch + /D knownoget { + dup /BaseState knownoget { /OFF eq } { //false } ifelse { + ( **** Warning: Default viewing OC config dictionary has /BaseState /OFF\n) + pdfformatwarning + 1 index { + oforce dup type /dicttype eq { + /OFF 0 put + } { + pop + } ifelse + } forall + /ON knownoget { + { oforce dup type /dicttype eq { + /OFF undef + } { + pop + } ifelse + } forall + } if + } { + /OFF knownoget { + { oforce dup type /dicttype eq { + /OFF 0 put + } { + pop + } ifelse + } forall + } if + } ifelse + } if + pop + } if + } if + + % Enumerate all AcroForm fields and link all separate widgets + % to the parent field. + Trailer /Root knownoget { + /AcroForm knownoget { + %% If we don't have a NeedAppearances entry, treat as if true. + %% We know Acrobat always regenerates all annotait + dup /NeedAppearances knownoget not { //true } if { + /NeedAppearances //true def + dup + /Fields knownoget { + { oforce + %% Make sure the entry from the Fields array is a dictionary + %% Bug #692447.pdf has an array of nulls. + dup type /dicttype eq { + link_widget_annots + }if + pop + } forall + } if + pop + } { + pop + } ifelse + } if + } if + + % Use OutputIntent ICC profile + systemdict /UsePDFX3Profile .knownget { + dup //false eq { + pop + } { + dup //true eq { pop 0 } if + dup type /integertype eq { + Trailer /Root oget /OutputIntents knownoget { + dup length 2 index le % i [] bool + 2 index 0 lt or { + pop pop + (Source file has no OutputIntent with this number.\n) + } { + exch oget dup type /dicttype ne { pop << >> } if + /DestOutputProfile knownoget { + [ /ICCBased 3 -1 roll ] ICCBased-resolve + 1 get .set_outputintent + () + } { + (This OutputputIntents dictionary has no profile.\n) + } ifelse + } ifelse + } { + pop (File has no /OutputIntents attribute\n) + } ifelse + } { + pop (UsePDFX3Profile must be a boolean or an integer.\n) + } ifelse + dup () eq { + pop + } { + ( **** ) stderrprint stderrprint + } ifelse + } ifelse + } if + Trailer /Root knownoget { /PageLabels knownoget { + %% Currenlty only the pdfwrite device can handle PageLabels + %% because we deal with these using putparams, not pdfmarks + %% This is because the pdfmark syntax can't handle all the + %% possible page label formats in a PDF file! + /WantsPageLabels /GetDeviceParam .special_op { + pop pop + .pdfpagelabels + } { + pop + } ifelse + } if + } if +} bind def + +% Verify that each entry in the xref table is pointing at an object with +% the correct object number and generation number. +/verify_xref % - verify_xref - +{ PDFfilelen + 1 1 Objects length 1 sub % stack: filesize 1 1 <number of objects - 1> + { % Check if the object is free (i.e. not used). The values in + % Generations is the generation number plus 1. If the value in + % Generations is zero then the object is free. + % Stack: <filesize> <obj num> + Generations 1 index get % Get the genration number + 0 ne { % Skip if object number is free + ObjectStream 1 index get % Check if object is in objectstream + 0 eq { % We only check objects not in an objectstream + { % Use stop context since we may get an error if object is invalid + dup Objects exch get % Get the object location + PDFoffset add dup 3 index ge % Compare object location to file size + { pop //true } % Rebuild if location not in file + { PDFfile exch setfileposition % Go to the object location + //true % Stack: <filesize> <obj num> <true> + PDFfile token pop % Read object number from file + 2 index eq { % Verify object number + PDFfile token pop % Read generation number from file + Generations 3 index % Get specified generaton number + get 1 sub % Gen numbs are stored with 1 added. + eq { % Verify generation number + PDFfile token pop + /obj eq { % Verify 'obj' text + pop //false % We have valid object, do not rebuild + } if + } if + } if + } ifelse + } .internalstopped + { //true } if % If we stop then we need to rebuild + % Stack: <filesize> <obj num> <need rebuild flag> + { + ( **** Warning: File has an invalid xref entry: ) + pdfformatwarning + pdfstring cvs pdfformatwarning + (. Rebuilding xref table.\n) pdfformatwarning + search_objects + exit + } if % If the entry is invalid + } { + % The object is in an object stream. We currently do not rebuild + % objects in an object stream. So If we find one, then abort the + % verification of the xref table entries. + pop exit % Pop object number and then exit loop + } ifelse % If not in an object stream + } if % If object entry is not free + pop % Remove object number + } for + pop % Remove the size of the file +} bind odef + +/pdfopencache { % - pdfopencache - + % Create and initialize some caches. + /PageCount pdfpagecount def + /PageNumbers PageCount 65534 .min dict def + /PageIndex PageCount 65534 .min array def +} bind def + +/pdfopenfile { % <file> pdfopenfile <dict> + pdfdict readonly pop % can't do it any earlier than this + 32 dict begin + /LocalResources 0 dict def + /DefaultQstate //null def % establish binding + /Printed where { pop } { + % Guess whether the output device is a printer. + /Printed currentpagedevice /OutputFile known def + } ifelse + currentpagedevice /OutputFile known { + currentpagedevice /OutputFile get (%d) search { + pop pop pop + /NO_PDFMARK_OUTLINES true def + /NO_PDFMARK_DESTS true def + } { + pop + }ifelse + } if + /PSLevel1 where { pop } { /PSLevel1 //false def } ifelse + % NB: PDFfile is used outside of the PDF code to determine that a + % PDF job is being processed; to not change or hide this key. + cvlit /PDFfile exch def + /PDFsource PDFfile def + /Repaired //false def + /RepairedAnError //false def + /StreamRunAborted //false def + /NeedAppearances //false def + currentglobal //true .setglobal globaldict begin + /UndefProcList 0 dict def + end .setglobal + PDFfile dup 0 setfileposition + 0 () /SubFileDecode filter % to avoid file closure + pdfstring readstring pop + (%PDF-) search not {/pdfopen cvx /syntaxerror signalerror} if + length /PDFoffset exch def pop + % some badly formed PDF's (Visioneer) have something other than EOL + % after the version number. If we get an error, shorten the string + % and try again. + //false exch % error encountered + { { cvr } stopped + { exch pop //true exch 0 1 index length 1 sub dup 0 eq + { pop 0 exit } if % exit if string now empty + getinterval % trim character from right end and retry + } + { exch { + ( **** Warning: PDF version number not followed by EOL.\n) + pdfformatwarning + } + if exit + } + ifelse + } loop + + /Classic-xref //true def + /PDFversion exch def + % Read the last cross-reference table. + count /pdfemptycount exch def + /Trailer << >> def % Initialize to an emptry dict. + {initPDFobjects findxref readxref} + PDFSTOPONERROR not { + .internalstopped { + recover_xref_data % Read failed. Attempt to recover xref data. + search_trailer % Search for the primary trailer + false % search_trailer sets up /Trailer, so don't run the code to do that... + } { + true + } ifelse + } { + exec true + } ifelse + + { + /Trailer exch def % Save trailer dict after first xref table + % Read any previous cross-reference tables. When we are done, + % verify that the entries in the xref tables are valid if NoVerifyXref + % is not defined. + Trailer + { /Prev knownoget not { % If no previous xref table then ... + Classic-xref { + /NoVerifyXref where { pop } { verify_xref } ifelse + } if + exit + } if + { readxref } + PDFSTOPONERROR not { + .internalstopped { + recover_xref_data % Read failed. Attempt to recover xref data. + exit % Exit loop since recover gets all obj data. + } if % If readxref stopped + } { + exec + } ifelse + % The PDF spec. says that each trailer dict should contain the required + % entries. However we have seen a PDF file that only has a Prev entry in + % the initial trailer dict. Acrobat complains but it accepts these files. + % To work with these files, we are copying any entries which we find in + % a previous trailer dict which are not present in the initial dict. + dup { + Trailer 2 index known { + pop pop % discard if key already present + } { + Trailer 3 1 roll put % add key if not present + } ifelse + } forall + } loop % Loop to previous trailer + } if + + /NumObjects Objects length def % To check that obj# < NumObjects + + % Scan numbers in the range 2147483648..4294967295 in Encrypt dictionary + % as unsigned integers for compatibility with Acrobat Reader. Bug 689010. + << /PDFScanUnsigned //true >> setuserparams + { Trailer /Encrypt knownoget { + pop + pdf_process_Encrypt % signal error + } if + } stopped + << /PDFScanUnsigned //false >> setuserparams + { stop } if + + % Check for recursion in the page tree. Bug 689954, MOAB-06-01-2007 + verify_page_tree + + currentdict end + } bind def + +%% Executing token on a file will close the file if we reach EOF while +%% processing. When repairing broken files (or searching for startxref +%% and the xref offset) we do *NOT* want this to happen, because that +%% will close PDFfile and we don't have the filename to reopen it. +/token_no_close { %% -file- token_no_close <any> true | false + dup type /filetype eq { + << + /EODCount 2 index bytesavailable %% fix data length at underlying bytes + /EODString () %% make sure filter passes that many bytes, no EOD + /CloseSource false %% Be sure, tell the filter not to close the source file + >> + /SubFileDecode filter dup %% -filter- -filter- + token { %% -filter- <any> true | false + %% token returned a value + exch %% <any> filter + closefile %% <any> + true %% <any> true + }{ + %% token didn't find a value + closefile %% - + false %% false + } ifelse + } { + token + } ifelse +} bind def + +% Look for the last (startxref) from the current position +% of the file. Return the position after (startxref) if found or -1 . +/find-startxref { % <file> find_eof <file> <position> + -1 + { 1 index dup 0 (startxref) /SubFileDecode filter flushfile + bytesavailable 9 lt { exit } if + pop dup fileposition + } loop +} bind def + +% Search for the last 'startxfer' and read a following token, which +% must be a number. Don't pay any attention to %%EOF because it's +% often mangled. +% There seems to be no limit on the amount of garbage that can be +% appended to the PDF file. Current record (60K) belongs to +% PDF-Out (v 2.0 - 35). We start the search from the last 1024 +% bytes and continue from the beginning of the file. +/findxref { % - findxref <xrefpos> + PDFfile dup dup dup 0 setfileposition bytesavailable + dup /PDFfilelen exch def + % Find the last %%EOF string (within 1024 bytes) + 1024 sub PDFoffset .max + setfileposition find-startxref % file pos|-1 % search the last 1024 bytes + dup 0 le { + pop + dup PDFoffset setfileposition find-startxref % search from the beginnibg + dup 0 le { + ( **** Error: Cannot find a 'startxref' anywhere in the file.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + /findxref cvx /syntaxerror signalerror + } if + } if + 2 copy setfileposition + pop token_no_close not { //null } if + dup type /integertype ne { + ( **** Error: invalid token after startxref.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + /findxref cvx /syntaxerror signalerror + } if +} bind def + +/stderrfile (%stderr) (w) file def +/stdoutfile (%stdout) (w) file def + +/stderrprint { % <string> stderrprint - + //stderrfile dup 3 -1 roll writestring flushfile +} bind def + +/stdoutprint { % <string> stderrprint - + //stdoutfile dup 3 -1 roll writestring flushfile +} bind def + +/pdfformaterror { % <string> pdfformaterror - + stdoutprint + /Repaired //true store + /RepairedAnError //true store +} bind def + +/pdfformatwarning { % <string> pdfformaterror - + QUIET not {stdoutprint}{pop}ifelse + /Repaired //true store + PDFSTOPONWARNING {/warning cvx /undefined signalerror} if +} bind def + +/knownoget_safe +{ 2 copy knownoget { 3 1 roll pop pop //true } { pop pop //false } ifelse +} odef + +/printProducer { + Trailer /Info { knownoget_safe } stopped { pop pop //false } if { + /Producer knownoget not { //null } if + } { + //null + } ifelse + dup //null eq { + pop + } { + ( **** The file was produced by: \n **** >>>> ) stderrprint + % Handle a Unicode Producer. + (\376\377) anchorsearch { + pop dup length 2 idiv string 0 1 2 index length 1 sub { + % Stack: origstr newstr i + 1 index exch 3 index 1 index 2 mul 1 add get put + } for exch pop + } if + stderrprint + ( <<<<\n) stderrprint + } ifelse +} bind def +% The UndefProcList collects noisy warnings. +% This gets rid of many multiple warnings from pdf_font.ps +/printCollectedWarnings { + UndefProcList length 0 gt { + (\n **** Embedded font uses undefined procedure\(s\): ) stderrprint + UndefProcList { + exch .namestring stderrprint ( ) stderrprint + =string cvs stderrprint ( times, ) stderrprint + } forall + (\n) stderrprint + } if +} bind def + +/printrepaired { + QUIET not + { + printCollectedWarnings + (\n **** This file had errors that were repaired or ignored.\n) + stdoutprint + printProducer + ( **** Please notify the author of the software that produced this\n) + stdoutprint + ( **** file that it does not conform to Adobe's published PDF\n) + stdoutprint + ( **** specification.\n\n) + stdoutprint + } if +} bind def + +/printrepairederror { + QUIET not + { + printrepaired + ( **** The rendered output from this file may be incorrect.\n) + stdoutprint + } if +} bind def + +% Write the outline structure for a file. Uses linkdest (below). +% omit links to pages that don't exist. +/writeoutline % <outlinedict> writeoutline - + { mark + 0 2 index /First knownoget + { { exch 1 add exch /Next knownoget not { exit } if } loop } + if + % stack: dict mark count + dup 0 eq + { pop 1 index } + { 2 index /Count knownoget { 0 lt { neg } if } if + /Count exch 3 index + } + ifelse + { + dup /A knownoget { + dup /URI known { + /A mark 3 2 roll % <<>> /A [ <<action>> + { oforce } forall + .dicttomark + 3 2 roll + } + { + dup /S knownoget { + %% Because we process GoTo Destinations into absolute references in the PDF file + %% we need to resolve the /D or /Dest. However, we must *not* do this for + %% GoToR Destinations because (obviously) those are in a different file and + %% we cannot resolve them into absolute references. We don't need to anyway + %% because that file must already have a named destination. + dup /GoTo eq { + pop + dup /D knownoget { + exch pop exch dup length dict copy dup /Dest 4 -1 roll put + } if + }{ + dup /GoToR eq { + pop /A mark % <<..action dict..>> /A [ + 3 2 roll % /A [ <<..action dict..>> + { oforce } forall + .dicttomark + 3 2 roll + }{ + dup /Launch eq { + pop /A mark % <<..action dict..>> /A [ + 3 2 roll % /A [ <<..action dict..>> + { oforce } forall + .dicttomark + 3 2 roll + }{ + /Named eq { + /N knownoget { % Assume /S /Named + namedactions exch .knownget { exec } if + } if + } if + } ifelse + } ifelse + } ifelse + } if + } ifelse + } if + linkdest + } stopped + { + cleartomark % ignore this link + ( **** Warning: Outline has invalid link that was discarded.\n) + pdfformatwarning + } { + /Title knownoget { + {/Title exch /OUT pdfmark} stopped {cleartomark} if + } { + cleartomark + ( **** Warning: Outline without /Title attribute was discarded.\n) + pdfformatwarning + } ifelse + } + ifelse + /First knownoget + { { dup writeoutline /Next knownoget not { exit } if } loop } + if + } bind def + +% Close a PDF file. +/pdfclose % <dict> pdfclose - + { begin + PDFfile closefile + end + } bind def + +% ======================== Page accessing ======================== % + +% Get a (possibly inherited) attribute of a page. +/pget % <pagedict> <key> pget <value> -true- + % <pagedict> <key> pget -false- + { + 2 copy knownoget + { exch pop exch pop //true } + { exch /Parent knownoget + { exch pget } + % finally see if the key is (misplaced) in the Root Catalog dict + { dup Trailer /Root oget exch knownoget dup { + 3 -1 roll ( **** Error: The /) pdfformaterror 50 string cvs pdfformaterror + ( key is missing from the Page tree.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } + { exch pop } + ifelse + } + ifelse + } + ifelse + } bind def + +% Get the value of a resource on a given page. +/rget { % <resname> <pagedict> <restype> rget <value> -true- + % <resname> <pagedict> <restype> rget -false- + LocalResources 1 index knownoget { + 3 index knownoget + } { + //false + } ifelse { + exch pop exch pop exch pop //true + } { + 1 index /Resources pget { + 1 index knownoget { 3 index knownoget } { //false } ifelse + } { + //false + } ifelse { + 4 1 roll pop pop pop //true + } { + countdictstack array dictstack + //false 5 1 roll + dup length 1 sub -1 4 { % false /Name <<>> /Type [<<gstate>>] i + 1 index exch get % false /Name <<>> /Type [] <<gstate>> + /FormResDict .knownget { % false /Name <<>> /Type [] <<res>> + 2 index knownoget { % false /Name <<>> /Type [] <<type_dict>> + 4 index knownoget { % false /Name <<>> /type [] <<res_dict>> + ( **** Warning: resource was found only in an external (parent) context.\n) pdfformatwarning + //true 7 2 roll % <<res_dict>> true false /Name <<>> /Type [] + pop exit + } if + } if + } if + } for + pop pop pop pop + } ifelse + } ifelse +} bind def + +% Get the total number of pages in the document. +/pdfpagecount % - pdfpagecount <int> + { Trailer /Root knownoget { + /Pages knownoget { + dup /Count knownoget { + dup type /integertype eq { dup 0 le } { //true } ifelse { + pop + dup /Kids knownoget { + pop + ( **** Warning: Invalid Page count.\n) pdfformatwarning + % find the last page and use that as the Count + 1 1 999999999 { + dup pdffindpage? + exch pop + //null eq { exit } { pop } ifelse + } for + 1 sub % decrement to last page that we were able to find + 2 copy /Count exch put + } { + 0 % return 0 and keep 0 page count. + ( **** Warning: PDF document has no pages.\n) pdfformatwarning + } ifelse + } if + exch pop + } { + dup /Type oget /Page eq { + << exch 1 array astore /Kids exch /Count 1 /Type /Pages >> + Trailer /Root oget /Pages 3 -1 roll put + 1 + ( **** Warning: No /Pages node. The document /Root points directly to a page.\n) + pdfformatwarning + } { + ( **** Warning: Page count not found; assuming 1.\n) + pdfformatwarning + pop 1 + } ifelse + } ifelse + } { + 0 + }ifelse + }{ + 0 + } ifelse + } bind def + +% Check for loops in the 'page tree' but accept an acyclic graph. +% - verify_page_tree - +/verify_page_tree { + Trailer /Root knownoget { + /Pages knownoget { + 10 dict begin + /verify_page_tree_recursive { + dup 1 def + dup /Kids knownoget { + { oforce + dup //null ne { + currentdict 1 index known { + ( **** Error: there's a loop in the Pages tree. Giving up.\n) pdfformaterror + /verify_page_tree cvx /syntaxerror signalerror + } if + verify_page_tree_recursive + } { + pop + } ifelse + } forall + } if + currentdict exch undef + } def + verify_page_tree_recursive + end + } if + } if +} bind def + +/pdffindpage? { % <int> pdffindpage? 1 null (page not found) + % <int> pdffindpage? 1 noderef (page found) + % <int> pdffindpage? 0 null (Error: page not found) + Trailer /Root oget /Pages get + { % We should be able to tell when we reach a leaf + % by finding a Type unequal to /Pages. Unfortunately, + % some files distributed by Adobe lack the Type key + % in some of the Pages nodes! Instead, we check for Kids. + dup oforce /Kids knownoget not { exit } if + exch pop //null + 0 1 3 index length 1 sub { + 2 index exch get + dup oforce dup /Kids known { /Count oget } { pop 1 } ifelse + % Stack: index kids null noderef count + dup 5 index ge { pop exch pop exit } if + 5 -1 roll exch sub 4 1 roll pop + } for exch pop + % Stack: index null|noderef + dup //null eq { pop pop 1 //null exit } if + } loop +} bind def + +% Find the N'th page of the document by iterating through the Pages tree. +% The first page is numbered 1. +/pdffindpageref { % <int> pdffindpage <objref> + dup pdffindpage? + % Stack: index countleft noderef + 1 index 1 ne { pop pop /pdffindpage cvx /rangecheck signalerror } if + exch pop + PageIndex 2 index 1 sub 65533 .min 2 index oforce put + PageNumbers 1 index oforce 3 index dup 65534 le + { put } + { pop pop pop } % don't store more than 65534 pagenumbers + ifelse + exch pop +} bind def +/pdffindpage { % <int> pdffindpage <pagedict> + pdffindpageref oforce +} bind def + +% Find the N'th page of the document. +% The first page is numbered 1. +/pdfgetpage % <int> pdfgetpage <pagedict> + { PageIndex 1 index 1 sub dup 65533 lt + { get } + { pop pop //null } + ifelse + dup //null ne + { exch pop oforce } + { pop pdffindpage } + ifelse + } bind def + +% Find the page number of a page object (inverse of pdfgetpage). +/pdfpagenumber % <pagedict> pdfpagenumber <int> + { % We use the simplest and stupidest of all possible algorithms.... + PageNumbers 1 index .knownget + { exch pop + } + { 1 1 PageCount 1 add % will give a rangecheck if not found + { dup pdfgetpage oforce 2 index eq { exit } if pop + } + for exch pop + } + ifelse + } bind def + +% Arrange the four elements that define a rectangle into a 'normal' order. +/normrect_elems % <x1> <y1> <x2> <y2> normrect_elems <llx> <lly> <urx> <ury> +{ + 4 { % Bug 693919 + dup type dup /integertype ne exch /realtype ne and { + ( **** Error: replacing malformed number ') pdfformaterror pdfstring cvs pdfformaterror + (' with 0.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + 0 + } if + 4 1 roll + } repeat + exch 4 1 roll % <x2> <x1> <y1> <y2> + 2 copy gt { exch } if % <x2> <x1> <lly> <ury> + 4 2 roll 2 copy lt { exch } if % <lly> <ury> <urx> <llx> + 4 1 roll exch % <llx> <lly> <urx> <ury> +} bind def + +% Arrange a rectangle into a 'normal' order. I.e the lower left corner +% followed by the upper right corner. +/normrect % <rect> normrect <rect> +{ + aload pop normrect_elems 4 array astore +} bind def + +/fix_empty_rect_elems % </Name> <x1> <y1> <x2> <y2> fix_empty_rect_elems <x1> <y1> <x2'> <y2'> +{ dup 3 index eq { //true } { 1 index 4 index eq } ifelse { + pop pop pop pop + ( **** Warning: File has an empty ) pdfformaterror pdfstring cvs pdfformaterror + (. Using the current page size instead.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + 0 0 currentpagedevice /PageSize get aload pop + } { + 5 -1 roll pop + } ifelse +} bind def + +/boxrect % <llx> <lly> <urx> <ury> boxrect <x> <y> <w> <h> + { exch 3 index sub exch 2 index sub + } bind def +/resolvedest { % <name|string|other> resolvedest <other|null> + dup type /nametype eq { + Trailer /Root oget /Dests knownoget { + exch knownoget not { //null } if + } { + pop //null + } ifelse + } { + dup type /stringtype eq { + Trailer /Root oget /Names knownoget { + /Dests knownoget { + exch nameoget + } { + pop //null + } ifelse + } { + pop //null + } ifelse + } if + } ifelse +} bind def + +% Procedures to do the necessary transformations of view destinations +% <PDF2PS_matrix> <rot> <view> -- <view'> +/viewdestprocs 8 dict dup begin + /Fit { exch pop exch pop } bind def + /FitH { + aload length 2 lt { + 1 array astore + 3 1 roll pop pop + }{ + 0 4 -1 roll 1 and 0 eq { exch } if + 4 -1 roll transform exch pop + 2 array astore + } ifelse + } bind def + /FitV { + aload length 2 lt { + 1 array astore + 3 1 roll pop pop + }{ + 0 4 -1 roll 1 and 0 ne { exch } if + 4 -1 roll transform pop + 2 array astore + } ifelse + } bind def + /FitB /Fit load def + /FitBH /FitH load def + /FitBV /FitV load def + /XYZ { + dup length dup 4 gt { + pop /viewdestprocs cvx /rangecheck signalerror + }{ + dup 4 eq { + pop aload pop + } { + dup 3 eq { + pop aload pop //null + } { + dup 2 eq { + pop aload pop //null //null + } { + dup 1 eq { + pop aload pop //null //null //null + } { + pop /viewdestprocs cvx /rangecheck signalerror + } ifelse + } ifelse + } ifelse + } ifelse + } ifelse + 3 1 roll + 2 copy 7 -1 roll 1 and 0 ne { exch } if 4 2 roll % odd rotation switches x<->y + 2 { dup //null eq { pop 0 } if exch } repeat % replace nulls with 0 + 7 -1 roll transform % transform coordinates + 2 { 3 -1 roll //null eq { pop //null } if exch } repeat % put the nulls back + 3 -1 roll + 4 array astore + } bind def + /FitR { + exch pop + aload pop + 2 { 5 index transform 4 2 roll } repeat normrect_elems + 5 array astore + exch pop + } bind def +end readonly def + +/linkdest { % <link|outline> linkdest + % ([/Page <n>] /View <view> | ) <link|outline> + dup /NewWindow knownoget { + /NewWindow exch 3 -1 roll + } if + dup /F knownoget { + /File exch 3 -1 roll + } if + dup /Dest knownoget + { + resolvedest + dup type /dicttype eq { /D knownoget not { //null } if } if + dup //null eq + { pop } + { dup 0 oget + //false % don't have a page# and transformation matrix (yet) + 1 index type /dicttype eq { + 1 index /Type knownoget { + /Page eq { + pop % the "false" flag + dup pdf_cached_PDF2PS_matrix exch + dup /Rotate pget not { 0 } if cvi 90 idiv exch + pdfpagenumber /CumulativePageCount where {pop CumulativePageCount}{0}ifelse add + //true % now we have a page# and a transformation matrix + } if + } if + } if + % stack: <link|outline> <dest> ( <PDF2PS_matrix> <rot> <page#> true | <page> false ) + { + /Page exch 6 2 roll + % stack: [/Page <page#>] <link|outline> <dest> <PDF2PS_matrix> <rot> + 3 -1 roll dup length 1 sub 1 exch getinterval /View 4 1 roll + % stack: [/Page <page#>] <link|outline> /View <PDF2PS_matrix> <rot> <view> + //viewdestprocs 1 index 0 get get exec + 3 -1 roll + } { + dup type /integertype eq { + /CumulativePageCount where {pop CumulativePageCount}{0}ifelse add + /Page exch 1 add 4 2 roll + } { + pop + } ifelse + dup length 1 sub 1 exch getinterval /View exch 3 -1 roll + } ifelse + } + ifelse + } + if +} bind def +% <pagedict> mark ... -proc- <page#> <error> +/namedactions 8 dict dup begin + /FirstPage { 1 /CumulativePageCount where {pop CumulativePageCount}{0}ifelse add //false } def + /LastPage { pdfpagecount /CumulativePageCount where {pop CumulativePageCount}{0}ifelse add //false } def + /NextPage { counttomark 2 add index pdfpagenumber 1 add dup pdfpagecount gt exch /CumulativePageCount where {pop CumulativePageCount}{0}ifelse add exch} bind def + /PrevPage { counttomark 2 add index pdfpagenumber 1 sub dup 1 lt exch /CumulativePageCount where {pop CumulativePageCount}{0}ifelse add exch} bind def +end readonly def +% <pagedict> <annotdict> -proc- - +/annottypes 5 dict dup begin + /Text { + mark exch + { /Rect /Open /Contents /F} + { 2 copy knownoget { 3 -1 roll } { pop } ifelse } + forall pop {/ANN pdfmark} stopped {cleartomark} if + } bind def + /Link { + /NO_PDFMARK_DESTS where {pop NO_PDFMARK_DESTS not}{true}ifelse + { + mark exch + dup /BS knownoget { << exch { oforce } forall >> /BS exch 3 -1 roll } if + dup /F knownoget { /F exch 3 -1 roll } if + dup /C knownoget { /Color exch 3 -1 roll } if + dup /Rect knownoget { /Rect exch 3 -1 roll } if + dup /Border knownoget { + dup type /arraytype eq { + dup length 3 lt + } { + //true + } ifelse { + pop [ 0 0 0 ] % Following AR5 use invisible border. + } if + /Border exch 3 -1 roll + } if + dup /A knownoget { + dup /URI known { + /A mark 3 2 roll % <<>> /A [ <<action>> + { oforce } forall + .dicttomark + 3 2 roll + } { + dup /S knownoget { + %% Because we process GoTo Destinations into absolute references in the PDF file + %% we need to resolve the /D or /Dest. However, we must *not* do this for + %% GoToR Destinations because (obviously) those are in a different file and + %% we cannot resolve them into absolute references. We don't need to anyway + %% because that file must already have a named destination. + dup /GoTo eq { + pop + dup /D knownoget { + exch pop exch dup length dict copy dup /Dest 4 -1 roll put + } if + }{ + dup /GoToR eq { + pop /A mark % <<..action dict..>> /A [ + 3 2 roll % /A [ <<..action dict..>> + { oforce } forall + .dicttomark + 3 2 roll + }{ + dup /Launch eq { + pop /A mark % <<..action dict..>> /A [ + 3 2 roll % /A [ <<..action dict..>> + { oforce } forall + .dicttomark + 3 2 roll + }{ + /Named eq { + /N knownoget { + namedactions exch .knownget { + exec { + pop + ( **** Warning: Ignoring a named action pointing out of the document page range.\n) + pdfformatwarning + } { + /Page exch 3 -1 roll + } ifelse + } if + } if + } if + }ifelse + } ifelse + } ifelse + } if + } ifelse + } if + { linkdest } stopped { + cleartomark + ( **** Warning: Link annotation points out of the document page range.\n) + pdfformatwarning + } { + pop {/LNK pdfmark} stopped {cleartomark} if + } ifelse + }{pop} ifelse + } bind def +end readonly def + +% **** The following procedure should not be changed to allow clients +% **** to directly interface with the constituent procedures. GSview +% **** and some Artifex customers rely on the pdfshowpage_init, +% **** pdfshowpage_setpage, pdfshowpage_finish so all logic should be +% **** implemented in one of those three procedures. +/pdfshowpage % <pagedict> pdfshowpage - + { dup /Page exch store + pdfshowpage_init % <pagedict> + pdfshowpage_setpage % <pagedict> + pdfshowpage_finish % - + } bind def + +/pdfpagecontents % <pagedict> pdfpagecontents <contents> + { } bind def + +/pdfshowpage_init % <pagedict> pdfshowpage_init <pagedict> + { /DSCPageCount DSCPageCount 1 add store + } bind def + +/get_media_box { % <pagedict> get_media_box <box> <bool> + /MediaBox pget { + oforce_array //true + } { + ( **** Error: Page has no /MediaBox attribute. Using the current page size.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + [ 0 0 currentpagedevice /PageSize get aload pop ] //false + } ifelse +} bind def + +/get_any_box { % <pagedict> get_any_box <box name> <box> + //systemdict /UseBleedBox .knownget dup { and } if { + dup /BleedBox pget { + /BleedBox exch + } if + } if + //systemdict /UseTrimBox .knownget dup { and } if { + dup /TrimBox pget { + /TrimBox exch + } if + } if + dup type /arraytype ne { + //systemdict /UseArtBox .knownget dup { and } if { + dup /ArtBox pget { + /ArtBox exch + } if + } if + } if + dup type /arraytype ne { + //systemdict /UseCropBox .knownget dup { and } if { + dup /CropBox pget { + /CropBox exch + } if + } if + } if + dup type /arraytype ne { + /MediaBox exch get_media_box pop + } { + oforce_elems % <<pdict>> /SomeBox x0 y0 x1 y1 + 6 -1 roll get_media_box { % /SomeBox x0 y0 x1 y1 [MediaBox] + aload pop % /SomeBox x0 y0 x1 y1 X0 Y0 X1 Y1 + 5 -1 roll .min exch % /SomeBox x0 y0 x1 X0 Y0 mY1 X1 + 5 -1 roll .min exch % /SomeBox x0 y0 X0 Y0 mX1 mY1 + 4 2 roll % /SomeBox x0 y0 mX1 mY1 X0 Y0 + 5 -1 roll .max exch % /SomeBox x0 mX1 mY1 mY0 X0 + 5 -1 roll .max exch % /SomeBox mX1 mY1 mX0 mY0 + 4 2 roll % /SomeBox mX0 mY0 mX1 mY1 + } { + pop + } ifelse + 4 array astore % /SomeBox [mX0 mY0 mX1 mY1] + } ifelse +} bind def + +% Compute the matrix that transforms the PDF->PS "default" user space +/pdf_PDF2PS_matrix { % <pdfpagedict> -- matrix + matrix currentmatrix matrix setmatrix exch + % stack: savedCTM <pdfpagedict> + dup get_any_box + % stack: savedCTM <pdfpagedict> /Trim|Crop|Art|MediaBox <Trim|Crop|Art|Media Box> + oforce_elems normrect_elems fix_empty_rect_elems 4 array astore + //systemdict /PDFFitPage known { + PDFDEBUG { (Fiting PDF to imageable area of the page.) = flush } if + currentpagedevice /.HWMargins get aload pop + currentpagedevice /PageSize get aload pop + % Adjust PageSize and .HWMargins for the page portrait/landscape orientation + 2 copy gt % PageSize_is_landscape + 7 index aload pop 3 -1 roll sub 3 1 roll exch sub exch + 10 index /Rotate pget not { 0 } if cvi 90 idiv 1 and 0 ne { exch } if + gt % Box_is_landscape + xor % PageSize_is_landscape(or square) xor'ed with Box_is_lanscape suggests rotate + 2 index 2 index eq not and { % don't rotate if Page is square + 1 index 0 translate 90 rotate % add in a rotation + PDFDEBUG { ( Rotating the page for best fit) = flush } if + 2 copy ne { + % rotate the .HWMargins + 2 copy lt { + 6 2 roll 4 -1 roll 6 -2 roll + } { + 6 2 roll 4 1 roll 6 -2 roll + } ifelse + % rotate the page dimensions + exch + } if + } if + 3 -1 roll sub 3 1 roll exch sub exch + % stack: savedCTM <pdfpagedict> <Crop|Media Box> Xmin Ymin Xmax Ymax + PDFDEBUG { ( Translate up by [ ) print 3 index =print (, ) print 2 index =print ( ]) = flush } if + 3 index 3 index translate % move origin up to imageable area + 2 index sub exch 3 index sub exch 4 2 roll pop pop + % stack: savedCTM <pdfpagedict> [Box] XImageable YImageable + 2 index aload pop 2 index sub exch 3 index sub exch 4 2 roll pop pop + 5 index /Rotate pget not { 0 } if 90 cvi idiv 1 and 0 ne { exch } if + % stack: savedCTM <pdfpagedict> [Box] XImageable YImageable XBox YBox + 4 copy + 3 -1 roll exch div 3 1 roll div .min + % stack: savedCTM <pdfpagedict> [Box] XImageable YImageable XBox YBox scale + PDFDEBUG { ( Scale by ) print dup = flush } if + 5 -4 roll + % stack: savedCTM <pdfpagedict> [Box] scale XImageable YImageable XBox YBox + 3 index 2 index 6 index mul sub 2 div 3 index 2 index 7 index mul sub 2 div + PDFDEBUG { ( Centering translate by [ ) print 1 index =print (, ) print dup =print ( ]) = flush } if + translate pop pop pop pop + } { + //systemdict /NoUserUnit .knownget not { //false } if { + 1 + } { + 1 index /UserUnit knownoget { + PDFDEBUG { (Scaling due to UserUnit by ) print dup = flush } if + } { + 1 + } ifelse + } ifelse + } ifelse + % stack: savedCTM <pdfpagedict> [Box] scale + dup scale + % Rotate according to /Rotate + aload pop boxrect + { + { pop pop } + { -90 rotate pop neg 0 translate } + { 180 rotate neg exch neg exch translate } + { 90 rotate neg 0 exch translate pop } + } + 5 index /Rotate pget not { 0 } if cvi + PDFDEBUG { dup 0 ne { (Rotating by ) print dup =print ( degrees.) = flush } if } if + 90 idiv 3 and get exec + % Now translate to the origin given in the Crop|Media Box + exch neg exch neg translate + % stack: savedCTM <pdfpagedict> + pop + matrix currentmatrix exch setmatrix +} bind def + +% Cache the matrix that transforms the PDF->PS "default" user space +% into <pdfpagedict> under the key //PDF2PS_matrix_key, then return it +/PDF2PS_matrix_key (PDF->PS matrix) cvn def +/pdf_cached_PDF2PS_matrix { % <pdfpagedict> -- <PDF2PS_matrix> + dup //PDF2PS_matrix_key .knownget { + exch pop + } { + dup dup pdf_PDF2PS_matrix //PDF2PS_matrix_key exch put + //PDF2PS_matrix_key get + } ifelse +} bind def +currentdict /PDF2PS_matrix_key undef + +/.pdfshowpage_Install { % <pagedict> [<prevproc>] .pdfshowpage_Install - + 0 get exec + pdf_cached_PDF2PS_matrix concat +} bind def + +/pdfshowpage_setpage { % <pagedict> pdfshowpage_setpage <pagedict> + 6 dict begin % for setpagedevice + % Stack: pdfpagedict + % This comment is no longer true, and is maintained here for history only: + % + % UseCIEColor is always true for PDF; see the comment in runpdf above + % + % We now test the page to see if it defines any Default* colour spaces and + % only set UseCIEColor if it does. This prevents a spurious warning from + % pdfwrite about not using UseCIEColor with pdfwrite. + % + pdfshowpage_detect_cspacesub { + /UseCIEColor //true def + } if + + % Only lock in Orientation if we need to for pdfmarks + .writepdfmarks { /Orientation 0 def } if + currentpagedevice + % Stack: pdfpagedict currentpagedevicedict + 1 index get_any_box + % Stack: pdfpagedict currentpagedevicedict /BoxName [box] + oforce_elems normrect_elems fix_empty_rect_elems boxrect 4 2 roll pop pop + 3 index /Rotate pget not { 0 } if cvi 90 idiv 1 and 0 ne { exch } if + % stack: pdfpagedict currentpagedevicedict boxwidth boxheight + //systemdict /PDFFitPage known { + % Preserve page size, + % but choose portrait/landscape depending on box width:height ratio + % (if box width == height, select portrait orientation) + gt + 1 index /PageSize get aload pop + 2 copy gt + 4 -1 roll ne { exch } if + } { + % Set the page size. + //systemdict /NoUserUnit .knownget not { //false } if not { + 3 index /UserUnit knownoget { + dup 4 -1 roll mul 3 1 roll mul + } if + } if + } ifelse + 2 array astore /PageSize exch def + % Determine the number of spot colors used on the page. Note: This searches + % the pages resources. It may be high if a spot color is in a resource but + % is not actually used on the page. + currentpagedevice /PageSpotColors known { /PageSpotColors 2 index countspotcolors def } if + + % Let the device know if we will be using PDF 1.4 transparency. + % The clist logic may need to adjust the size of bands. + 1 index pageusestransparency /PageUsesTransparency exch def + dup /Install .knownget { + % Don't let the Install procedure get more deeply + % nested after every page. + dup type dup /arraytype eq exch /packedarraytype eq or { + dup length 4 eq { + dup 2 get /.pdfshowpage_Install load eq { + 1 get 0 get % previous procedure + } if + } if + } if + } { + { } + } ifelse 1 array astore + 2 index exch /.pdfshowpage_Install load /exec load + 4 packedarray cvx + % Stack: pagedict currentpagedict installproc + /Install exch def + % Stack: pagedict currentpagedict + pop currentdict end setpagedevice +} bind def + +/.free_page_resources { % - .free_page_resources - + Page /Resources pget { + /Shading knownoget { + { dup type /dicttype eq { + dup /.shading_dict known { + dup /.shading_dict undef + } if + } if + pop pop + } forall + } if + } if +} bind def + +/pdfshowpage_finish { % <pagedict> pdfshowpage_finish - + save /PDFSave exch store + /PDFdictstackcount countdictstack store + /PDFexecstackcount count 2 sub store + (before exec) VMDEBUG + + % set up color space substitution (this must be inside the page save) + pdfshowpage_setcspacesub + + .writepdfmarks { + + % Copy the boxes. + { /CropBox /BleedBox /TrimBox /ArtBox } { + 2 copy pget { + % .pdfshowpage_Install transforms the user space do same here with the boxes + oforce_elems + 2 { Page pdf_cached_PDF2PS_matrix transform 4 2 roll } repeat + normrect_elems 4 index 5 1 roll fix_empty_rect_elems 4 array astore + mark 3 1 roll {/PAGE pdfmark} stopped {cleartomark} if + } { + pop + } ifelse + } forall + + % Copy annotations and links. + dup /Annots knownoget { + 0 1 2 index length 1 sub + { 1 index exch oget + dup type /dicttype eq { + dup /Subtype oget annottypes exch .knownget { exec } { pop } ifelse + } { + pop + } ifelse + } + for pop + } if + + } if % end .writepdfmarks + + % Display the actual page contents. + 9 dict begin + /BXlevel 0 def + /BMClevel 0 def + /OFFlevels 0 dict def + /BGDefault currentblackgeneration def + /UCRDefault currentundercolorremoval def + %****** DOESN'T HANDLE COLOR TRANSFER YET ****** + /TRDefault currenttransfer def + matrix currentmatrix 2 dict + 2 index /CropBox pget { + oforce_elems normrect_elems boxrect + 4 array astore 1 index /ClipRect 3 -1 roll put + } if + dictbeginpage setmatrix + /DefaultQstate qstate store + + count 1 sub /pdfemptycount exch store + % If the page uses any transparency features, show it within + % a transparency group. The scan was performed during pdfshowpage_setpage + % and the result was set in the pagedevice dictionary. Use it rather than + % scanning again IF it is present. If the pdfshowpage_setup was not called + % (eg GSView 5) then it will not be present, so we must rescan. + currentpagedevice /PageUsesTransparency .knownget not {dup pageusestransparency} if + dup /PDFusingtransparency exch def { + % If the current device isn't ProcessColorModel /DeviceCMYK, or if it is a + % HighLevelDevice (pdfwrite) we don't need the special handling of Overprint + % transparency, so disable the checking. + currentpagedevice dup /ProcessColorModel get /DeviceCMYK ne exch /HighLevelDevice known or { + /checkOPtrans { pop false } def % NB: original will be restored from PDFsave + } if + % Show the page within a PDF 1.4 device filter. + 0 .pushpdf14devicefilter { + /DefaultQstate qstate store % device has changed -- reset DefaultQstate + % If the page has a Group, enclose contents in transparency group. + % (Adobe Tech Note 5407, sec 9.2) + dup /Group knownoget { + 1 index /CropBox pget { + /CropBox exch + } { + 1 index get_media_box pop /MediaBox exch + } ifelse + oforce_elems normrect_elems fix_empty_rect_elems 4 array astore .beginformgroup + showpagecontents + .endtransparencygroup + } { + showpagecontents + } ifelse + } stopped { + % abort the transparency device + .abortpdf14devicefilter + /DefaultQstate qstate store % device has changed -- reset DefaultQstate + stop + } if + { } settransfer % identity transfer during popdevice (put_image) + .poppdf14devicefilter % NB: reset to DefaultQstate will also restore transfer function + /DefaultQstate qstate store % device has changed -- reset DefaultQstate + } { + /checkOPtrans { pop false } def % no-op the check if the page doesn't use transparency + % NB: original will be restored from PDFsave + showpagecontents + } ifelse + .free_page_resources + % todo: mixing drawing ops outside the device filter could cause + % problems, for example with the pnga device. + endpage + end % scratch dict + % Some PDF files don't have matching q/Q (gsave/grestore) so we need + % to clean up any left over dicts from the dictstack + + PDFdictstackcount //false + { countdictstack 2 index le { exit } if + currentdict /n known not or + end + } loop { + StreamRunAborted not { + (\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n) + + pdfdict /.Qqwarning_issued .knownget + { + { + pop + } + { + currentglobal pdfdict gcheck .setglobal + pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } ifelse + } + { + currentglobal pdfdict gcheck .setglobal + pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } ifelse + } if + } if + pop + count PDFexecstackcount sub { pop } repeat + (after exec) VMDEBUG + Repaired % pass Repaired state around the restore + RepairedAnError + PDFSave restore + currentglobal pdfdict gcheck .setglobal + pdfdict /.Qqwarning_issued //false .forceput + .setglobal + /RepairedAnError exch def + /Repaired exch def +} bind def + +% Display the contents of a page (including annotations). +/showpagecontents { % <pagedict> showpagecontents - + dup % Save the pagedict for the Annotations + count 1 sub /pdfemptycount exch store + gsave % preserve gstate for Annotations later + /Contents knownoget not { 0 array } if + dup type /arraytype ne { 1 array astore } if { + oforce dup type /dicttype eq { + //false resolvestream pdfopdict .pdfrun + } { + (**** Error: The Page /Contents array contains an element which is not a stream\n This page will not display correctly\n\n) + pdfformaterror + pop exit + }ifelse + } forall + % check for extra garbage on the ostack and clean it up + count pdfemptycount sub dup 0 ne { + ( **** Error: File did not complete the page properly and may be damaged.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + { pop } repeat + } { + pop + } ifelse + grestore + % Draw the annotations + //systemdict /ShowAnnots .knownget not { //true } if { + /Annots knownoget { + { oforce + dup //null ne { + .writepdfmarks + %% + %% We don't want to preserve annotations with ps2write, because we don't convert them + %% back into pdfmarks on output. + %% + /ForOPDFRead /GetDeviceParam .special_op { + exch pop + }{ + //false + }ifelse + not + and + //systemdict /PreserveAnnots .knownget not {//true} if and { + mark exch {preserveannot} PDFSTOPONERROR {exec}{stopped {(Error: Ignoring invalid annotation, output may be incorrect.\n) pdfformaterror} if} ifelse cleartomark + }{ + mark exch {drawannot} PDFSTOPONERROR {exec}{stopped {(Error: Ignoring invalid annotation, output may be incorrect.\n) pdfformaterror} if} ifelse cleartomark + } ifelse + } { + pop + } ifelse + } forall + } if + } if + //systemdict /ShowAcroForm .knownget { //true eq } { //false } ifelse { + Trailer /Root oget /AcroForm knownoget { draw_acro_form } if + } if +} bind def + +/processcolorspace { % - processcolorspace <colorspace> + % The following is per the PLRM3. + currentdevice 1 dict dup /ProcessColorModel dup put .getdeviceparams + exch pop exch pop + dup type /nametype ne { cvn } if + dup { setcolorspace } .internalstopped { pop /DeviceRGB } if +} bind def + +% ------ Transparency support ------ % + +% Determine whether a page might invoke any transparency features: +% - Non-default BM, ca, CA, or SMask in an ExtGState +% - Image XObject with SMask +% Note: we deliberately don't check to see whether a Group is defined, +% because Adobe Illustrator 10 (and possibly other applications) define +% a page-level group whether transparency is actually used or not. +% Ignoring the presence of Group is justified because, in the absence +% of any other transparency features, they have no effect. +% +% Transparency is a 1.4 feature however we have seen files that claimed +% to be PDF 1.1 with transparency features. Bugs 689288, 691273. +/pageusestransparency { % <pagedict> pageusestransparency <bool> + NOTRANSPARENCY { + pop //false + } { + dup //false exch { + 4 dict 1 index resourceusestransparency { pop not exit } if + /Parent knownoget not { exit } if + } loop + % Also check for transparency in the annotation (if not in resources). + { pop //true } { annotsusetransparency } ifelse + } ifelse +} bind def + +% Check if transparency is specified in an ExtGState dict +/extgstateusestransparency { % <gstate dict> extgstateusestransparency <bool> + //false exch % Assume no transparency + dup //null eq { + pop % bug 692050 + } { + { % establish loop context + dup /BM knownoget { + dup /Normal ne exch /Compatible ne and { pop not exit } if + } if + dup /ca knownoget { 1 ne { pop not exit } if } if + dup /CA knownoget { 1 ne { pop not exit } if } if + dup /SMask knownoget { /None ne { pop not exit } if } if + pop exit + } loop + } ifelse +} bind def + +% Check if transparency is used in a Pattern +/patternusestransparency { % <Pattern dict> patternusestransparency <bool> + dup //null eq NOTRANSPARENCY or + { pop //false } + { //false exch % Assume no transparency + { + 4 dict 1 index resourceusestransparency { pop not exit } if + dup /ExtGState knownoget { extgstateusestransparency { pop not exit } if } if + pop exit + } loop + } + ifelse +} bind def + +% Check the Resources of a page or Form. Check for loops in the resource chain. +/resourceusestransparency { % <dict> <dict> resourceusestransparency <bool> + { % Use loop to provide an exitable context. + /Resources knownoget not { 0 dict } if + 2 copy .knownget { + { % Some circular references may be missed because scanning stops + % when the 1st transparency is found. + ( **** Warning: Found circular references in resource dictionaries while checking for transparency.\n) + pdfformatwarning + } if + pop //false exit + } if + 2 copy //true put % In the current chain. + dup /ExtGState knownoget { + //false exch + { exch pop oforce extgstateusestransparency { pop //true exit } if + } forall + { pop //true exit } if + } if + dup /Pattern knownoget { + //false exch + { exch pop oforce patternusestransparency { pop //true exit } if + } forall + { pop //true exit } if + } if + dup /XObject knownoget { + dup type /dicttype eq { + //false exch + { + exch pop oforce + dup //null ne { + dup type /dicttype eq { + dup /Subtype get + dup /Image eq { + 1 index /SMask oknown { pop pop not exit } if + 1 index /SMaskInData knownoget { + 0 ne { pop pop not exit } if + } if + } if + /Form eq { + dup /Group known {pop pop true exit}{ + 3 index exch resourceusestransparency { not exit } if + } ifelse + } { + pop + } ifelse + } { + pop + ( **** Warning: Ignoring non-dictionary /XObject attribute while checking for transparency.\n) + pdfformatwarning + } ifelse + } { + pop + } ifelse + } forall + { pop //true exit } if + } { + ( **** Warning: Ignoring non-dictionary /XObject while checking for transparency.\n) + pdfformatwarning + pop + } ifelse + } if + 2 copy //false put % Visited but not in the current chain. + pop //false exit + } loop + exch pop +} bind def + +% Check if the annotations on a page use transparency +/annotsusetransparency { % <page dict> annotsusetransparency <bool> + //false exch % Assume no transparency + /Annots knownoget { % Get Annots array + { + oforce + dup //null ne { + dup /Subtype knownoget { + /Highlight eq { % Highlight annotation is always implemented + pop pop //true exit % as transparency. + } if + } if + dup /AP knownoget { % Get appearance dict for the annoation + /N knownogetdict { % Get the /N (i.e. normal) appearance stream + 4 dict exch resourceusestransparency { pop pop //true exit } if + } if + } if % If AP dict known + dup /CA knownoget { + 1 le { + pop pop //true exit + } if + } if + /ca knownoget { + 1 le { + pop //true exit + } if + } if + } { + pop + } ifelse + } forall % For all annots on the page + } if +} bind def + +% Add a color name to our spot color list. Ignore /All and /None +/putspotcolor { % <name> <spotcolordict> putspotcolor - + % The 'name' could be a string. If so then convert to a name. + exch dup type /stringtype eq { cvn } if + dup dup /None eq exch /All eq or { pop pop } { 0 put } ifelse +} bind def + +% Determine which spot colors are used within a color space Note: This +% dict will include all colors used in Separation or DeviceN color spaces. +% Thus it may include Cyan, Magenta, Yellow, and Black. +% <colorspace> <spotcolordict> colorspacespotcolors - +/colorspacespotcolors { + exch dup type /arraytype eq { + % If we have an Indexed color space then get the base space. + dup 0 oget % <<>> [csp] /Type + dup /Indexed eq { + pop 1 oget % <<>> [base] + 2 copy exch colorspacespotcolors + } { + % Stack: <spotcolordict> <colorspace> <colorspacetype> + dup /Separation eq exch /DeviceN eq or { + dup 1 oget dup type /arraytype eq { + { oforce 2 index putspotcolor } forall + } { + 2 index putspotcolor + } ifelse + } if + } ifelse + } if + pop pop +} bind def + +% Check the Resources of a page, form, or annotation. Determine which spot +% colors are used within the resource Note: The spot color dict will include +% all colors used in Separation or DeviceN color spaces. Thus it may include +% Cyan, Magenta, Yellow, and Black. We also pass a dict that is used to check +% for loops in the resource list. +% <spotcolordict> <loopdict> <page/form/annot dict> +% resourcespotcolors <spotcolordict> <loopdict> +/resourcespotcolors { + { % Use loop to provide an exitable context. + % Exit if no Resources entry + /Resources knownoget not { exit } if + % Exit if we have already seen this dict + 2 copy known { pop exit } if + + % Save the Resources dict into our loop checking dict. + 2 copy 0 put + + % Scan resources that might contain a color space. + dup /ColorSpace knownoget { + { exch pop oforce 3 index colorspacespotcolors } forall + } if + dup /Pattern knownoget { + { exch pop oforce + dup /Shading knownoget { + exch pop + /ColorSpace oget 3 index colorspacespotcolors + } { + 4 copy exch pop resourcespotcolors pop pop pop + } ifelse + } forall + } if + dup /Shading knownoget { + { exch pop + oforce /ColorSpace + { oget } stopped + { + pop pop + ( **** Error: invalid color space in shading, output may be incorrect.\n) pdfformaterror + } + { 3 index colorspacespotcolors} + ifelse + } forall + } if + /XObject knownoget { + dup type /dicttype eq { + { exch pop oforce + dup type /dicttype eq { + dup //null ne { + dup /Subtype oget + dup /Form eq { + pop resourcespotcolors + } { + /Image eq { + /ColorSpace knownoget { + 2 index colorspacespotcolors + } if + } { + pop + } ifelse + } ifelse + } { + pop + } ifelse + } { + pop + } ifelse + } forall + } { + pop % Just ignore here, already reported by resourceusestransparency. + } ifelse + } if + exit + } loop +} bind def + +% Determine which spot colors are used within the annotations. Note: This +% dict will include all colors used in Separation or DeviceN color spaces. +% Thus it may include Cyan, Magenta, Yellow, and Black. +% <spotcolordict> <loopdict> <annotsarray> +% annotsspotcolors <spotcolordict> <loopdict> +/annotsspotcolors { + { oforce + dup //null ne { + /AP knownoget { % Get appearance dict for the annoation + /N knownogetdict { % Get the /N (i.e. normal) appearance stream + resourcespotcolors + } if % If normal appearance streamknown + } if % If AP dict known + } { + pop + } ifelse + } forall +} bind def + +% Determine spot colors are used within a page. We are creating a dict to +% hold the spot color names as keys. Using a dict avoids having to worry +% about duplicate entries. The keys in the dict contain the spot color +% names. However the values have no meaning. Note: This dict will include +% all colors used in Separation or DeviceN color spaces specified in the +% page's resources. Thus it may include Cyan, Magenta, Yellow, and Black. +% There is no attempt to verify that these color spaces are actually used +% within the object streams for the page. +/pagespotcolors { % <pagedict> pagespotcolors <spotcolordict> + dup + % Create a dict to hold spot color names. + 0 dict exch + % Create a dict to be used to check for reference loops. + 4 dict exch + % Check for color spaces in the Resources + resourcespotcolors + % now check upwards in the object hierarchy in case of inherited resources + 2 index + { + /Parent knownoget + { + dup 4 1 roll + resourcespotcolors + 3 -1 roll + } + { + exit + } ifelse + } loop + % Also check for color spaces in the annotations. + 3 -1 roll + /Annots knownoget { annotsspotcolors } if + pop % Discard reference loop dict +} bind def + +% Determine how many (if any) spot colors are used by a page. +% Note: This count does not include Cyan, Magenta, Yellow, or Black +/countspotcolors { % <pagedict> countspotcolors <count> + pagespotcolors % Get dict with all spot colors + dup length % spot color dict length + % Remove CMYK from the spot color count. + [ /Cyan /Magenta /Yellow /Black ] + { 2 index exch known { 1 sub } if } forall + exch pop % Remove spot color dict +} bind def + +% ------ ColorSpace substitution support ------ % + +%% +%% <pagedict> pdf_colorspace_detect_cspacesub <boolean> +%% +/pdf_colorspace_detect_cspacesub { + //false exch + /Resources knownoget { + /ColorSpace knownoget { + dup /DefaultGray knownoget { + resolvecolorspace csncomp 1 eq { + pop pop //true + } if + } { + dup /DefaultRGB knownoget { + resolvecolorspace csncomp 3 eq { + pop pop //true + } if + } { + /DefaultCMYK knownoget { + resolvecolorspace csncomp 4 eq { + pop //true + } if + } if + } ifelse + } ifelse + } if + } if +} bind def + +%%<Objectdict> <calling obj_num> pdfform_detect_cspacesub <boolean> +%% +/pdf_object_detect_cspacesub { + exch %% <calling obj_num> <Objectdict> + dup pdf_colorspace_detect_cspacesub { + pop //true + }{ %% <calling obj_num> <Objectdict> + /Resources knownoget { %% <calling obj_num> <Resourcesdict> + /XObject knownoget { %% <calling obj_num> <XObjectdict> + //false exch %% <calling obj_num> <XObjectdict> false + %% We have files where the XObject Resource is not a dictionary + dup type /dicttype eq { %% <calling obj_num> <XObjectdict> false + + %% check each Xobject entry in the dictionary, + %% forall purs a key/value pair on the stack for us. + %% + { %% <calling obj_num> <XObjectdict> false key value + exch pop %% <calling obj_num> <XObjectdict> false value + + %% If this is an indirect reference, check if its the smae object + %% as the current one. If its not indirect, make the object number 0 + %% for comparison purposes. + dup type /packedarraytype eq { + dup 0 get dup 4 index + eq + } { + 0 false + }ifelse + + %% <calling obj_num> <XObjectdict> false value <form object or 0 if not indirect> <boolean> + not { + %% swap object number and value, and dereference value + exch oforce + %% Apparently we have files where the content of the XObject Resource dictionary is null + dup //null ne { + %% and files where the indivudal XObjects are not dictionaries + dup type /dicttype eq { + dup /Subtype get /Form eq { + exch + pdf_object_detect_cspacesub { + pop //true exit + } if + } { + pop pop + }ifelse + }{ + pop pop + } ifelse + }{ + pop pop + } + ifelse + }{ + pop pop + } ifelse + } forall + }{ + pop + }ifelse + } { + %% No forms, so can't be any Default* spaces + //false + }ifelse + } { + //false + } ifelse + } ifelse + %% Remove the calling object ID, return our boolean + exch pop +} bind def + +% +% <pagedict> pdfshowpage_detect_cspacesub <pagedict> <boolean> +% +% this is used simply to detect whether the current page has any +% Default* color spaces defined. If it does then we want pdfshowpage_setpage +% to set UseCIEColor to true so that the Default* space is used. If the +% page doesn't use any Default* spaces, then we *don't* want to set +% UseCIEColor as that will confuse a warning in pdfwrite about +% not using UseCIEColor with pdfwrite. +% +/pdfshowpage_detect_cspacesub { + dup 0 pdf_object_detect_cspacesub + + /HighLevelDevice /GetDeviceParam .special_op { + exch pop not exch pop + }if + +} bind def + +% +% <pagedict> pdfshowpage_setcspacesub <pagedict> +% +% Set up color space substitution for a page. Invocations of this procedure +% must be bracketed by the save/restore operation for the page, to avoid +% unintended effects on other pages. +% +% If any color space substitution is used, and the current color space is a +% device dependent color space, make sure the current color space is updated. +% There is an optimization in the setcolorspace operator that does +% nothing if both the current and operand color spaces are the same. For +% PostScript this optimization is disabled if the UseCIEColor page device +% parameter is true. This is not the case for PDF, as performance suffers +% significantly on some PDF files if color spaces are set repeatedly. Hence, +% if color space substitution is to be used, and the current color space +% is a device dependent color space, we must make sure to "transition" the +% current color space. +% +/pdfshowpage_setcspacesub { + //false + /DefaultGray 2 index /ColorSpace //rget exec { + resolvecolorspace dup csncomp 1 eq { + dup type /nametype eq { 1 array astore } if + /DefaultGray exch /ColorSpace defineresource pop + pop //true + } { + pop + ( **** Error: ignoring invalid /DefaultGray color space.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + } if + + /DefaultRGB 2 index /ColorSpace //rget exec { + resolvecolorspace dup csncomp 3 eq { + dup type /nametype eq { 1 array astore } if + /DefaultRGB exch /ColorSpace defineresource pop + pop //true + } { + pop + ( **** Error: ignoring invalid /DefaultRGB color space.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + } if + + /DefaultCMYK 2 index /ColorSpace //rget exec { + resolvecolorspace dup csncomp 4 eq { + dup type /nametype eq { 1 array astore } if + /DefaultCMYK exch /ColorSpace defineresource pop + pop //true + } { + pop + ( **** Error: ignoring invalid /DefaultCMYK color space.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + } if + + { % if using color space substitution, "transition" the current color space + currentcolorspace dup length 1 eq { % always an array + 0 get + dup /DeviceGray eq 1 index /DeviceRGB eq or 1 index /DeviceCMYK eq or { + /Pattern setcolorspace setcolorspace + } { + pop + } ifelse + } { + pop + } ifelse + } if +} bind def + +% Write OutputIntents to device if the device handles it +/writeoutputintents { + currentdevice 1 dict dup /OutputIntent //null put readonly + .getdeviceparams + mark ne { pop pop + % device supports OutputIntent parameter + % Make sure we don't have a badly broken PDF file! + Trailer /Root knownoget { + /OutputIntents knownoget { + dup type /arraytype eq { + { % process all output profiles present + oforce + dup length dict .copydict + dup /DestOutputProfile knownoget { + PDFfile fileposition exch + mark exch { oforce } forall .dicttomark + //true resolvestream + [ { counttomark 1 add index + 64000 string readstring + not { exit } if + } loop + ] exch closefile + 0 1 index { length add } forall .bytestring + 0 3 2 roll { + 3 copy putinterval + length add + } forall pop + exch PDFfile exch setfileposition + 1 index /DestOutputProfile 3 2 roll put + } if + % Convert to string array because it's easier for the device + [ 1 index /OutputCondition knownoget not { () } if + 2 index /OutputConditionIdentifier knownoget not { () } if + 3 index /RegistryName knownoget not { () } if + 4 index /Info knownoget not { () } if + 5 index /DestOutputProfile knownoget not { () } if + ] + [ /OutputIntent 3 2 roll /.pdfputparams where + { pop .pdfputparams } + { currentdevice //null //false counttomark 1 add 3 roll .putdeviceparamsonly } + ifelse + pop pop + pop % done with this OutputIntent dictionary + } forall + } { + pop + ( **** Error: /OutputIntent is of an incorrect type, ignoring OutputIntent.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + } if % OutputIntents known + % tell device there are no more OutputIntents + [ /OutputIntent [ ] /.pdfputparams where + { pop .pdfputparams } + { currentdevice //null //false counttomark 1 add 3 roll .putdeviceparamsonly } + ifelse + pop pop + } if + } if +} bind def + +end % pdfdict +.setglobal diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps new file mode 100644 index 00000000000..ba53b54cd7e --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps @@ -0,0 +1,1815 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% Definitions for most of the PDF operators. + +.currentglobal //true .setglobal + +% Define pdfmark. Don't allow it to be bound in. +% Also don't define it in systemdict, because this leads some Adobe code +% to think this interpreter is a distiller. +% (If this interpreter really is a distiller, don't do this.) +systemdict /pdfmark known not + { userdict /pdfmark { cleartomark } bind put } if + +userdict /GS_PDF_ProcSet 256 dict dup begin + +% ---------------- Abbreviations ---------------- % + +/bdef { bind def } bind def + +% ---------------- Graphics state stack ---------------- % + +% PDF adds a number of parameters to the graphics state. +% We implement this by pushing and popping a dictionary +% each time we do a PDF gsave or grestore. +% The keys in this dictionary are as follows: +% self % identifies the dictionary as one of ours +% ClipRect % (optional) +% Show +% TextSaveMatrix % matrix at time of BT (iff within BT/ET) +% (The following correspond directly to PDF state parameters.) +% AlphaIsShape +% FillConstantAlpha +% FillColor +% FillColorSpace +% FillOverprint +% SoftMask +% StrokeConstantAlpha +% StrokeColor +% StrokeColorSpace +% StrokeOverprint +% TextSpacing +% TextHScaling +% Leading +% TextFont +% TextLineMatrix +% TextMatrix +% TextRise +% TextRenderingMode +% WordSpacing +% (The following is cached information derived from other graphics state params) +% FontMatrixNonHV % TextFont.FontMatrix alters horz/vert glyph advance vector direction + +/nodict 1 dict def +nodict /self { //nodict } executeonly put % to avoid recursion in dumps +nodict readonly pop + +/dictbeginpage { % <initialdict> dictbeginpage - + 20 dict copy dup begin + 1 packedarray cvx executeonly /self exch def + graphicsbeginpage textbeginpage +} bdef +/endpage { % - endpage - + showpage end +} bdef + +/graphicsbeginpage { + initgraphics + //true .setaccuratecurves + currentdict /ClipRect knownoget { aload pop rectclip } if + 0 g 0 G //false op //false OP 0 OPM + 1 ca 1 CA //null SMask //false AIS /Compatible BM //true TK +} bdef + +% We must allow /Show to be set, otherwise a text operation can +% end up in infinite recursion with showfirst calling Show, and +% Show calling showfirst. +/gput_always_allow +1 dict dup begin + /Show 0 def +end def + +/gput % <value> <key> gput - + { + dup //gput_always_allow exch known not currentdict /n known and { + pop pop + ( **** Error: Ignoring changes to the graphic state after operator 'W'.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } { + exch currentdict //nodict eq { /self dup load end 5 dict begin def } if + def + } ifelse + } bdef +currentdict /gput_always_allow .undef + +/q { + %% Special case, if we get a 'q' while accumulating clip/eoclip then + %% we need to make sure we close the current dictionary, and reopen it after + %% performing the gsave, so that the redefinition of 'n' in particular is correct + currentdict /n known { + currentdict %% copy the dicitonary for the accumulation + end %% and close it (NB *before* the gsave!) + gsave //nodict begin %% execute gsave and start 'nodict' just like normal + begin %% reopen the accumulation dictionary. + %% when we execute 'n' this will close and we'll go back + %% to the regular 'nodict' opened above. This could cause some + %% odd interactions with 'Q' for unbalanced files..... + } { + %% ugly hackery to work around badly broken PDF file in Bug #695897. The file has nested BT/ET + %% sections, and delimits them with q/Q. The problem is that our code to deal with nested + %% text sections looks in the current dictionary for TextSaveMatrix, and a 'q' makes a brand + %% new empty dictionary, so it defeats it. + %% I tried copying the TextSaveMatrix from the parent state into this one, but that then causes + %% other problems because we end up apllying the TextSaveMatrix when we shouold not. Attempting + %% to clear the TextSaveMatrix from all saved states on ET then caused it not to be defined at + %% times when we needed it..... + %% This is all terribly flaky, but defining a new matrix inside gsaves that tells us that we had + %% were already in a text block allows us to detect and cope with the nested BT's and leaving the + %% original TextSaveMatrix behind allows the matching ET not to throw an error, as well as coping + %% with the various other problems listed above. Its not pretty though. + currentdict /TextSaveMatrix known { + currentdict /TextSaveMatrix get matrix copy + gsave //nodict begin + /qTextSaveMatrix gput + }{ + gsave //nodict begin + }ifelse + } ifelse + PDFusingtransparency { .pushextendedgstate } if +} bdef + +% Some PDF files have excess Q operators! +/Q { + //false + { currentdict /n known { end pop //true } { exit } ifelse + } loop { + ( **** Error: Encountered a 'Q' before finishing 'W' mode.\n) + pdfformaterror + ( Output may be incorrect..\n) pdfformaterror + } if + currentdict /self .knownget { + exec //nodict eq { + end + PDFusingtransparency { .popextendedgstate } if + % Restore graphics state, but do not modify path. Paths are not part + % of the PDF graphics state; see 4.4.1 of PDF reference 3rd ed. + % Collecting the path with one ctm and re-playing it with another ctm + % transforms the path exactly as PDF needs. + {.getpath} stopped { + ( **** Error: unable to preserve current path, probable degenerate CTM, output may be incorrect.\n) pdfformaterror + grestore newpath + }{ + grestore newpath { exec } forall + } ifelse + //false + } { + //true + } ifelse + } { + //true % formaterror -- not a gsave dict + } ifelse + { + (\n **** Error: File has unbalanced q/Q operators \(too many Q's\)\n Output may be incorrect.\n) + + pdfdict /.Qqwarning_issued .knownget + { + { + pop + } + { + currentglobal pdfdict gcheck .setglobal + pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } ifelse + } + { + currentglobal pdfdict gcheck .setglobal + pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } ifelse + } if +} bdef + +% Save PDF gstate +/qstate { % - qstate <qstate> + gstate +} bdef + +% Set PDF gstate +/setqstate { % <qstate> setqstate - + { matrix setmatrix //false upath } stopped { + pop setgstate newpath + } { + % Save the CTM, set identity during the uappend, then set the CTM + exch setgstate matrix currentmatrix matrix setmatrix + exch newpath uappend setmatrix + } ifelse +} bdef + +% Save most of graphic state attributes. +% - get-gs-attrs ... +/get-gs-attrs { + currentsmoothness + currentflat + currentoverprint + currentstrokeadjust + currentdash + currentmiterlimit + currentlinejoin + currentlinecap + currentlinewidth + currentfont + currentcolor + currentcolorspace + { currentpoint } stopped + matrix currentmatrix +} bdef + +% Restore most of graphic state attributes. +% ... get-gs-attrs - +/set-gs-attrs { + setmatrix + { newpath } { moveto } ifelse + setcolorspace + setcolor + setfont + setlinewidth + setlinecap + setlinejoin + setmiterlimit + setdash + setstrokeadjust + setoverprint + setflat + setsmoothness +} bdef + +% ---------------- Color setting ---------------- % + +/fcput % <color> <colorspace> fcput - + { /FillColorSpace gput /FillColor gput + } bdef +/scput % <color> <colorspace> scput - + { /StrokeColorSpace gput /StrokeColor gput + } bdef +/csput % <colorspace> csput - + { csset 2 copy fcput scput + } bdef + +/csdevgray [/DeviceGray] readonly def +/csdevrgb [/DeviceRGB] readonly def +/csdevcmyk [/DeviceCMYK] readonly def +/cspattern [/Pattern] readonly def +/nullpatternproc { pop } bdef +/nullpattern mark + /PatternType 1 /PaintType 1 /TilingType 3 /BBox [0 0 1 1] + /XStep 1 /YStep 1 /PaintProc //nullpatternproc +.dicttomark readonly def + +% Each entry in the color space dictionary is a procedure of the form +% <cspace> -proc- <cspace> <initial-color> +/CSdict mark + /DeviceGray { pop //csdevgray 0 } bind + /DeviceRGB { pop //csdevrgb [0 0 0] cvx } bind + /DeviceCMYK { pop //csdevcmyk [0 0 0 1] cvx } bind + /CIEBasedA { 0 } bind + /CIEBasedABC { [0 0 0] cvx } bind + /CalGray { pop //csdevgray 0 } bind + /CalRGB { pop //csdevrgb [0 0 0] cvx } bind + /Lab {[0 0 0] cvx } bind + /ICCBased { [ 1 index 1 oget /N get { 0 } repeat ] cvx } bind + /Separation { 1 } bind + /DeviceN { % What is the correct value?? + [ 1 index 1 get length { 1 } repeat ] cvx + } bind + /Indexed { 0 } bind + /Pattern { + dup type /nametype eq 1 index length 1 eq or { + pop //cspattern //nullpattern matrix makepattern + } { + //nullpattern matrix makepattern 1 index 1 get csset + % Stack: patternspace nullpattern basecolor basespace + pop [ 3 1 roll dup type /arraytype eq { aload pop } if + counttomark -1 roll ] cvx + } ifelse + } bind +.dicttomark readonly def +/csset % <cspace> csset <color> <cspace> + { dup dup type /nametype ne { 0 get } if //CSdict exch get exec exch + } bdef + +/g { //csdevgray fcput } bdef +/G { //csdevgray scput } bdef +/rg { 3 array astore cvx //csdevrgb fcput } bdef +/RG { 3 array astore cvx //csdevrgb scput } bdef +/k { 4 array astore cvx //csdevcmyk fcput } bdef +/K { 4 array astore cvx //csdevcmyk scput } bdef +%% +%% Bug #694412, we set the colour space immediately now. Previously we +%% only set the colour space and colour when a stroke or fill took place. +%% if that happened inside a gsave/grestore we could end up setting the +%% same colour space many times, which is a problem if its an expensive +%% space, like ICCBased. +%% +/cs { csset dup setgcolorspace fcput } bdef +/CS { csset dup .swapcolors setgcolorspace .swapcolors scput } bdef +/ri { //.renderingintentdict exch .knownget { .setrenderingintent } if } bdef +% We have to break up sc according to the number of operands. +%% +%% Also Bug #694412, we need to set the actual colour in response to the +%% PDF operators as well. However, the transparenmcy code also uses the +%% original calls (sc, SC, sc1, SC1, sc* and SC*) and so we create +%% a duplicate set which do the same as the originals, but se the current +%% colour as well. +%% +/sc1_and_set { /FillColor gput FillColor FillColorSpace setgcolor} bdef +/sc1 { /FillColor gput } bdef +/SC1_and_set {/StrokeColor gput .swapcolors StrokeColor StrokeColorSpace setgcolor .swapcolors } bdef +/SC1 { /StrokeColor gput } bdef +% We have to avoid storing into a color array associated with an outer +% gsave level, so we do a kind of "copy on write". +/sc* { + currentdict /FillColor .knownget { + astore pop + } { + /FillColor load + % FillColor may contain either a single value or an array. + dup type /arraytype eq { length }{ pop 1 } ifelse + array astore cvx /FillColor gput + } ifelse +} bdef +/SC* { + currentdict /StrokeColor .knownget { + astore pop + } { + /StrokeColor load + % StrokeColor may contain either a single value or an array. + dup type /arraytype eq { length }{ pop 1 } ifelse + array astore cvx /StrokeColor gput + } ifelse +} bdef +/sc*_and_set { + sc* + FillColor FillColorSpace setgcolor +} bdef +/SC*_and_set { + SC* + .swapcolors StrokeColor StrokeColorSpace setgcolor .swapcolors +} bdef + +% ---------------- Overprint/transparency setting ---------------- % + +/op { /FillOverprint gput } bdef % NB pdf_draw:gsparamdict handled /OP with no /op +/OP { /StrokeOverprint gput } bdef +/OPM { + /.setoverprintmode where { pop dup .setoverprintmode .swapcolors .setoverprintmode .swapcolors } { pop } ifelse +} bdef +/ca { /FillConstantAlpha gput } bdef +/CA { /StrokeConstantAlpha gput } bdef +/SMask { /SoftMask gput } bdef +/AIS { /AlphaIsShape gput } bdef +/BM { + /.setblendmode where { + pop [ exch dup type /nametype ne { aload pop } if /Normal ] { + { .setblendmode } .internalstopped not { exit } if pop + } forall + } { + pop + } ifelse +} bdef +/TK { + /.settextknockout where { pop .settextknockout } { pop } ifelse +} bdef + +% ---------------- Color installation ---------------- % + +% Establish a given color (and color space) as current. +/.settransparencyparams { % <alpha> <smask> .settransparencyparams - + PDFusingtransparency { + /.begintransparencygroup where { + pop AlphaIsShape { + 1 .setopacityalpha exch .setshapealpha 1 + } { + 1 .setshapealpha exch .setopacityalpha 0 + } ifelse + % Set the soft mask by rendering the XObject. Doing this every time + % is obviously very inefficient; we'll improve it later. + .settransparencymask + } { + pop pop + } ifelse + } { + pop pop + } ifelse +} bdef +/.settransparencymask { % <paramdict> <masknum> .settransparencymask - + exch dup type /dicttype ne { + PDFusingtransparency { + pop pop + } { + dup /Draw get exec + } ifelse + } { + dup /Draw get exec + } ifelse +} bdef +% (Non-mask) images must execute setfillblend. +/setfillblend { + FillOverprint setoverprint + FillConstantAlpha SoftMask .settransparencyparams +} def +/setfillstate { + FillColor FillColorSpace setgcolor setfillblend +} def + +/setstrokestate { + .swapcolors + StrokeColor StrokeColorSpace setgcolor StrokeOverprint setoverprint + StrokeConstantAlpha SoftMask .settransparencyparams + .swapcolors +} def +/Cdict 15 dict dup begin % <color...> <colorspace> -proc- - + /DeviceGray { pop setgray } bdef + /DeviceRGB { pop setrgbcolor } bdef + /DeviceCMYK { pop setcmykcolor } bdef + /CIEBasedA { setgcolorspace setcolor } bdef + /CIEBasedABC /CIEBasedA load def + /CIEBasedDEF /CIEBasedA load def + /CIEBasedDEFG /CIEBasedA load def + /CalRGB /CIEBasedA load def + /CalGray /CIEBasedA load def + /Lab /CIEBasedA load def + %% This section is to deal with the horrible pair of files in Bug #696690 and Bug #696120 + %% These files have ICCBased spaces where the value of /N and the number of components + %% in the profile differ. In addition the profile in Bug #696690 is invalid. In the + %% case of Bug #696690 the /N value is correct, and the profile is wrong, in the case + %% of Bug #696120 the /N value is incorrect and the profile is correct. + %% We 'suspect' that Acrobat uses the fact that Bug #696120 is a pure image to detect + %% that the /N is incorrect, we can't be sure whether it uses the profile or just uses + %% the /N to decide on a device space. What we now do is; If the /N and device profile + %% number of components don't match, we assume the device profile is correct and patch + %% /N to be the same as the profile (see /ICCBased-resolve), but we save the original + %% value of /N in /OrigN. In setcolor, if the space is a genuine ICCBased space + %% (not a replacement for a device profile) we call set_dev_color which will actually + %% exercise the profile. If that fails we return an error. Here we run setcolor in a + %% stopped context, and if it fails we check to see if there is a /OrigN (ths occurs + %% only if the /N was different to the number of components in the profile). If there + %% is a /OrigN then prefer that to the profile, otherwise they agreed, so just use + %% /N and select a device space. If we can't select a device space with the correct + %% number of components, give up and throw an error. See also /last-ditch-bpc-csp + %% in pdf_draw.ps. + /ICCBased { + dup 1 get + dup /OrigN .knownget {exch /N get}{/N get dup} ifelse + 3 add mark exch 2 roll + setgcolorspace {setcolor} stopped + { + cleartomark + [//null /DeviceGray //null /DeviceRGB /DeviceCMYK] exch + {get} stopped + { + ( **** Error: Unable to set an ICCBased colour space, and cannot set an alternate from the number of components.\n) print + /setcolorspace cvx /undefined signalerror + } + { + dup //null eq { + ( **** Error: Unable to set an ICCBased colour space, and cannot set an alternate from the number of components.\n) print + /setcolorspace cvx /undefined signalerror + }{ + ICCProfileNError flush not { + ( **** Warning : Error setting an ICCBased colour space, using /N to set an alternate device space.\n) print + ( Output may be incorrect.\n) print + } if + setcolorspace + /ICCProfileNError true def + } ifelse + }ifelse + }{ + cleartomark pop + } + ifelse + } bdef + /Separation /CIEBasedA load def + /DeviceN /CIEBasedA load def + /Indexed /CIEBasedA load def + /Pattern + { setgcolorspace + + % Since multiple patterns may share + % same data stream, we need to ensure + % that the stream is at 0 position. + % Making this consistently with resolveshading, + % which applies ReusableStreamDecode filter + % to the PS stream, which represents the + % PDF stream in dynamics. + + dup /Shading knownoget { + dup /ShadingType oget 4 ge { + /DataSource knownoget { + dup type /filetype eq { + 0 setfileposition + } { + pop + } ifelse + } if + } { + pop + } ifelse + } if + + % Associate pattern instance with the default qstate for the context. + % A single pattren object can be reused in several contexts. + dup DefaultQstate .knownget { + exch pop + } { + % But don't update read-only initial null pattern. + dup /PaintProc .knownget { //nullpatternproc ne } { //true } ifelse { + dup dup /Matrix knownoget not { { 1 0 0 1 0 0 } } if + gsave DefaultQstate setqstate makepattern grestore + dup 3 1 roll + DefaultQstate exch put + } if + } ifelse + setcolor + } bdef +end def +/setgcolor % (null | <color...>) <colorspace> setgcolor - + { 1 index //null eq + { pop pop } + { dup 0 get //Cdict exch get exec } + ifelse + } bdef +% Compare the old and new color spaces in an attempt to avoid expensive +% reloads of CIEBased color spaces. +/PCSdict 15 dict dup begin % <colorspace> -proc- <colorspace|pdfcspace> + /CIEBasedA { dup 1 get /PDFColorSpace .knownget { exch pop } if } bdef + /CIEBasedABC /CIEBasedA load def + /CIEBasedDEF /CIEBasedA load def + /CIEBasedDEFG /CIEBasedA load def + /Indexed { + dup 1 get dup pdfcolorspace 2 copy ne { 3 1 roll } if pop pop + } bdef +end def +/pdfcolorspace { % <colorspace> pdfcolorspace <colorspace|pdfcspace> + dup type /arraytype eq { + //PCSdict 1 index 0 get .knownget { exec } if + } if +} bdef +/setgcolorspace { % <colorspace> setgcolorspace - + dup pdfcolorspace currentcolorspace pdfcolorspace eq { + pop + } { + setcolorspace + } ifelse +} bdef + +/OPsavedict 2 dict def % for saveOP, saveBM + +% colorspaces that don't require special overprint transparency handling +/okOPcs mark /DeviceGray 0 /DeviceCMYK 1 /DeviceN 2 /Separation 3 .dicttomark def + +/checkOPtrans % <fillop|strokeop> checkOPtrans <bool> +% return true if OP needs special transparency treatment +% If the colorspace is not one where overprint makes sense, no special handling (return false) +% NB: This will get replaced with a quick "no-op" if the device doesn't support Overprint +{ % Check OP and BM in case we need to push a group + okOPcs currentcolorspace 0 get dup /Indexed eq { + pop currentcolorspace 1 get % use the base space + } if + known { + /stroke ne { FillOverprint } { StrokeOverprint } ifelse + .currentblendmode dup /Normal eq exch /Compatible eq or not and + } { + pop //false + } ifelse +} bdef + +/fsexec % <fillop|strokeop> fsexec - +{ + PDFusingtransparency { + SoftMask //null ne { + mark /Subtype /Group /Isolated //true .dicttomark pathbbox .begintransparencygroup + } if + dup checkOPtrans exch 1 index { + % We need to push a non-isolated, non-knockout transparency group and + % perform the operation in CompatibleOverprint mode, then end the + % transparency group. Do the begintransparencygroup step here. + mark /Subtype /Group /Isolated //false .dicttomark pathbbox .begintransparencygroup + exch .currentblendmode exch .currentopacityalpha exch 4 -1 roll % save current values + /CompatibleOverprint .setblendmode 1 .setopacityalpha + } if + cvx exec + { + .endtransparencygroup .setopacityalpha .setblendmode % end the CompatibleOverprint group + } if + SoftMask //null ne { + .endtransparencygroup + } if + } { + cvx exec + } ifelse +} bdef + +% ---------------- Path painting and clipping ---------------- % + +%% Bug #696017 In order to get the correct position of paths and other objects which +%% are illegally present inside a text block, we need to use the saved TextSaveMatrix +%% to construct/place them. But we don't want to do lots of lookups on every segment of +%% a path (we feel its OK to do lookups for images). So what we do is redefine the +%% path contruction operators at the beginning of a text block, and put them back afterwards. +%% Here we define the 'normal' and 'inside text' versions of those operators, and routines +%% to switch the definitions back and forth. + +/check_and_set_saved_matrix { + currentdict /TextSaveMatrix known { + currentdict /TextSaveMatrix get setmatrix + } + { + currentdict /qTextSaveMatrix known { + currentdict /qTextSaveMatrix get setmatrix + } if + } ifelse +} bind def + +/normal_m { { moveto } stopped { count pdfemptycount sub 2 .min { pop } repeat 0 0 moveto } if } bdef +/inside_text_m { + { + matrix currentmatrix 3 1 roll + check_and_set_saved_matrix + moveto + setmatrix + } + stopped { count pdfemptycount sub 2 .min { pop } repeat 0 0 moveto } if +} bdef + +/normal_l { { lineto } stopped { count pdfemptycount sub 2 .min { pop } repeat } if } bdef +/inside_text_l { + { + matrix currentmatrix 3 1 roll + check_and_set_saved_matrix + lineto + setmatrix + } + stopped { count pdfemptycount sub 2 .min { pop } repeat } if +} bdef + +/normal_c { { curveto } stopped { count pdfemptycount sub 6 .min { pop } repeat } if } bdef +/inside_text_c { + { + matrix currentmatrix 7 1 roll + check_and_set_saved_matrix + curveto + setmatrix + } + stopped { count pdfemptycount sub 6 .min { pop } repeat } if +} bdef + +/normal_v { count pdfemptycount sub 4 ge { + { currentpoint 6 2 roll curveto } stopped { count pdfemptycount sub 6 .min { pop } repeat } if + } { + count pdfemptycount sub { pop } repeat + } ifelse + } bdef +/inside_text_v { count pdfemptycount sub 4 ge { + { + matrix currentmatrix 5 1 roll + check_and_set_saved_matrix + currentpoint 6 2 roll curveto + setmatrix + } stopped { count pdfemptycount sub 6 .min { pop } repeat } if + } { + count pdfemptycount sub { pop } repeat + } ifelse + } bdef + +/normal_y { { 2 copy curveto } stopped { count pdfemptycount sub 6 .min { pop } repeat } if } bdef +/inside_text_y { + { + matrix currentmatrix 5 1 roll + check_and_set_saved_matrix + 2 copy curveto + setmatrix + } + stopped { count pdfemptycount sub 6 .min { pop } repeat } if +} bdef + +/normal_re { + 4 2 roll moveto exch dup 0 rlineto 0 3 -1 roll rlineto neg 0 rlineto + closepath + } bdef +/inside_text_re { + matrix currentmatrix 5 1 roll + check_and_set_saved_matrix + 4 2 roll moveto exch dup 0 rlineto 0 3 -1 roll rlineto neg 0 rlineto + closepath + setmatrix + } bdef + +/S { + OFFlevels length 0 eq { + setstrokestate .swapcolors /stroke fsexec .swapcolors + } { + newpath + } ifelse +} bdef + +/f { + OFFlevels length 0 eq { + setfillstate /fill fsexec + } { + newpath + } ifelse +} bdef + +/f* { + OFFlevels length 0 eq { + setfillstate /eofill fsexec + } { + newpath + } ifelse +} bdef + +/n { newpath } bdef % don't allow n to get bound in + +/s { closepath S } bdef + +/B { + OFFlevels length 0 eq { + PDFusingtransparency { + % knockout trans group around the filled and stroked object + mark + /Isolated //true /Knockout //true + .dicttomark + % strokepath will return empty path (no currentpoint) if nothing is stroked + gsave { strokepath pathbbox } stopped grestore not { + 1 .setopacityalpha + .begintransparencygroup + gsave setfillstate fill grestore + setstrokestate .swapcolors /stroke fsexec .swapcolors + .endtransparencygroup + } { newpath pop } ifelse + } { + gsave setfillstate fill grestore + setstrokestate .swapcolors /stroke fsexec .swapcolors + } ifelse + } { + newpath + } ifelse +} bdef + +/b { closepath B } bdef + +/B* { + OFFlevels length 0 eq { + PDFusingtransparency { + % knockout trans group around the filled and stroked object + mark + /Isolated //true /Knockout //true + .dicttomark + % strokepath will return empty path (no currentpoint) if nothing is stroked + gsave { strokepath pathbbox } stopped grestore not { + 1 .setopacityalpha + .begintransparencygroup + gsave setfillstate eofill grestore + setstrokestate .swapcolors /stroke fsexec .swapcolors + .endtransparencygroup + } { newpath pop } ifelse + } { + gsave setfillstate eofill grestore + setstrokestate .swapcolors /stroke fsexec .swapcolors + } ifelse + } { + newpath + } ifelse +} bdef + +/b* { closepath B* } bdef + +% Clipping: + +/Wdict 4 dict dup begin +/S { OFFlevels length 0 eq { gsave setstrokestate .swapcolors stroke .swapcolors grestore } if n } bdef +/f { OFFlevels length 0 eq { gsave setfillstate fill grestore } if n } bdef +/f* { OFFlevels length 0 eq { gsave setfillstate eofill grestore } if n } bdef +/n { end { currentpoint } stopped not { pop pop clip } if newpath } bdef +end readonly def +/W { //Wdict begin } bdef +/W*dict 4 dict dup begin +Wdict { def } forall +/n { end { currentpoint } stopped not { pop pop eoclip } if newpath } bdef +end readonly def +/W* { //W*dict begin } bdef + +% ---------------- Text control ---------------- % + +/textbeginpage + { /TextSpacing 0 def % 0 Tc + /TextLeading 0 def % 0 TL + /TextRenderingMode 0 def % 0 Tr + /TextRise 0 def % 0 Ts + /WordSpacing 0 def % 0 Tw + /TextHScaling 1.0 def % 100 Tz + /TextFont //null def + /FontMatrixNonHV //false def + /Show { showfirst } def + /TextFillStateNeeded //true def + } bdef + +/TestDegenerateCTM { + matrix currentmatrix + dup 0 get + exch dup 3 get + exch dup 1 get + exch 2 get + mul + 3 1 roll mul + exch sub + 0 eq { + true + }{ + false + } ifelse +} bdef + +% Contrary to the statement in the PDF manual, BT and ET *can* be nested, +% if the CharProc for a Type 3 font does a BT/ET itself. +% Since we always call the CharProc inside a q/Q, we simply ensure that +% the text state is saved and restored like the rest of the extended +% graphics state. + +/settextmatrix { + matrix currentmatrix + TextMatrix concat + TestDegenerateCTM { + (\n **** Error: Degenerate text matrix detected, ignoring Tm operation\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + setmatrix + } { + pop + } ifelse + TextHScaling 1 ne { TextHScaling 1 scale } if + TextRise 0 ne { 0 TextRise translate } if + TextFont dup //null eq { pop } { setfont } ifelse +} bdef + +/settextstate { + % The text state can be set even outside BT/ET. + currentdict /TextSaveMatrix known { + TextSaveMatrix + aload pop + 5 index 0 ne 3 index 0 ne and + 5 index 0 ne 5 index 0 ne and or not { + (\n **** Error: Invalid (0 scaling) text matrix for Tm ****\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + % handle invalid scale by using a really small value + 2 -6 roll pop pop pop pop + 0.00000001 0 0 0.00000001 + 6 -2 roll + }if + 6 array astore + setmatrix settextmatrix + } if +} bdef +/settextposition { + % Update the TextMatrix translation. + gsave TextSaveMatrix setmatrix + {currentpoint} stopped not { TextRise sub TextMatrix 4 2 getinterval astore pop + % We would like to do "grestore currentpoint translate" + % here, but some PDF files set a singular text matrix + % (0 0 0 0 <x> <y> Tm), so we can't do this. + TextTempMatrix identmatrix setmatrix currentpoint + grestore + TextTempMatrix currentmatrix 4 2 getinterval astore pop + TextTempMatrix setmatrix + } { + ( **** Error: Invalid currentpoint, probable degenerate CTM.\n) pdfformaterror + ( Ignroing error, output may be incorrect.\n) pdfformaterror + grestore + } ifelse +} bdef + +/switch_to_text_marking_ops { + pdfopdict /m {inside_text_m} bind .forceput + pdfopdict /l {inside_text_l} bind .forceput + pdfopdict /c {inside_text_c} bind .forceput + pdfopdict /v {inside_text_v} bind .forceput + pdfopdict /y {inside_text_y} bind .forceput + pdfopdict /re {inside_text_re} bind .forceput +} bdef + +/switch_to_normal_marking_ops { + pdfopdict /m {normal_m} bind .forceput + pdfopdict /l {normal_l} bind .forceput + pdfopdict /c {normal_c} bind .forceput + pdfopdict /v {normal_v} bind .forceput + pdfopdict /y {normal_y} bind .forceput + pdfopdict /re {normal_re} bind .forceput +} bdef + +/BT { + currentdict /TextSaveMatrix known { + ( **** Error: illegal nested BT operator detected.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + ET_NO_TXT_KO %% Does not push any compositor actions + } if + + %% Bug #695897 see the explanation in /q defined above. + currentdict /qTextSaveMatrix known { + currentdict /qTextSaveMatrix get /TextSaveMatrix gput + ( **** Error: Illegal nested BT operator (inside a gsave) detected.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + ET_NO_TXT_KO %% Does not push any compositor actions + } if + currentdict /n known { + currentdict end + /.W exch def + } if + currentdict /TextLineMatrix .knownget + { identmatrix pop TextMatrix identmatrix pop } + { matrix /TextLineMatrix gput matrix /TextMatrix gput } + ifelse + { showfirst } /Show gput + currentdict /TextSaveMatrix .knownget not { + matrix dup /TextSaveMatrix gput + } if currentmatrix pop settextmatrix + matrix /TextTempMatrix gput % see settextposition + + %% Set the special version of the path constructoin operators, so that + %% they will work as expected if they are illgeally present in a text block. + switch_to_text_marking_ops + + %% If needed, let the pdf14 device know we are in a BT condition. This + %% distinguishes BT from an Annotation /FreeText show command which also + %% can come into pdf_text_begin with an opacity not equal to 1. + PDFusingtransparency .currenttextknockout and { + .begintransparencytextgroup + } if + +} bdef + +/ET_NO_TXT_KO { + currentdict /TextSaveMatrix known { + TextRenderingMode 4 ge { .currentfilladjust 0 .setfilladjust clip .setfilladjust} if + newpath TextSaveMatrix setmatrix + currentdict /TextSaveMatrix undef + + % if we were in a W/W* context, grab the dict, undefine temp entry for it, + % and push it back on the dict stack + currentdict /.W known { + .W + currentdict /.W undef + begin + } if + } { + ( **** Error: Ignoring spurious ET operator.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + %% Only switch back to the regular marking operations if we were not + %% in a nested text block (inside a gsave). + currentdict /qTextSaveMatrix known not { + switch_to_normal_marking_ops + } if +} bdef + +/ET { + //ET_NO_TXT_KO exec + % Group push occurred in pdf14_text_begin. + PDFusingtransparency .currenttextknockout and { + .endtransparencytextgroup + } if +} bdef + +/Tc { /TextSpacing gput { showfirst } /Show gput } bdef +/TL { /TextLeading gput } bdef +/Tr { dup .settextrenderingmode /TextRenderingMode gput { showfirst } /Show gput } bdef +/Ts { /TextRise gput settextstate } bdef +/Tw { /WordSpacing gput { showfirst } /Show gput } bdef +/Tz { + dup 0 eq { + (\n **** Error: Invalid 0.0 horizontal text scaling given for Tz\n) + ( Output may be incorrect.\n) pdfformaterror + pdfformaterror + pop 0.00000001 % handle invalid scale by using a really small value + }{ + 100 div + }ifelse /TextHScaling gput settextstate} bdef + +% ---------------- Font control ---------------- % + +% Test if the FontMatrix could transform a horizontal/vertical (depending +% on writing mode) advance vector in glyph space into one with a different +% direction in text space. +% - if FontMatrix = [a b c d tx ty], this condition translates to: +% b != 0 for horizontal writing mode +% c != 0 for vertical writing mode +% - when false, we automatically have wy/x == 0 in text space whenever wy/x == 0 +% in glyph space, and can avoid the slow method that is otherwise necessary +% to implement zeroing wy/x cf PDF Ref 5.3.3 "Text space details" + % Worker procedure for testing a single font matrix +/?FontMatrixNonHV { % ?horz <<fontdict>> -- ?horz ?nonhv + /FontMatrix .knownget { + 1 index { 1 } { 2 } ifelse get 0 ne + } { + //false + } ifelse +} bdef + % Worker procedure for recursive checking of font matrices +/?FontMatrixNonHV { % {self} ?horz <<font>> -- {self} ?horz ?nonhv + 2 copy //?FontMatrixNonHV exec { % check the font's own FontMatrix + pop pop //true + } { + % look for descendents/ components + pop % {self} ?horz <<font>> + dup /FontType get + dup 0 eq { % Type 0: look into FDepVector + pop /FDepVector get 2 index % {self} ?horz [fonts..] {testproc} + } { + 9 eq { % Type 9 (CIDFontType 0): check FDArray + /FDArray get //?FontMatrixNonHV + } { % all others: nothing more to check + pop {} {} + } ifelse + } ifelse + %stack: {self} ?horz [fonts..] {testproc} + //false 5 2 roll { % {testproc} false {self} ?horz <<subfont>> + 4 index exec { + 4 -1 roll pop //true 4 1 roll + exit + } if + } forall + %stack: {testproc} ?nonhv {self} ?horz + 4 2 roll exch pop + } ifelse +} bdef + % Main procedure +/?FontMatrixNonHV { % <<rootfont>> -- ?nonhv + //?FontMatrixNonHV exch + % determine WMode + dup /WMode .knownget { 0 eq } { //true } ifelse % {proc} <<rootfont>> ?horz + exch + % call the worker procedure + //?FontMatrixNonHV exec + exch pop exch pop +} bdef + +/Tf { % <font> <scale> Tf - + dup 0 eq { + (\n **** Error: Invalid 0.0 font scale given for Tf\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + pop 0.00000001 % handle invalid scale by using a really small value + } if + 1 index type /dicttype ne { + selectfont currentfont + } { + dup 1 eq { pop } { scalefont } ifelse + } + ifelse + dup ?FontMatrixNonHV dup FontMatrixNonHV ne { + /FontMatrixNonHV gput + { showfirst } /Show gput + } { + pop + } ifelse + /TextFont gput settextstate +} bdef + +% Copy a font, removing its FID. If changed is true, also remove +% the UniqueID and XUID, if any. If the original dictionary doesn't have +% the keys being removed, don't copy it. +/.copyfontdict % <font> <changed> .copyfontdict <dict> + { + 1 index /.OrigUniqueIDXUID .knownget + {//false} + { + 1 index /XUID .knownget + { + //true 1 index {0 gt and} forall + {//false}{pop //true} ifelse + } + { + //true + }ifelse + } ifelse + + { + 1 index /UniqueID .knownget + {[exch]}{//null} ifelse + } if + 3 1 roll + + 1 index /FID known + 1 index { 2 index /UniqueID known or 2 index /XUID known or } if + { % We add 1 to the length just in case the original + % didn't have a FID. + exch dup length 1 add dict exch + { % Stack: changed newfont key value + 1 index /FID eq + not { 3 copy put } if pop pop + } + forall exch + } + if pop + + 1 index //null eq + {exch pop} + {dup 3 -1 roll /.OrigUniqueIDXUID exch put} + ifelse + +} bdef + +% Insert a new Encoding or Metrics into a font if necessary. +% Return a possibly updated font, and a flag to indicate whether +% the font was actually copied. +/.updatefontmetrics { % <font> <Metrics|null> .updatefontmetrics + % <font'> <copied> + dup //null ne { + exch //true .copyfontdict dup /Metrics 4 -1 roll put //true + } { + pop //false + } ifelse +} bdef + +/.updatefontencoding { % <font> <Encoding|null> .updatefontencoding + % <font'> <copied> + dup //null ne { dup 2 index /Encoding get ne } { //false } ifelse { + exch //false .copyfontdict dup /Encoding 4 -1 roll put //true + } { + pop //false + } ifelse +} bdef + +% Duplicate keys in CharString dictionary according to GlyphMap: <</new_glyph /old_glyph>> +% We have to do this because PDF fonts can associate multiple widths with the same glyph +% but Metrics dictionary works by the glyph name. +/.update_charstring { % <font> <GlyphMap> .update_charstring <font'> <copied> + dup //null ne { + exch //true .copyfontdict % map font + dup dup /CharStrings get % map font font cstr + dup length % map font font cstr len + 4 index length add % map font font cstr len+map_len + dict copy dup begin % map font font cstr' + /CharStrings exch put % map font + exch { % font /new /old + currentdict exch .knownget { + def + } { + currentdict /.notdef .knownget { + def + } { + pop + % The font has no .notdef. + % Could not resolve the conflict, + % but either the font is invalid or the glyph name is never used. + } ifelse + } ifelse + } forall + end //true + } { + pop //false + } ifelse +} bdef + +/.updatefont { % <font> <Encoding|null> <Metrics|null> <GlyphMap|null> + % .updatefont <font'> <copied> + 4 2 roll % <Metrics|null> <GlyphMap> <font> <Encoding|null> + .updatefontencoding % <Metrics|null> <GlyphMap> <font> bool + 4 1 roll exch % bool <Metrics|null> <font> <GlyphMap> + .update_charstring % bool <Metrics|null> <font> bool + 3 1 roll exch % bool bool <font> <Metrics|null> + .updatefontmetrics % bool bool <font> bool + 4 2 roll or or % <font> is_copied +} bdef + +% ---------------- Text positioning ---------------- % + +/Td { + %% Bug #695950 - invalid parameter to 'Td' operator + %% Technically the parameters to Td are reals and can vary +/- 3.403x10^38 + %% However that would be kind of hard to validate, and in any event these + %% are somewhat unlikely numbers. We validate against +/- 2^32 instead. If this + %% should ever be a problem we'll have to modify this check. + %% Testing reveals that Acrobat clamps these out of range values to 0, it doesn't + %% simply ignore the error. + exch dup dup 4294967295 ge exch 4294967295 neg le or { + ( **** Error: invalid argument to Td, Treating argument as 0.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + pop 0 + } if + exch dup dup 4294967295 ge exch 4294967295 neg le or { + ( **** Error: invalid argument to Td, Treating argument as 0.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + pop 0 + } if + TextLineMatrix transform TextLineMatrix 4 2 getinterval astore pop + TextLineMatrix TextMatrix copy pop settextstate +} bdef +/TD { dup neg /TextLeading gput Td } bdef +/T* { 0 TextLeading neg Td } bdef +/Tm { + 5 index 0 ne 3 index 0 ne and + 5 index 0 ne 5 index 0 ne and or not { + ( **** Error: Invalid (0 scaling) text matrix for Tm ****\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + % handle invalid scale by using a really small value + 2 -6 roll pop pop pop pop + 0.00000001 0 0 0.00000001 + 6 -2 roll + }if + TextLineMatrix astore TextMatrix copy pop settextstate +} bdef + +% ---------------- Text painting ---------------- % + +/Vexch { + rootfont /WMode knownoget { 1 eq { exch } if } if +} bind def + +/textrenderingprocs [ % (0 is handled specially) + % Painting-only modes + { tf } { tS } { tB } { tn } + % Clipping modes + { gsave tf grestore tW } + { gsave tS grestore tW } + { gsave tB grestore tW } + { tW } +] readonly def + +/pdfwrite_textrenderingprocs [ + % Tr 0 - Fill + { setfillstate show } bind + % Tr 1 - Stroke + { currentlinewidth exch setstrokestate + % Need to set the stroke width to a value which gives the correct + % width under pdfwrite. Pdfwrite uses (in text mode) an identity + % CTM, so we need to calculate the stroke width which would result + % if the CTM had been unity. + currentlinewidth dup + matrix defaultmatrix idtransform TextSaveMatrix dtransform + abs 2 copy exch abs eq { + pop + }{ + % non-square scaling reduces to Text matrix in pdfwrite , so + % we can ignore it. (wrong answer, but consistent) + pop pop currentlinewidth + }ifelse setlinewidth + show setlinewidth} bind + % Tr 2 - Fill then Stroke + { currentlinewidth exch setstrokestate + % Need to set the stroke width to a value which gives the correct + % width under pdfwrite. Pdfwrite uses (in text mode) an identity + % CTM, so we need to calculate the stroke width which would result + % if the CTM had been unity. + currentlinewidth dup + matrix defaultmatrix idtransform TextSaveMatrix dtransform + abs 2 copy exch abs eq { + pop + }{ + % non-square scaling reduces to Text matrix in pdfwrite , so + % we can ignore it. (wrong answer, but consistent) + pop pop currentlinewidth + }ifelse setlinewidth + setfillstate show setlinewidth} bind + % Tr 3 - Neither fill nor stroke + { setfillstate show } bind + % + % pdfwrite emits all text inside a gsave/grestore pair. As + % a result we can't preserve any of the 'clip' modes, as the + % clip gets undone by the restore. We need to handle the clip + % separately. + % + % Tr 4 - Fill, add to clip + { gsave 0 .settextrenderingmode + setfillstate dup show grestore //true charpath } bind + % Tr 5 - Stroke, add to clip + { gsave 1 .settextrenderingmode + currentlinewidth dup + matrix defaultmatrix idtransform TextSaveMatrix dtransform + abs 2 copy exch abs eq { + pop + }{ + % non-square scaling reduces to Text matrix in pdfwrite , so + % we can ignore it. (wrong answer, but consistent) + pop pop currentlinewidth + }ifelse setlinewidth + setstrokestate dup show grestore + //true charpath} bind + % Tr 6 - Fill, stroke, add to clip + { gsave 2 .settextrenderingmode + currentlinewidth dup + matrix defaultmatrix idtransform TextSaveMatrix dtransform + abs 2 copy exch abs eq { + pop + }{ + % non-square scaling reduces to Text matrix in pdfwrite , so + % we can ignore it. (wrong answer, but consistent) + pop pop currentlinewidth + }ifelse setlinewidth + setstrokestate setfillstate dup show grestore + //true charpath} bind + % Tr 7 - Add to clip + { //true charpath} bind +] readonly def + +/setstrokeforTrpreservation { + % Check to see if the current device supports Tr + /PreserveTrMode /GetDeviceParam .special_op { + exch pop + }{ + //false + }ifelse + { + TextRenderingMode 1 eq TextRenderingMode 2 eq or + TextRenderingMode 5 eq TextRenderingMode 6 eq or or { + setstrokestate + % Need to set the stroke width to a value which gives the correct + % width under pdfwrite. Pdfwrite uses (in text mode) an identity + % CTM, so we need to calculate the stroke width which would result + % if the CTM had been unity. NOTE! Only interested in magnitudes, + % not signs. + currentlinewidth dup + matrix defaultmatrix idtransform TextSaveMatrix dtransform + abs 2 copy exch abs eq { + pop + }{ + % non-square scaling reduces to Text matrix in pdfwrite , so + % we can ignore it. (wrong answer, but consistent) + pop pop currentlinewidth + }ifelse + setlinewidth + } if + } if +} bind def + +% conditionally set fillstate to avoid multiple operations during text operators +/settextfillstate { + TextFillStateNeeded { setfillstate //false /TextFillStateNeeded gput } if +} bind def + +% If current path is not known to be valid, use the clip path +/TextTransSetup { % showarg path_valid TextTransSetup false showarg + % showarg path_valid false TextTransSetup prev_BM prev_opacity true showarg + % NB: if 'show' is used, then we use the clippath, but a smaller bbox is preferred + SoftMask //null ne { + dup mark /Subtype /Group /Isolated //true .dicttomark exch + { pathbbox } { gsave clippath pathbbox grestore } ifelse + .begintransparencygroup + } if + //null checkOPtrans { + % We need to push a non-isolated, non-knockout transparency group and + % perform the operation in CompatibleOverprint mode, then end the + % transparency group. Do the begintransparencygroup step here. + mark /Subtype /Group /Isolated //false .dicttomark exch + { pathbbox } { gsave clippath pathbbox grestore } ifelse + .begintransparencygroup + OPsavedict dup /saveBM .currentblendmode put /saveOA .currentopacityalpha put % save current values + /CompatibleOverprint .setblendmode 1 .setopacityalpha + } { + pop % discard path_valid boolean + } ifelse +} bind def + +/TextTransTeardown { % stack: path_valid + .currentblendmode /CompatibleOverprint eq { + % end the CompatibleOverprint group and restore the opacity and BM + .endtransparencygroup + OPsavedict dup /saveOA get .setopacityalpha /saveBM get .setblendmode + } if + SoftMask //null ne { + .endtransparencygroup + } if +} bind def + +/setshowstate + { WordSpacing 0 eq TextSpacing 0 eq and FontMatrixNonHV not and + { + % Check to see if the current device supports Tr + /PreserveTrMode /GetDeviceParam .special_op { + exch pop + }{ + //false + }ifelse + { + pdfwrite_textrenderingprocs TextRenderingMode get + } + { + TextRenderingMode 0 eq + currentfont /FontType get 3 eq TextRenderingMode 3 eq not + and or + { + { settextfillstate //false TextTransSetup show TextTransTeardown } + } { + TextRenderingMode 3 eq { + % Some PDF files execute 'tm' with a singular matrix, + % and then use the text rendering mode 3. + % The graphics library currently cannot handle text + % operations when the CTM is singular. + % Work around this here. + { + matrix currentmatrix dup dup + dup 0 get 0 eq 1 index 1 get 0 eq and { + dup dup 2 get 0 eq { 0 }{ 1 } ifelse 1 put + } if + dup 2 get 0 eq 1 index 3 get 0 eq and { + dup dup 1 get 0 eq { 3 }{ 2 } ifelse 1 put + } if + setmatrix + currentpoint + % don't worry about transparency for invisible text + 4 index settextfillstate show % Tr was set to graphic state. + moveto + setmatrix + % now set the currentpoint using the original matrix + gsave + setmatrix + //false charpath currentpoint newpath + grestore + moveto + } + } { + { //false charpath textrenderingprocs TextRenderingMode get exec } + } ifelse + } ifelse + } ifelse + } + { + % If we are doing a plain old fill, or no text at all, *or* we are going to + % a device supporting text rendering modes, then go through this route. + % + TextRenderingMode 0 eq TextRenderingMode 3 eq or + currentfont /FontType get 3 eq or + + /PreserveTrMode /GetDeviceParam .special_op { + exch pop + }{ + //false + }ifelse + % pdfwrite can't handle rendering modes which involve clipping + TextRenderingMode 4 lt and or + % Tr was set to graphic state. + { + FontMatrixNonHV { + { + % preserve current line width around possible stroke setup + currentlinewidth exch + setstrokeforTrpreservation + settextfillstate //false TextTransSetup + [ TextSpacing WordSpacing 3 index + { % str [... weach wword c undef|ythis xthis|undef + exch % will be removed, unless FontMatrix.xx/yy == 0 (FontMatrixNonHV already true) + Vexch pop % str [... weach wword c wthis + 3 index add exch 32 eq {1 index add} if % str [... weach wword w + 3 1 roll % str [... w weach wword + } + % for the "exch" removed or not below, see comment in pdf_font.ps::getfontmetrics + currentfont /FontMatrix get 0 3 Vexch pop get 0 ne { + 1 1 index length 1 sub getinterval cvx + } if + cshow pop pop ] + { xshow } { yshow } Vexch pop exec + setlinewidth TextTransTeardown + } + } { + WordSpacing 0 eq { + { + { setstrokeforTrpreservation + settextfillstate //false TextTransSetup TextSpacing 0 Vexch 3 -1 roll ashow TextTransTeardown + } + currentlinewidth + { setlinewidth } + 3 .execn + } + } { + TextSpacing 0 eq { + { % preserve current line width around possible stroke setup + { setstrokeforTrpreservation + settextfillstate //false TextTransSetup WordSpacing 0 Vexch 32 4 -1 roll .pdfwidthshow + TextTransTeardown + } + currentlinewidth + { setlinewidth } + 3 .execn + } + } { + { % preserve current line width around possible stroke setup + { setstrokeforTrpreservation + settextfillstate //false TextTransSetup WordSpacing 0 Vexch 32 + TextSpacing 0 Vexch 6 -1 roll .pdfawidthshow TextTransTeardown + } + currentlinewidth + { setlinewidth } + 3 .execn + } + } ifelse + } ifelse + } ifelse + } + { + { currentlinewidth exch + WordSpacing TextSpacing + % Implement the combination of t3 and false charpath. + % Note that we must use cshow for this, because we + % can't parse multi-byte strings any other way. + % Stack: string wword wchar + { + exch % will be removed, unless FontMatrixNonHV && FontMatrix.xx/yy == 0 + % Stack: str wword wchar ccode xthis ythis + Vexch pop currentpoint 6 3 roll + % Stack: str wthis xorig yorig wword wchar ccode + (x) dup 0 3 index put + % + % for devices which can handle the text rendering mode we don't want + % to decompose into paths, we want to do a 'show'. However pdfwrite + % can't handle clipping text, so we *do* want to do the clip path + % as a 'true charpath'. + % + /PreserveTrMode /GetDeviceParam .special_op { + exch pop + }{ + //false + }ifelse { + % NB we must have Tr at least 4 or the test above would have + % taken a different path, so we *know* the Tr involves clipping + % or we wouldn't be here. Subtract 4 from the Tr and preserve + % that mode, then do a charpath so the clip path gets set up + % correctly. + gsave TextRenderingMode 4 sub .settextrenderingmode + setstrokeforTrpreservation + setstrokestate settextfillstate //false TextTransSetup dup show grestore TextTransTeardown } if + //false charpath + 3 copy 32 eq { add } { exch pop } ifelse + % Stack: str wthis xorig yorig wword wchar ccode wextra + 7 -3 roll moveto add + 0 Vexch rmoveto pop + } + % for the "exch" removed or not below, see comment in pdf_font.ps::getfontmetrics + FontMatrixNonHV dup not exch { + currentfont /FontMatrix get 0 3 Vexch pop get 0 ne + } if { + 1 1 index length 1 sub getinterval cvx + } if + 4 -1 roll cshow pop pop + % + % If the device doesn't handle text rendering modes then we now have a suitable + % path, so call the correct routine to stroke/fill it (clip is handled when we + % get ET). + % + /PreserveTrMode /GetDeviceParam .special_op { + exch pop not + }{ + //true + }ifelse { + textrenderingprocs TextRenderingMode get exec + } if + setlinewidth + } + } + ifelse + } + ifelse /Show gput + } bdef +/showfirst { setshowstate Show } def + +/Tj { + { + //true /TextFillStateNeeded gput + 0 0 moveto Show settextposition + } + OFFlevels length 0 eq { + exec + } { + gsave get-gs-attrs nulldevice set-gs-attrs + exec + get-gs-attrs grestore set-gs-attrs + } ifelse + //true /TextFillStateNeeded gput +} bdef +/' { T* Tj } bdef +/" { exch Tc exch Tw T* Tj } bdef +/TJ { + { 0 0 moveto { + dup type /stringtype eq { + Show + } { -1000 div + currentfont /ScaleMatrix .knownget { 0 get mul } if + 0 Vexch rmoveto + } ifelse + } forall settextposition + //true /TextFillStateNeeded gput + } + OFFlevels length 0 eq { + exec + } { + gsave get-gs-attrs nulldevice set-gs-attrs + exec + get-gs-attrs grestore set-gs-attrs + } ifelse + //true /TextFillStateNeeded gput +} bdef + +% NB: We don't need clippath when filling or stroking +/tf { + //true /TextFillStateNeeded gput + settextfillstate //true TextTransSetup currentpoint fill TextTransTeardown moveto +} bdef +/tn { currentpoint newpath moveto } bdef % Obsolete, never used. +% For stroking characters, temporarily restore the graphics CTM so that +% the line width will be transformed properly. +/Tmatrix matrix def +/tS + { + currentfont /FontType get 3 eq + { + settextfillstate //true TextTransSetup currentpoint fill TextTransTeardown moveto + } + { + setstrokestate //true TextTransSetup + currentpoint //Tmatrix currentmatrix TextSaveMatrix setmatrix .swapcolors stroke TextTransTeardown .swapcolors + setmatrix moveto + } ifelse + //true /TextFillStateNeeded gput + } bdef + +% Handle transparency the same as /B operator +/tB { + PDFusingtransparency { + % knockout trans group around the filled and stroked object + mark + /Isolated //true /Knockout //true + .dicttomark + 1 .setopacityalpha + % While text will always have a currentpoint, strokepath seems to mess with it. + % we get the currentpoint, then use moveto to restore it for pathbbox + gsave currentpoint strokepath moveto pathbbox grestore + .begintransparencygroup + gsave tf grestore tS + .endtransparencygroup + } { + gsave tf grestore tS + } ifelse + //true /TextFillStateNeeded gput +} bdef + +% This does the wrong thing if there have been multiple text operations +% within a single BT/ET pair, but it's a start. +/tW { } bdef + +%% split a string containing \r or \n into multiple strings) +%% \r\n is also handled. +%% (string) .splitstring (string1) (string2) ..... +/.splitstring { + 0 exch %% start_index string + dup length 1 sub %% start_index string (string length - 1) + 0 1 3 -1 roll %% start_index string 0 1 (string_length -1) + { %% start_index string loop_index + dup %% start_index string loop_index loop_index + 2 index exch get %% start_index string loop_index character + dup 10 eq exch 13 eq or { %% start_index string loop_index + dup 3 index %% start_index string loop_index loop_index start_index + sub %% start_index string loop_index (loop_index - start_index) + dup 0 gt { %% \r\n will give us a 0 length string so ignore it + 3 index exch %% start_index string loop_index start_index (loop_index - start_index) + 3 index 3 1 roll %% start_index string loop_index string start_index (loop_index - start_index) + getinterval %% start_index string loop_index sub_string + 4 1 roll %% sub_string start_index string loop_index + 1 add + 3 -1 roll %% sub_string string loop_index start_index + pop exch %% sub_string loop_index string %% loop_index becomes new start_index + }{ + pop %% start_index string loop_index + 1 add 3 1 roll exch %% loop_index string start_index + pop %% loop_index string %% loop_index becomes new start index + } ifelse + }{ + pop %% start_index string + } ifelse + } for + %% start_index string + dup length 2 index sub dup %% start_index string (length - start_index) (length - start_index) + 0 gt { %% we have characters left %% start_index string (length - start_index) + 3 -1 roll exch %% string start_index (length - start_index) + getinterval %% sub_string + } { + pop pop pop + } ifelse +} bind def + +% Text formatting and painting for the AcroForm field without appearance streams. +/Tform { % <MaxLen> (V) <Ff> <Q> Tform - + clippath pathbbox 4 2 roll pop pop % MaxLen (V) Ff Q dx dy + currentfont /ScaleMatrix .knownget { 3 get } { 1 } ifelse % MaxLen (V) Ff Q dx dy yy + + currentfont /FontBBox .knownget + not + { + currentfont dup /FontType get + 0 eq + { + /FDepVector get 0 get /FontBBox get} + { + pop null % force an error + } ifelse + }if + dup 1 get neg exch 3 get % MaxLen (V) Ff Q dx dy yy desc asc + + dup 0 ne { div } { pop pop 0 } ifelse % MaxLen (V) Ff Q dx dy yy desc/asc + 1 index mul % MaxLen (V) Ff Q dx dy yy desc/asc*yy + + %% Check if this is declared as a multiine text widget, and if it is + %% check that the string has at least 2 characters, so we can split it + %% into at least two strings.... + %% Bug #687498.pdf has a multiline text widget with an empty string (amongst + %% many other problems with this file). + 5 index 16#1000 and 0 ne 7 index length 1 gt and{ % multiline + %% First lets see how many lines we have, make a copy of the string + 6 index mark exch .splitstring % MaxLen (V) Ff Q dx dy yy desc/asc*yy [ () () ... + counttomark 1 add 4 add index % MaxLen (V) Ff Q dx dy yy desc/asc*yy [ () () ... count Q + dup 0 eq { + pop % remove extra copy of Q + counttomark dup 2 add 2 add index exch div % MaxLen (V) Ff Q dx dy yy desc/asc*yy [ () () ... line_height + counttomark 1 add 1 roll % MaxLen (V) Ff Q dx dy yy desc/asc*yy line_height [ () () ... + 2 0 moveto % start at bottom left of rect + counttomark 1 1 3 -1 roll { % for every string + pop gsave + <FEFF> anchorsearch { + pop + } if + Show grestore % pop loop counter, show string (saving current point) + counttomark 1 add index 0 exch rmoveto % get line height, move that amount vertically. + } for + pop pop + }{ + 1 eq { + counttomark dup 2 add 2 add index exch div % MaxLen (V) Ff Q dx dy yy desc/asc*yy [ () () ... line_height + counttomark 1 add 1 roll % MaxLen (V) Ff Q dx dy yy desc/asc*yy line_height [ () () ... + 2 0 moveto % start at bottom left of rect + counttomark 1 1 3 -1 roll { % for every string + pop gsave % pop loop counter + <FEFF> anchorsearch { + pop + } if + dup stringwidth pop counttomark 5 add index % get rectangle width + exch sub 2 div 0 rmoveto % subtract width of string, divide by 2 move that amount + Show grestore % show string + counttomark 1 add index 0 exch rmoveto % get line height, move that amount vertically. + } for + pop pop + }{ + counttomark dup 2 add 2 add index exch div % MaxLen (V) Ff Q dx dy yy desc/asc*yy [ () () ... line_height + counttomark 1 add 1 roll % MaxLen (V) Ff Q dx dy yy desc/asc*yy line_height [ () () ... + 2 0 moveto % start at bottom left of rect + counttomark 1 1 3 -1 roll { % for every string + pop gsave % pop loop counter + <FEFF> anchorsearch { + pop + } if + dup stringwidth pop counttomark 5 add index % get rectangle width + exch sub 2 sub 0 rmoveto % subtract width of string,move that amount + Show grestore % show string + counttomark 1 add index 0 exch rmoveto % get line height, move that amount vertically. + } for + pop pop + }ifelse + }ifelse + 8 { pop } repeat + } { + 5 index 16#1000000 and 0 ne { % comb + 8 { pop } repeat (Combed form fields are not yet implemented.) = + } { % plain text + 3 1 roll sub add 2 div % MaxLen (V) Ff Q dx (dy-yy+desc)/2 + 0 exch moveto % MaxLen (V) Ff Q dx + 1 index 0 ne { + 3 index + <FEFF> anchorsearch { + pop + } if + stringwidth pop % MaxLen (V) Ff Q dx w + sub exch 1 eq { 2 div } { 2 sub } ifelse % MaxLen (V) Ff (dx-w)/2 + 0 rmoveto % MaxLen (V) Ff + pop % MaxLen (V) + } { + pop pop pop % MaxLen (V) + 2 0 rmoveto + } ifelse + exch pop + <FEFF> anchorsearch { + pop + } if + Show % - + } ifelse + } ifelse +} bdef + +end readonly put % GS_PDF_ProcSet + +.setglobal diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_rbld.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_rbld.ps new file mode 100644 index 00000000000..673a8db8ad2 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_rbld.ps @@ -0,0 +1,448 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% + +% pdf_rbld.ps - Rebuilding of broken PDF files (xref errors) + +% This module contains routines that are used if we detect an error +% while reading the xref tables. These routines will scan the file and +% build an xref table by finding the objects. We also need to find the +% appropriate trailer dictionary. Note: One procedure is also used +% even if we do not need to rebuild a PDF file. +% +% This module cannot rebuild a PDF file which has had errors created inside +% of objects or binary data streams. It often succeeds with files that +% have had its end of lines converted between unix and dos versions. + +% if true --> we have an object with duplicate object and generation numbers. +/dup_obj_gen_num //false def + +% Note: This procedure is also used by non-rebuild code. +% Store a line in the xref array (Actually Objects and Generations arrays) +% <obj num> (strm num> <obj loc> <gen num> <rebuild> +% setxrefentry <obj num> strm num> <obj loc> <gen num> +/setxrefentry +{ + 5 1 roll + dup 65535 or 65535 ne { + ( **** Error: Generation number out of 0..65535 range, assuming 0.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + pop 0 + } if + % We store generation numbers as value + 1 + % We reserve 0 to indicate an free xref entry + 1 add % increment generation number + % To save space, generations numbers are stored in a string unless we + % find a generation number greater than 255. If so then transfer to + % an array. + dup 255 gt { + Generations type /stringtype eq { % Convert Generations to an array. + Generations length array dup % Create new array + 0 1 2 index length 1 sub { % Copy from old string to new array + Generations 1 index get put dup + } for + pop + /Generations exch store % Save new Generations array + } if + } if + % Verify that the new values are for a new object. If the current + % entry is null then we have a new entry. + Objects 4 index get //null eq { + ObjectStream 4 index 4 index cvx put % Save ObjectStream object number + Objects 4 index 3 index cvx put % Save object location + Generations 4 index 2 index put % Save geenration number + } { + % Verify that the new entry has at least as high a generaton number + % We accept equal entry number because we have found PDF files in + % which there are multiple objects with the same object and entry + % numbers. The normal xref logic only accepts the first such + % entry that it finds. However the 'rebuild PDF' logic can find + % both such entries. The correct one is usually the last one. + Generations 4 index get 1 index le { + %% Check if the object we already found was at the locaton specified + %% in the original xref (now stored in Orig_Objects). If so, prefer + %% that offset, otherwise prefer the later object. + %% NB check first to see that the object number is in the range of the original + %% xref. If it isn't, set the 'original' Offset to 0. + 3 index Orig_Objects length le {Orig_Objects 4 index get}{0}ifelse + Objects 5 index get eq not + { + ObjectStream 4 index 4 index cvx put % Save ObjectStream object number + Objects 4 index 3 index cvx put % Save object location + Generations 4 index 2 index put % Save geenration number + } if + } if + % Set error flag if we have equal object and generation numbers + Generations 4 index get 1 index eq { /dup_obj_gen_num //true def } if + } 8 -1 roll { ifelse } { pop if } ifelse % Run 'else' only when rebuilding. +} bind def + +% Print the contents of the xref array. This actually consists of three +% arrays (Objects, Generations, and ObjectStream). +/print_xref % - print_xref - +{ 0 1 Objects length 1 sub % stack: 0 1 <number of objects - 1> + { dup =only % print object number + ( ) print + dup Generations exch get 1 sub =only % print Generation number + ( ) print + dup ObjectStream exch get ==only % print ObjectStream object number + ( ) print + Objects exch get === % print object location + } for + flush +} bind def + +% Get token from string and check its type +% <string> <type> typed_token <false> % no token or not match +% <string> <type> typed_token <obj> <last> <true> % matching token type +% Where last is the string remainder +/typed_token +{ exch + token_nofail % get token + { + dup type % stack: type last token type + 4 -1 roll eq { % stack: last token bool + exch //true % desired object found - set exit status + } { + pop pop //false % not type - clear stack, set exit status + } ifelse + } { + pop //false % no token - pop type, set exit status + } ifelse % check if we got token +} bind def + +% Allocate space for post_eof_count to be bound into procedures below. +/post_eof_count 0 def + +% We want the location of the trailer dictionary at the start of file. +% First we will find the xref. Then we will skip over the xref entries +% to the trailer. +/search_start_trailer % - search_start_trailer <trailer loc> +{ % Read the first 300 bytes and check for xref + PDFfile 0 setfileposition + PDFfile bytesavailable post_eof_count sub % location of end of data + 300 .min % block size to read + dup string 0 1 4 -1 roll 1 sub + { 2 copy PDFfile read pop put pop } for + (xref) search { + % found 'xref' + exch pop exch pop length 4 add PDFfile exch setfileposition + PDFfile token pop % get starting entry - or 'trailer' + (trailer) ne { % if we do not already have 'trailer' + PDFfile token pop % get number of entries + PDFfile token pop pop % this moves us into the middle of the first entry + 25 string exch % define working string for readline + { PDFfile 1 index readline pop pop + } repeat % skip entries + pop % pop working string + PDFfile token pop pop % get 'trailer' + PDFfile fileposition % get file position + } if + } { + pop 0 % no xref, should not happen, report it upstrem + } ifelse +} bind def + + +%% Searches backwards from a specified point looking for a 'trailer' keyword. +%% position search_earlier_trailer position or 0 +%% +%% Its is just possible that a 'trailer' keyword could straddle a buffer, in which case +%% we wouldn't find it. Given that this only executes for broken files anyway I don't +%% propose to worry about it at the moment, if anyone ever turns up an example we may +%% choose to enhance this routine further. +%% +/search_earlier_trailer { + { % position + dup 0 gt { % position bool + dup 65535 .min exch % block_size position + 1 index sub % block_size position-block_size + dup % block_size new_position new_position + PDFfile exch setfileposition % block_size new position + exch dup % new position block_size block_size + dup string 0 1 4 -1 roll 1 sub % + {2 copy PDFfile read pop put pop } for % + % new_position block size (...string from file....) + (trailer) search { + pop + { search not { exit } if pop } loop + % determine where the trailer is in the file + % trailer loc = end loc - remaing string length + length % new_position block size string length + 3 1 roll % string length new_position block size + add exch sub % string length - (new_position + block size) + } { + pop % discard old block size + pop 0 + } ifelse + } { + pop 0 exit + }ifelse + + %% We either have a position for a trailer, or 0 if we failed to find one + dup 0 eq not { + exit + }if + pop % renove the zero leaving the new start position + } loop +} bind def + +% We want the location of the trailer dictionary at the end of file. +% We will read the last block of data and search for the final occurance +% of the word 'trailer' +/search_end_trailer % - search_end_trailer <trailer loc> +{ % Position to read block of data from the end of the file. Note: We ignore + % anything past the last %%EOF since this is not PDF data. + PDFfile 0 setfileposition + PDFfile bytesavailable post_eof_count sub % location of end of data + dup 65535 .min % block size to read + % stack: <file end pos> <block size> + % move file position to the start of the block + 2 copy sub PDFfile exch setfileposition + % read block of data + dup string 0 1 4 -1 roll 1 sub { 2 copy PDFfile read pop put pop } for + % search for last occurance of 'trailer' + (trailer) search { + pop + { search not { exit } if pop } loop + % determine where the trailer is in the file + % trailer loc = end loc - remaing string length + length sub + } { + pop pop 0 + } ifelse +} bind def + +% We want to find the trailer dictionary. There is a trailer dictionary +% for each xref object list. We only want the trailer dictionary associated +% with the first xref object list. In theory this can be anywhere in the +% file. However since we are trying to repair a broken file, we cannot simply +% follow the xref links. So we are falling back to a simple strategy. We +% find the specified location of the first xref list. If its location is in +% the first half of the file then we search for the first trailer dictionary +% at the start of the file. Otherwise we search for the last trailer at the +% end of the file. +/search_trailer % - search_trailer - +{ % Find the 'startxref' and associated position at the end of the file. + % Position to read block of data from the end of the file. Note: We + % actually end at the end of the last %%EOF since this is the end of the + % useful PDF data. (Some files contain trailing garbage.) + PDFfile 0 setfileposition + PDFfile bytesavailable % size of file + post_eof_count sub dup % location of end of last %%EOF + dup 4096 .min % block size to read + % stack: <useful file size> <useful file size file> <block size> + % move file position to the start of the block + 2 copy sub PDFfile exch setfileposition + % read block of data + dup string 0 1 4 -1 roll 1 sub { 2 copy PDFfile read pop put pop } for + % search for last occurance of 'startxref' + //false % Assume that startxref not present + exch (startxref) { + search not { exit } if % Exit loop when no more startxref's + pop 3 -1 roll pop //true 3 1 roll % Idicate that we have found starxref + } loop + exch % Exch last string and 'found' flag + { + % determine where the startxref is in the file + % 'startxref' loc = end loc - remaing string length - 9 bytes + length sub 9 sub + % move the file to this position and read startxref and position + PDFfile exch setfileposition PDFfile token + pop pop PDFfile token_no_close pop + dup type /integertype eq not { + pop + % startxref not followed by integer. We will search the end of the file for trailer. + PDFfilelen + } if + } { + % startxref not found. We will search the end of the file for trailer. + pop pop PDFfilelen + } ifelse + % compare xref position to 1/2 the length of the file and search for trailer + exch 2 div lt { + search_start_trailer dup 0 eq { pop search_end_trailer } if + } { + search_end_trailer dup 0 eq { pop search_start_trailer } if + } ifelse + dup 0 eq { + pop + ( **** Error: Trailer dictionary not found.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + }{ + % get the trailer + dup + PDFfile exch setfileposition % set to the specified trailer location + /dictlevelcount 0 def + PDFfile traileropdict .pdfrun % read trailer info + + { + dup /Root known not { + ( **** Warning: This trailer dictionary does not contain a /Root entry\n searching for a prior trailer.\n) pdfformatwarning + %% remove trailer dict copy, duplicate file position, then remove the length of 'trailer' so we don't + %% find the same one again.... + pop dup 7 sub + search_earlier_trailer + }{exit}ifelse + dup 0 eq { + pop + ( **** Error: Valid trailer not found.\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + }{ + PDFfile exch setfileposition % set to the specified trailer location + /dictlevelcount 0 def + PDFfile traileropdict .pdfrun % read trailer info + } ifelse + } loop + /Trailer exch def + pop + } ifelse +} bind def + +% This routine will determine if there is stuff after the %%EOF. There is +% supposed to be only a line termination. However many real life files +% contain some garbage. This routine checks how much. We then ignore this +% stuff when we are scanning for objects. +/determine_post_eof_count % - determine_post_eof_count <count> +{ % Position to read block of data from the end of the file. + PDFfilelen % size of file + dup 4096 .min % file_size block_size + dup 3 1 roll sub % block_size file_size-block_size + PDFfile exch setfileposition % block_size + string PDFfile exch readstring pop % () + + % search for last occurance of 'startxref', '%%EOF' is often damaged + (startxref) search { + pop + { search not { exit } if pop + } loop + % how much is left = remaining string length + + % Now search for %%EO or try to read a number after 'startxref'. + (%%EO) search { + pop pop + } { + % Look for a number after startxref + { dup token { pop exch pop } if + } stopped pop + } ifelse + length + } { + % Can't even find startxref, assume it's all objects + pop 0 + } ifelse +} bind def + +% This routine will scan a file searaching for object locations to build +% an alternate version of the data in the xref tables. +% Its purpose is to provide a basis for an xref fixing facility. +/search_objects % - search_objects - +{ % Initialize the Objects, Generations, etc. arrays + Objects dup length array copy /Orig_Objects exch def + initPDFobjects + % reset duplicate object and generation numbers error flag + /dup_obj_gen_num //false def + % Determine how many bytes are in the file after the final %%EOF + /post_eof_count determine_post_eof_count def + % Start at the beginning of the file + PDFfile 0 setfileposition + % Create a working string (and also store its length on stack). We are + % using a maximum size string size the logic below wants a recovered object + % to fit into our working string. + 65535 dup string + { % Now loop through the entire file looking for objects + PDFfile fileposition % save current file position + % When we get near the end of the file, we use a smaller interval of + % our working string to prevent reading past the end. (See comments on + % EOF testing below.) + PDFfile bytesavailable post_eof_count sub 10 sub dup 4 index lt { + 2 index 0 3 -1 roll getinterval % near EOF, use interval of string + } { + pop 1 index % not near end, use full working string + } ifelse + % Read a line from file. If the line does not fit into our working string, + % or any other error, then we will discard it. + PDFfile exch { readline } .internalstopped + { pop pop //false } if % indicate no string if we stopped + { % stack: <length> <working_str> <loc> <string> + % Now that we have line, get obj num, ref num, and 'obj'. Verify that each + % of these is correct type. + dup (obj) search { % preliminary check for obj + pop pop pop + /integertype typed_token { % get obj number + /integertype typed_token { % get ref number + /nametype typed_token { % get 'obj' text + pop % pop remaining string + /obj eq { % verify name is 'obj' + % make sure we have room in the arrays. We work in increments + % of 20 each time we increase the size. + 1 index 20 add 20 idiv 20 mul + growPDFobjects + % save xref parameters into ObjectStream, Objects and Generations + 1 index 0 % rearrange parms for setxrefentry + 4 index PDFoffset sub 3 index + //true setxrefentry % save parameters + pop pop pop pop % clear parameters + } if % check if name is 'obj' + } if % check if we got 'obj" string + pop % remove ref number + } if % check if we got ref number + pop % remove obj number + } if % check if we got object number + } { + pop pop + } ifelse + } if % check if got a string from readline + pop % remove location + % Check if we are approaching the end of the file. We do not want to + % read past the end of the file since that closes it. We actually stop + % 10-20 bytes early since there cannot be an object that close to the end. + % (There is a Trailer dictionary, etc. at the end of the file.) + PDFfile bytesavailable post_eof_count sub 20 lt { exit } if + } loop % loop through the entire file + pop pop % remove working string and its length + % Output warning if we have two objects with the same object and generation + % numbers. + dup_obj_gen_num { + ( **** Warning: There are objects with matching object and generation\n) + pdfformatwarning + ( **** numbers. The output may be incorrect.\n) + pdfformatwarning + } if + currentdict /Orig_Objects undef +} bind def + +% Print warning message because we found a problem while reading the xref +% tables +/print_xref_warning +{ ( **** Error: An error occurred while reading an XREF table.\n) + pdfformaterror + ( **** The file has been damaged. This may have been caused\n) + pdfformaterror + ( **** by a problem while converting or transfering the file.\n) + pdfformaterror + ( **** Ghostscript will attempt to recover the data.\n) + pdfformaterror + ( **** However, the output may be incorrect.\n) pdfformaterror +} bind def + +% Attempt to recover the XRef data. This is called if we have a failure +% while reading the normal XRef tables. This routine usually works +% only for pre PDF1.5 versions of PDF files. +/recover_xref_data % - recover_xref_data - +{ print_xref_warning % Print warning message + count pdfemptycount sub { pop } repeat % remove anything left by readxref + search_objects % Search for objects +} bind def diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_sec.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_sec.ps new file mode 100644 index 00000000000..3889ae70292 --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_sec.ps @@ -0,0 +1,751 @@ +% Copyright (C) 2001-2012 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., 7 Mt. Lassen Drive - Suite A-134, San Rafael, +% CA 94903, U.S.A., +1(415)492-9861, for further information. +% +% Copyright (C) 1996-1998 Geoffrey Keating. +% Copyright (C) 2001-2008 Artifex Software, Inc. +% This file may be freely distributed with or without modifications, +% so long as modified versions are marked as such and copyright notices are +% not removed. + +% Implementation of security hooks for PDF reader. + +% This file contains the procedures that have to take encryption into +% account when reading a PDF file. It was originally distributed +% separately by Geoffrey Keating as an add-on to version 6 and earlier. + +% Modified by Alex Cherepanov to work with GS 6.60 and higher. +% New versions of GS require explicit checks for /true, /false, and /null +% in .decpdfrun. This fix is backward-compatible. + +% Modified by Raph Levien and Ralph Giles to use the new C +% implementations of md5 and arcfour in ghostscript 7.01, and to +% be compatible with PDF 1.4 128-bit encryption. + +% Modified by Ralph Giles for PDF 1.6 AES encryption. + +% Modified by Michael Constant for PDF 1.7 ExtensionLevel 3 +% AES-256 encryption. + +/.setlanguagelevel where { pop 2 .setlanguagelevel } if +.currentglobal //true .setglobal +/pdfdict where { pop } { /pdfdict 100 dict def } ifelse +pdfdict begin + +% Older ghostscript versions do not have .pdftoken, so we use 'token' instead. +/.pdftoken where { pop } { /.pdftoken /token load def } ifelse + +% take a stream and arc4 decrypt it. +% <stream> <key> arc4decodefilter <stream> +/arc4decodefilter { + 1 dict begin + /Key exch def + currentdict end /ArcfourDecode filter +} bind def + +% <ciphertext> <key> arc4decode <plaintext> +/arc4decode { + 1 index length 0 eq { + pop + } { + 1 index length string 3 1 roll arc4decodefilter exch readstring pop + } ifelse +} bind def + +% take a stream and aes decrypt it. +% <stream> <key> aesdecodefilter <stream> +/aesdecodefilter { + 1 dict begin + /Key exch def + currentdict end + /AESDecode filter +} bind def + +% AES decrypt a string, returning a string. The second argument can +% be a dictionary of the form << /Key key /Padding false >>, which +% specifies the key and any options for the AESDecode filter, or it +% can just be a string (the key). +% +% <ciphertext> <dict> aesdecode <plaintext> +% <ciphertext> <key> aesdecode <plaintext> +/aesdecode { + 1 index length 0 eq { + pop + } { + 1 index length string 3 1 roll + + % If our second argument is a dictionary, it's the full set + % of decoding options (including the key); pass it directly + % to the AESDecode filter. Otherwise, it's just the key, so + % call aesdecodefilter to construct the dictionary. + dup type /dicttype eq { /AESDecode filter } { aesdecodefilter } ifelse + + exch readstring pop + } ifelse +} bind def + +/md5 { + 16 string dup /MD5Encode filter dup 4 3 roll writestring closefile +} bind def + +/md5_trunk { + md5 0 pdf_key_length getinterval +} bind def + +/sha256 { + 32 string dup /SHA256Encode filter dup 4 3 roll writestring closefile +} bind def + +% <string> contains_non_ascii <bool> +/contains_non_ascii { + //false exch { 128 ge { pop //true exit } if } forall +} bind def + +/pdf_padding_string + <28bf4e5e4e758a41 64004e56fffa0108 + 2e2e00b6d0683e80 2f0ca9fe6453697a> +def + +% Pad a key out to 32 bytes. +/pdf_pad_key { % <key> pdf_pad_key <padded key> + dup length 32 gt { 0 32 getinterval } if + pdf_padding_string + 0 32 3 index length sub getinterval + concatstrings +} bind def + +/pdf_xorbytes { % <iter-num> <key> pdf_xorbytes <xored-key> + dup length dup string + exch 1 sub 0 1 3 2 roll { + % <iter-num> <key> <new-key> <byte-num> + dup 3 index exch get 4 index xor + % <iter-num> <key> <new-key> <byte-num> <byte> + 3 copy put pop pop + } for + 3 1 roll pop pop +} bind def + +% Get length of encryption key in bytes +/pdf_key_length { % pdf_key_length <key_length> + Trailer /Encrypt oget + dup /V knownoget not { 0 } if 1 eq + { pop 5 } % If V == 1 then always use 40 bits + { /Length knownoget { -3 bitshift } { 5 } ifelse } + ifelse +} bind def + +% Algorithm 3.2 +/pdf_compute_encryption_key { % <password> pdf_compute_encryption_key <key> + % Step 1. + pdf_pad_key + + % Step 2, 3. + Trailer /Encrypt oget dup /O oget + % <padded-key> <encrypt> <O> + + % Step 4. + exch /P oget 4 string exch + 2 copy 255 and 0 exch put + 2 copy -8 bitshift 255 and 1 exch put + 2 copy -16 bitshift 255 and 2 exch put + 2 copy -24 bitshift 255 and 3 exch put pop + % <padded-key> <O> <P> + + % Step 5. + Trailer /ID knownoget { 0 oget } { + () + ( **** Error: ID key in the trailer is required for encrypted files.\n) pdfformaterror + ( File may not be possible to decrypt.\n) pdfformaterror + } ifelse + 3 { concatstrings } repeat + % We will finish step 5 after possibly including step 6. + + % The following only executed for /R equal to 3 or more + Trailer /Encrypt oget dup /R oget dup 3 ge { + + % Step 6. If EncryptMetadata is false, pass 0xFFFFFFFF to md5 function + % The PDF 1.5 Spec says that EncryptMetadata is an undocumented + % feature of PDF 1.4. That implies that this piece of logic should + % be executed if R >= 3. However testing with Acrobat 5.0 and 6.0 shows + % that this step is not executed if R equal to 3. Thus we have a test for + % R being >= 4. + 4 ge { + /EncryptMetadata knownoget % Get EncryptMetadata (if present) + not { //true } if % Default is true + not { % If EncryptMetadata is false + <ff ff ff ff> concatstrings % Add 0xFFFFFFFF to working string + } if + } { + pop % Remove Encrypt dict + } ifelse + md5_trunk % Finish step 5 and 6. + + % Step 7. Executed as part of step 6 + % Step 8. (This step is defintely a part of PDF 1.4.) + 50 { md5_trunk } repeat + } { + pop pop md5_trunk % Remove R, Encrypt dict, finish step 5 + } ifelse + + % Step 9 - Done in md5_trunk. +} bind def + +% Algorithm 3.4 +/pdf_gen_user_password_R2 { % <filekey> pdf_gen_user_password_R2 <U> + + % Step 2. + pdf_padding_string exch arc4decode +} bind def + +% Algorithm 3.5 +/pdf_gen_user_password_R3 { % <filekey> pdf_gen_user_password_R3 <U> + + % Step 2. + pdf_padding_string + + % Step 3. + Trailer /ID knownoget { 0 oget } { + () + ( **** Error: ID key in the trailer is required for encrypted files.\n) pdfformaterror + ( File may not be possible to decrypt.\n) pdfformaterror + } ifelse + concatstrings md5 + + % Step 4. + 1 index arc4decode + + % Step 5. + 1 1 19 { + 2 index pdf_xorbytes arc4decode + } for + exch pop + +} bind def + +/pdf_gen_user_password { % <password> pdf_gen_user_password <filekey> <U> + % common Step 1 of Algorithms 3.4 and 3.5. + pdf_compute_encryption_key dup + + Trailer /Encrypt oget + + /R oget dup 2 eq { + pop pdf_gen_user_password_R2 + } { + dup 3 eq { + pop pdf_gen_user_password_R3 + } { + dup 4 eq { % 4 uses the algorithm as 3 + pop pdf_gen_user_password_R3 + } { + % This procedure is only used if R is between 2 and 4, + % so we should never get here. + /pdf_gen_user_password cvx /undefined signalerror + } ifelse + } ifelse + } ifelse +} bind def + +% Algorithm 3.6 +% <password> pdf_check_pre_r5_user_password <filekey> true +% <password> pdf_check_pre_r5_user_password false +/pdf_check_pre_r5_user_password { + pdf_gen_user_password + + Trailer /Encrypt oget /U oget + + 0 2 index length getinterval eq { + //true + } { + pop //false + } ifelse +} bind def + +% Compute an owner key, ie the result of step 4 of Algorithm 3.3 +/pdf_owner_key % <password> pdf_owner_key <owner-key> +{ + % Step 1. + pdf_pad_key + + % Step 2. + md5_trunk + + % 3.3 Step 3. Only executed for /R equal to 3 or more + Trailer /Encrypt oget /R oget 3 ge { + 50 { md5_trunk } repeat + } if + + % Step 4 - Done in md5_trunk. +} bind def + +% Algorithm 3.7 +% <password> pdf_check_pre_r5_owner_password <filekey> true +% <password> pdf_check_pre_r5_owner_password false +/pdf_check_pre_r5_owner_password { + % Step 1. + pdf_owner_key + + % Step 2. + Trailer /Encrypt oget dup /O oget 2 index arc4decode + % <encryption-key> <encrypt-dict> <decrypted-O> + + % Step 3. Only executed for /R equal to 3 or more + exch /R oget 3 ge { + 1 1 19 { + 2 index pdf_xorbytes arc4decode + } for + } if + exch pop + % <result-of-step-3> + + pdf_check_pre_r5_user_password +} bind def + +% Algorithm 3.2a +% <password> pdf_check_r5_password <filekey> true +% <password> pdf_check_r5_password false +/pdf_check_r5_password { + 10 dict begin % temporary dict for local variables + + % Step 1. + % If the .saslprep operator isn't available (because ghostscript + % wasn't built with libidn support), just skip this step. ASCII + % passwords will still work fine, and even most non-ASCII passwords + % will be okay; any non-ASCII passwords that fail will produce a + % warning from pdf_process_Encrypt. + /.saslprep where { pop .saslprep } if + + % Step 2. + dup length 127 gt { 0 127 getinterval } if + /Password exch def + + % Step 3. + /O Trailer /Encrypt oget /O oget def + /U Trailer /Encrypt oget /U oget def + + Password O 32 8 getinterval concatstrings + U 0 48 getinterval concatstrings sha256 + + O 0 32 getinterval eq { + % Step 3, second paragraph. + + Password O 40 8 getinterval concatstrings + U 0 48 getinterval concatstrings sha256 + + 16 string Trailer /Encrypt oget /OE oget concatstrings + << /Key 4 -1 roll /Padding //false >> aesdecode //true + } { + % Step 4. + Password U 32 8 getinterval concatstrings sha256 + U 0 32 getinterval eq { + % Step 4, second paragraph. + Password U 40 8 getinterval concatstrings sha256 + + 16 string Trailer /Encrypt oget /UE oget concatstrings + << /Key 4 -1 roll /Padding //false >> aesdecode //true + } { + //false + } ifelse + } ifelse + + % Step 5. + dup { + % Adobe says to decrypt the Perms string using "ECB mode with + % an initialization vector of zero", which must be a mistake -- + % ECB mode doesn't use initialization vectors. It looks like + % they meant "ECB mode, or CBC mode with an initialization + % vector of zero", since the two are equivalent for a single- + % block message. We use the latter. + 16 string Trailer /Encrypt oget /Perms oget concatstrings + << /Key 4 index /Padding //false >> aesdecode + + 9 3 getinterval (adb) eq not { + ( **** Error: Failed to decrypt Perms string.\n) pdfformaterror + ( Cannot decrypt PDF file.\n) pdfformaterror + printProducer + /pdf_check_r5_password cvx /rangecheck signalerror + } if + } if + + end +} bind def + +% <password> pdf_check_password <filekey> true +% <password> pdf_check_password false +/pdf_check_password { + % If R is 2, 3, or 4, use Algorithms 3.6 and 3.7 to see if this is + % a valid user or owner password. Following historical practice, + % we treat the password as an arbitrary string of bytes and don't + % interpret it in any way. (If the password fails, it would be + % nice to try some plausible character set conversions, but this + % gets complicated. Even Adobe products don't seem to handle it + % consistently.) + % + % If R is 5, use Algorithm 3.2a. The password should be text, in + % either UTF-8 or the current locale's charset. + + Trailer /Encrypt oget /R oget + + dup dup 2 ge exch 4 le and { + pop + dup pdf_check_pre_r5_user_password { + exch pop //true + } { + pdf_check_pre_r5_owner_password + } ifelse + } { + dup 5 eq { + pop + % First, try the password as UTF-8. + dup pdf_check_r5_password { + exch pop //true + } { + % The password didn't work as UTF-8, so maybe it's in the + % locale character set instead. If possible, convert it to + % UTF-8 and try again. + /.locale_to_utf8 where { + pop .locale_to_utf8 pdf_check_r5_password + } { + pop //false + } ifelse + } ifelse + } { + dup 6 eq { + pop + % First, try the password as UTF-8. + dup Trailer /Encrypt oget check_r6_password { + exch pop //true + } { + % The password didn't work as UTF-8, so maybe it's in the + % locale character set instead. If possible, convert it to + % UTF-8 and try again. + /.locale_to_utf8 where { + pop .locale_to_utf8 Trailer /Encrypt oget check_r6_password + } { + pop //false + } ifelse + } ifelse + } { + ( **** Warning: This file uses an unknown standard security handler revision: ) + exch =string cvs concatstrings (\n) concatstrings pdfformatwarning + ( Cannot decrypt PDF file.\n) pdfformaterror + printProducer + /pdf_check_password cvx /undefined signalerror + } ifelse + } ifelse + } ifelse +} bind def + +% Process the encryption information in the Trailer. +/pdf_process_Encrypt { + Trailer /Encrypt oget + /Filter oget /Standard eq not { + ( **** Warning: This file uses an unknown security handler.\n) pdfformatwarning + ( Cannot decrypt PDF file.\n) pdfformaterror + printProducer + /pdf_process_Encrypt cvx /undefined signalerror + } if + () pdf_check_password + { + /FileKey exch def + } { + /PDFPassword where { + pop PDFPassword pdf_check_password + { + /FileKey exch def + } { + ( **** Error: Password did not work.\n) pdfformaterror + ( Cannot decrypt PDF file.\n) pdfformaterror + + % If ghostscript was built without libidn, it's missing the + % .saslprep operator and thus can't do proper Unicode password + % normalization. Similarly, if the system provides neither + % iconv nor the Windows MultiByteToWideChar function, then we + % won't have the .locale_to_utf8 operator to convert passwords + % from the locale character set to UTF-8. + % + % It's not a huge problem if you're missing either or both of + % these. ASCII passwords will work fine regardless, and even + % Unicode passwords will often be okay. + % + % However, if .saslprep or .locale_to_utf8 is missing, and the + % user enters a non-ASCII password that doesn't work, we give + % a warning message. + PDFPassword contains_non_ascii { + /.saslprep where not { + ( **** WARNING: Ghostscript was configured without libidn,\n) + ( **** so non-ASCII passwords aren't supported!\n) + concatstrings pdfformaterror + } { + pop + /.locale_to_utf8 where not { + ( **** WARNING: Ghostscript was configured without iconv,\n) + ( **** so non-ASCII passwords aren't supported!\n) + concatstrings pdfformaterror + } { + pop + } ifelse + } ifelse + } if + + /pdf_process_Encrypt cvx /invalidfileaccess signalerror + } ifelse + } { + ( **** This file requires a password for access.\n) pdfformaterror + /pdf_process_Encrypt cvx /invalidfileaccess signalerror + } ifelse + } ifelse + +% Trailer /Encrypt oget /P oget 4 and 0 eq #? and +% { ( ****This owner of this file has requested you do not print it.\n) +% pdfformaterror printProducer +% /pdf_process_Encrypt cvx /invalidfileaccess signalerror +% } +% if +} bind def + +% Calculate the key used to decrypt an object (to pass to .decpdfrun or +% put into a stream dictionary). +/computeobjkey % <object#> <generation#> computeobjkey <keystring> +{ + Trailer /Encrypt oget /V oget 5 eq { + % Encrypt version 5 doesn't use object keys; everything is + % encrypted with the file key. + pop pop FileKey + } { + exch + FileKey length 5 add string + dup 0 FileKey putinterval + exch + % stack: gen# string obj# + 2 copy 255 and FileKey length exch put + 2 copy -8 bitshift 255 and FileKey length 1 add exch put + 2 copy -16 bitshift 255 and FileKey length 2 add exch put + pop exch + 2 copy 255 and FileKey length 3 add exch put + 2 copy -8 bitshift 255 and FileKey length 4 add exch put + pop + % this step is for the AES cipher only + Trailer /Encrypt oget + dup /StmF knownoget { + %% Treat StmF of 'Identity' the same as if it is missing. + dup /Identity eq { + pop pop + } { + exch /CF knownoget { + exch oget /CFM oget /AESV2 eq { + (sAlT) concatstrings + } if + } { + pop + } ifelse + } ifelse + } { + pop + } ifelse + md5 0 FileKey length 5 add 2 index length .min getinterval + } ifelse +} bind def + +% As .pdfrun, but decrypt strings with key <key>. +/PDFScanRules_true << /PDFScanRules //true >> def +/PDFScanRules_null << /PDFScanRules //null >> def +/.decpdfrun % <file> <keystring> <opdict> .decpdfrun - + { % Construct a procedure with the file, opdict and key bound into it. + 2 index cvlit mark + /PDFScanRules .getuserparam //null eq { + //PDFScanRules_true { setuserparams } 0 get % force PDF scanning mode + mark 7 4 roll + } { + mark 5 2 roll + } ifelse + { .pdftoken not { (%%EOF) cvn cvx } if + dup xcheck + { PDFDEBUG { dup //== exec flush } if + 3 -1 roll pop + 2 copy .knownget + { exch pop exch pop exec + } + { exch pop + dup /true eq + { pop //true + } + { dup /false eq + { pop //false + } + { dup /null eq + { pop //null + } + { ( **** Error: Unknown operator: ) + exch =string cvs concatstrings (\n) concatstrings + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } + ifelse + } + ifelse + } + ifelse + } + ifelse + } + { exch pop PDFDEBUG { dup ==only ( ) print flush } if + dup type /stringtype eq + { + % Check if we have encrypted strings R>=4 allows for + % selection of encryption on streams and strings + Trailer /Encrypt oget % Get encryption dictionary + dup /R oget 4 lt % only >=4 has selectable + { % R < 4 --> arc4 strings + pop 1 index arc4decode % Decrypt string + PDFDEBUG { (%Decrypted: ) print dup //== exec flush } if + } { % Else R >= 4 + /StrF knownoget % Get StrF (if present) + { % If StrF is present ... + dup /Identity eq not % Check if StrF != Identity + { /StdCF eq + { Trailer /Encrypt oget /CF knownoget { + /StdCF oget /CFM oget + dup /AESV2 eq exch /AESV3 eq or + } { + //false + } ifelse { % Decrypt string + 1 index aesdecode + } { + 1 index arc4decode + } ifelse + } + { 1 index arc4decode } + ifelse % If StrF != StdCF + PDFDEBUG { (%Decrypted: ) print dup //== exec flush } if + } + { pop } + ifelse % If StrF != identity + } + if % If StrF is known + } + ifelse % Ifelse R < 4 + } { + dup type /nametype eq { + .pdffixname + } if + } + ifelse + exch pop + } + ifelse + } + aload pop .packtomark cvx + { loop } 0 get 2 packedarray cvx + { stopped } 0 get + /PDFScanRules .getuserparam //null eq { + //PDFScanRules_null { setuserparams } 0 get % reset PDF scannig mode if it was off + } if + /PDFsource PDFsource + { store { stop } if } aload pop .packtomark cvx + /PDFsource 3 -1 roll store exec + } bind def +currentdict /PDFScanRules_true undef +currentdict /PDFScanRules_null undef + +% Run the code to resolve an object reference. +/pdf_run_resolve +{ /FileKey where % Check if the file is encrypted + { pop % File is encrypted + 2 copy computeobjkey dup 4 1 roll + PDFfile exch resolveopdict .decpdfrun + dup dup dup 5 2 roll + % stack: object object key object object + { % Use loop to provide an exitable context. + xcheck exch type /dicttype eq and % Check if executable dictionary + not { % If object is not ... + pop pop % ignore object + exit % Exit 'loop' context + } if % If not possible stream + % Starting with PDF 1.4 (R = 3), there are some extra features + % which control encryption of streams. The EncryptMetadata entry + % in the Encrypt dict controls the encryption of metadata streams. + Trailer /Encrypt oget % Get encryption dictionary + dup /R oget dup 3 lt % Only PDF 1.4 and higher has options + { % R < 3 --> all streams encrypted + pop pop /StreamKey exch put % Insert StreamKey in dictionary + exit % Exit 'loop' context + } if + % Check EncryptMeta. stack: object object key Encrypt R + exch dup /EncryptMetadata knownoget % Get EncryptMetadata (if present) + not { //true } if % If not present default = true + not % Check if EncryptMetadata = false + { % if false we need to check the stream type + 3 index /Type knownoget % Get stream type (if present) + not { //null } if % If type not present use fake name + /Metadata eq % Check if the type is Metadata + { pop pop pop pop % Type == Metadata --> no encryption + exit % Exit 'loop' context + } if + } if + % PDF 1.5 encryption (R == 4) has selectable encryption handlers. If + % this is not PDF 1.5 encryption (R < 4) then we are done checking and + % we need to decrypt the stream. stack: object object key R Encrypt + exch 4 lt % Check for less than PDF 1.5 + { pop /StreamKey exch put % Insert StreamKey in dictionary + exit % Exit 'loop' context + } if + % Check if the stream encryption handler (StmF) == Identity. + PDFDEBUG { + Trailer /Encrypt oget /CF knownoget { + /StdCF oget /CFM oget + (Encrypt StmF is StdCF with CFM ) print = + } if + } if + /StmF knownoget % Get StmF (if present) + not { /Identity } if % If StmF not present default = Identity + /Identity eq % Check if StmF == Identity + { pop pop % Identity --> no encryption + exit % Exit 'loop' context + } if + % If we get here then we need to decrypt the stream. + /StreamKey exch put % Insert StreamKey into dictionary + exit % Exit 'loop' context, never loop + } loop % End of loop exitable context + } { % Else file is not encrypted + PDFfile resolveopdict .pdfrun + } ifelse % Ifelse encrypted +} bind def + +% Prefix a decryption filter to a stream if needed. +% Stack: readdata? dict parms file/string filternames +% (both before and after). +/pdf_decrypt_stream + { 3 index /StreamKey known % Check if the file is encrypted + { + exch + % Stack: readdata? dict parms filternames file/string + 3 index /StreamKey get + Trailer /Encrypt oget + dup /StmF knownoget + { % stack: key Encrypt StmF + exch /CF knownoget { + exch oget /CFM oget % stack: key StmF-CFM + dup /AESV2 eq exch /AESV3 eq or + } { pop //false } ifelse + { aesdecodefilter } % install the requested filter + { arc4decodefilter } + ifelse + } + { pop arc4decodefilter } % fallback for no StmF + ifelse + exch + } if + } bind def + +end % pdfdict +.setglobal diff --git a/Master/tlpkg/tlgs/Resource/Init/xlatmap b/Master/tlpkg/tlgs/Resource/Init/xlatmap new file mode 100644 index 00000000000..1d52f623e1a --- /dev/null +++ b/Master/tlpkg/tlgs/Resource/Init/xlatmap @@ -0,0 +1,49 @@ +% xlatmap - the map of translation tables for various kinds of fonts. +% +% It specifies Decoding resources to be used with FAPI-handled fonts. +% If a font contains multiple character mapping tables, this gives +% priorities for choosing a specific table from the font according to +% the order of entries of this map. + +% This file is intended to be customized by users. Please keep the +% obvious format of this file. Strings and names must not be empty +% and must not contain null ('\0') characters. + + +% The map contains entries for each kind of font being handled by +% any font rendering plugin. The key of an entry is the font type +% and the value is array of pairs. +% The first element of pair is a string which encodes identifier of +% character mapping table. The format of the first element depends +% on the font type, and should be recognized by the font rendering +% plugins. The second element is name of the Decoding resource. If +% that resource is not available, definefont will fail. Note that +% currently we supply insufficient decoding resources, as well as +% insufficient entries in this map. + +/TrueType +[ % Each entry is pair : + % a string PlatformID.SpecificID and a name of Decoding resource. + (3.0) /Symbol % Symbol + (3.1) /Unicode % Unicode + (3.2) /ShiftJIS % Japanese + (3.3) /PRC % Simplified Chinese, GB2312 + (3.4) /Big5 % Traditional Chinese + (3.5) /Wansung % Korean + (3.6) /Johab % Korean + (3.10) /UCS-4 % UCS-4 + % todo : add more entries +] + +/PostScript +[ % Since PostScript fonts were designed especially for PostScript, + (*) /Unicode % fixme : other charsets +] + +/Intellifont +[ (*) /FCO_Unicode % fixme : other charsets +] + +/Microtype +[ (*) /FCO_Unicode % FCOfontmap may may overwrite this for a specific font. +] |