2 |
- |
1 |
% Copyright (C) 1994, 2000 Aladdin Enterprises. All rights reserved.
|
|
|
2 |
%
|
|
|
3 |
% This software is provided AS-IS with no warranty, either express or
|
|
|
4 |
% implied.
|
|
|
5 |
%
|
|
|
6 |
% This software is distributed under license and may not be copied,
|
|
|
7 |
% modified or distributed except as expressly authorized under the terms
|
|
|
8 |
% of the license contained in the file LICENSE in this distribution.
|
|
|
9 |
%
|
|
|
10 |
% For more information about licensing, please refer to
|
|
|
11 |
% http://www.ghostscript.com/licensing/. For information on
|
|
|
12 |
% commercial licensing, go to http://www.artifex.com/licensing/ or
|
|
|
13 |
% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
|
|
|
14 |
% San Rafael, CA 94903, U.S.A., +1(415)492-9861.
|
|
|
15 |
|
|
|
16 |
% $Id: pdf_font.ps,v 1.80 2005/09/29 15:24:53 leonardo Exp $
|
|
|
17 |
% PDF font operations.
|
|
|
18 |
|
|
|
19 |
% Finding a font by name can't give a proper result when PDF font names aren't unique.
|
|
|
20 |
% But it is only the way to obtain a font in Postscript after a font file is executed.
|
|
|
21 |
% Therefore using a FontName (and findfont) is allowed only
|
|
|
22 |
% immediately after a font file is executed.
|
|
|
23 |
% In all other cases the font to be found by a pointer through PDF structures.
|
|
|
24 |
%
|
|
|
25 |
% This ideal logics can't work for documents,
|
|
|
26 |
% which define a font resource with an embedded font,
|
|
|
27 |
% and another font resource with same BaseFont but with no embedded font
|
|
|
28 |
% (and possibly with no font descriptor).
|
|
|
29 |
% Our testbase does contain such examples.
|
|
|
30 |
% In this case we do find font by FontName (with findfont),
|
|
|
31 |
% since there is no other way to get a reasonable result.
|
|
|
32 |
|
|
|
33 |
/.setlanguagelevel where { pop 2 .setlanguagelevel } if
|
|
|
34 |
.currentglobal true .setglobal
|
|
|
35 |
/pdfdict where { pop } { /pdfdict 100 dict def } ifelse
|
|
|
36 |
GS_PDF_ProcSet begin
|
|
|
37 |
pdfdict begin
|
|
|
38 |
|
|
|
39 |
% We cache the PostScript font in an additional element of the
|
|
|
40 |
% font resource dictionary, called PSFont.
|
|
|
41 |
|
|
|
42 |
% ---------------- Encodings ---------------- %
|
|
|
43 |
|
|
|
44 |
/.notdefEncoding 256 { /.notdef } repeat 256 packedarray def
|
|
|
45 |
|
|
|
46 |
% Apply a list of differences to an Encoding.
|
|
|
47 |
% Note that the differences may cause the array to grow.
|
|
|
48 |
/updateencoding { % <encoding|null> <differences> updateencoding <enc'>
|
|
|
49 |
% Calculate the length of the result.
|
|
|
50 |
% in case the incoming Encoding is null, use .notdefEncoding
|
|
|
51 |
exch dup null eq { pop .notdefEncoding } if
|
|
|
52 |
|
|
|
53 |
dup type /nametype ne { exch pop oforce } { pop 1 add } ifelse
|
|
|
54 |
% Differences list may not be in order, update the largest_index
|
|
|
55 |
% stack: <Differences> <encoding> <largest_index> <at_index>
|
|
|
56 |
2 copy lt { exch pop dup } if % at_index is new largest
|
|
|
57 |
} forall
|
|
|
58 |
pop 1 index length .max array dup 0 4 -1 roll putinterval
|
|
|
59 |
exch 0 exch {
|
|
|
60 |
% Stack: enc' code element
|
|
|
61 |
dup type /nametype ne
|
|
|
62 |
{ exch pop oforce }
|
|
|
63 |
{ 3 copy put pop 1 add }
|
|
|
64 |
ifelse
|
|
|
65 |
} forall pop
|
|
|
66 |
} bdef
|
|
|
67 |
|
|
|
68 |
% Get the Encoding for a font.
|
|
|
69 |
/getencoding % <base-encoding> <font-resource> getencoding <enc>
|
|
|
70 |
{ /Encoding knownoget
|
|
|
71 |
{ dup type /nametype eq
|
|
|
72 |
{
|
|
|
73 |
% The published PDF specification says the Encoding name
|
|
|
74 |
% "must be" one of the 3 predefined Encodings, implying
|
|
|
75 |
% that an error should occur if it isn't. However, Acrobat
|
|
|
76 |
% Reader simply ignores unknown names, and since there are
|
|
|
77 |
% some buggy applications that rely on this, we do the same.
|
|
|
78 |
|
|
|
79 |
dup dup dup /MacRomanEncoding eq
|
|
|
80 |
exch /MacExpertEncoding eq or
|
|
|
81 |
exch /WinAnsiEncoding eq or
|
|
|
82 |
{ exch pop findencoding
|
|
|
83 |
}
|
|
|
84 |
{ pop
|
|
|
85 |
}
|
|
|
86 |
ifelse
|
|
|
87 |
}
|
|
|
88 |
{ dup /BaseEncoding knownoget
|
|
|
89 |
{
|
|
|
90 |
dup / eq
|
|
|
91 |
{ pop
|
|
|
92 |
( **** Warning: Ignoring bad BaseEncoding name.\n) pdfformaterror
|
|
|
93 |
% as found in a PDF file from J.D.Edwards OneWorld (B7333), bug 687786
|
|
|
94 |
}
|
|
|
95 |
{
|
|
|
96 |
findencoding 3 -1 roll pop exch
|
|
|
97 |
}
|
|
|
98 |
ifelse
|
|
|
99 |
}
|
|
|
100 |
if
|
|
|
101 |
/Differences knownoget { updateencoding } if
|
|
|
102 |
}
|
|
|
103 |
ifelse
|
|
|
104 |
}
|
|
|
105 |
if
|
|
|
106 |
} bdef
|
|
|
107 |
|
|
|
108 |
/checkGlyphNames2Unicode % <dict> checkGlyphNames2Unicode -
|
|
|
109 |
{
|
|
|
110 |
PDFDEBUG {
|
|
|
111 |
dup /FontInfo .knownget {
|
|
|
112 |
/GlyphNames2Unicode .knownget {
|
|
|
113 |
(Has GlyphNames2Unicode) =
|
|
|
114 |
pop % { exch == ==} forall
|
|
|
115 |
} if
|
|
|
116 |
} if
|
|
|
117 |
} if
|
|
|
118 |
pop
|
|
|
119 |
} bind def
|
|
|
120 |
|
|
|
121 |
% Define a font using it's FontName as the key.
|
|
|
122 |
% Adjust a font according to the Encoding and Widths in the font resource.
|
|
|
123 |
/adjustfont { % <font-resource> <font> adjustfont <font'>
|
|
|
124 |
getfontencoding
|
|
|
125 |
3 copy .processToUnicode
|
|
|
126 |
getfontmetrics 5 -1 roll pop .updatefont { dup /FontName get exch definefont } if
|
|
|
127 |
} bind def
|
|
|
128 |
|
|
|
129 |
% Get the (possibly modified) encoding of a font.
|
|
|
130 |
/getfontencoding { % <font-resource> <font> getfontencoding
|
|
|
131 |
% <font-resource> <font> <Encoding|null>
|
|
|
132 |
1 index /Encoding known {
|
|
|
133 |
dup /Encoding knownoget { 2 index getencoding } { null } ifelse
|
|
|
134 |
} {
|
|
|
135 |
null
|
|
|
136 |
} ifelse
|
|
|
137 |
} bdef
|
|
|
138 |
|
|
|
139 |
% Returns true if the current glyph is in the Differences array at
|
|
|
140 |
% the specified index value. This is needed because the Widths
|
|
|
141 |
% array may map to the same glyph at different positions from the
|
|
|
142 |
% Encoding. We want to use the Width that was associated with the
|
|
|
143 |
% one specified in the Encoding::Differences list.
|
|
|
144 |
/match_in_diff % <Differences> <index> <glyphname> match_in_diff <bool>
|
|
|
145 |
{ false 4 1 roll 0 4 -1 roll % stack: false index glyphname at_index==0 Differences
|
|
|
146 |
{ exch 1 index type /nametype ne {
|
|
|
147 |
% stack: false index glyphname Diff_element at_index
|
|
|
148 |
pop % Diff_element is new at_index
|
|
|
149 |
} {
|
|
|
150 |
% stack: false index glyphname Diff_element at_index
|
|
|
151 |
exch 2 index eq {
|
|
|
152 |
% stack: false index glyphname at_index
|
|
|
153 |
dup 3 index eq {
|
|
|
154 |
true 5 1 roll % stack: true false index glyphname at_index
|
|
|
155 |
pop exit
|
|
|
156 |
} if
|
|
|
157 |
} if
|
|
|
158 |
1 add % at_index++ stack: false index glyphname at_index'
|
|
|
159 |
} ifelse
|
|
|
160 |
} forall
|
|
|
161 |
% stack: true false index glyphname
|
|
|
162 |
% or : false index glyphname at_index
|
|
|
163 |
pop pop pop
|
|
|
164 |
} bdef
|
|
|
165 |
|
|
|
166 |
/unique_name { % <dict> </root> unique_name </unique>
|
|
|
167 |
%
|
|
|
168 |
% Note : this function interacts with pdf_write_encoding in src/gdevpdtw.c
|
|
|
169 |
% and with copied_drop_extension_glyphs in src\gxfcopy.c
|
|
|
170 |
% by adding a reserved substring (~GS~).
|
|
|
171 |
%
|
|
|
172 |
.namestring % <<>> (root)
|
|
|
173 |
|
|
|
174 |
5 string cvs % <<>> (root) (0)
|
|
|
175 |
(~GS~) exch concatstrings
|
|
|
176 |
1 index exch % <<>> (root) (root) (~GS~0)
|
|
|
177 |
concatstrings % <<>> (root) (root~GS~0)
|
|
|
178 |
dup % <<>> (root) (root~GS~0) (root~GS~0)
|
|
|
179 |
3 index exch % <<>> (root) (root~GS~0) <<>> (root~GS~0)
|
|
|
180 |
known not {
|
|
|
181 |
exch pop exit % <<>> (root~GS~0)
|
|
|
182 |
} if
|
|
|
183 |
pop
|
|
|
184 |
} for
|
|
|
185 |
exch pop cvn % /root0
|
|
|
186 |
} bdef
|
|
|
187 |
|
|
|
188 |
% Get the metrics of a font, if specified.
|
|
|
189 |
/getfontmetrics { % <font-resource> <font> <Encoding|null> getfontmetrics
|
|
|
190 |
% <font-resource> <font> <Encoding|null>
|
|
|
191 |
% <Metrics|null> <GlyphMap|null>
|
|
|
192 |
2 index /Widths known {
|
|
|
193 |
dup null eq { pop dup /Encoding get } if
|
|
|
194 |
4 dict begin
|
|
|
195 |
dup length dict
|
|
|
196 |
/Metrics exch def
|
|
|
197 |
/Encoding exch def
|
|
|
198 |
/GlyphMap //null def
|
|
|
199 |
exch
|
|
|
200 |
dup /Widths oget /Widths exch def
|
|
|
201 |
% Stack: font font-res
|
|
|
202 |
% Note that widths are always based on a 1000-unit
|
|
|
203 |
% character space, but the FontMatrix may specify
|
|
|
204 |
% some other scale factor. Compensate for this here,
|
|
|
205 |
% by scaling the Widths if necessary.
|
|
|
206 |
0.001 2 index /FontMatrix get 0 get div
|
|
|
207 |
% Stack: font font-res mscale
|
|
|
208 |
1 index /FirstChar oget dup 1 4 index /LastChar oget
|
|
|
209 |
{ % Stack: font font-res mscale first-char index
|
|
|
210 |
Encoding 1 index dup 2 index length ge {
|
|
|
211 |
( **** Warning: Font Encoding array size is smaller than character range.\n)
|
|
|
212 |
pdfformaterror
|
|
|
213 |
pop pop /.notdef
|
|
|
214 |
} {
|
|
|
215 |
get
|
|
|
216 |
} ifelse
|
|
|
217 |
Widths 2 index 4 index sub dup 2 index length ge {
|
|
|
218 |
( **** Warning: Font Widths array size is smaller than character range.\n)
|
|
|
219 |
pdfformaterror
|
|
|
220 |
% use MissingWidth if it's available, if not, default to 1000 (full width)
|
|
|
221 |
pop pop 4 index /FontDescriptor knownoget {
|
|
|
222 |
/MissingWidth knownoget not { 1000 } if
|
|
|
223 |
} { 1000 } ifelse
|
|
|
224 |
} {
|
|
|
225 |
oget
|
|
|
226 |
} ifelse
|
|
|
227 |
% Stack: font font-res mscale first-char index charname width
|
|
|
228 |
4 index mul
|
|
|
229 |
% The following 'loop' is only context for 'exit'.
|
|
|
230 |
{
|
|
|
231 |
% Work around a bug in pdfTeX, which can generate Encoding
|
|
|
232 |
% vectors containing nulls :
|
|
|
233 |
1 index //null eq { exit } if
|
|
|
234 |
Metrics 2 index .knownget {
|
|
|
235 |
1 index ne
|
|
|
236 |
} {
|
|
|
237 |
//false
|
|
|
238 |
} ifelse {
|
|
|
239 |
% Two or more Encoding elements refer same glyph name,
|
|
|
240 |
% and Widths specify different wihts for it.
|
|
|
241 |
% Since a Postscript font can't have different
|
|
|
242 |
% Metrics for same glyph name,
|
|
|
243 |
% we generate an unique name, and create a new
|
|
|
244 |
% Charstrings entry with same glyph value.
|
|
|
245 |
GlyphMap //null eq {
|
|
|
246 |
/Encoding Encoding dup length array copy def
|
|
|
247 |
/GlyphMap 4 dict def
|
|
|
248 |
} if
|
|
|
249 |
% To prevent too many new names, check whether
|
|
|
250 |
% we can use one already created for same glyph.
|
|
|
251 |
//true
|
|
|
252 |
GlyphMap { % f r s c i n w b n1 n2
|
|
|
253 |
4 index eq { % f r s c i n w b n1
|
|
|
254 |
dup Metrics exch get % f r s c i n w b n1 w1
|
|
|
255 |
3 index eq { % f r s c i n w b n1
|
|
|
256 |
4 3 roll pop % f r s c i w b n1
|
|
|
257 |
3 1 roll pop % f r s c i n1 w
|
|
|
258 |
Encoding 3 index 3 index put
|
|
|
259 |
//false % f r s c i n1 w b
|
|
|
260 |
exit
|
|
|
261 |
} {
|
|
|
262 |
pop
|
|
|
263 |
} ifelse
|
|
|
264 |
} { % f r s c i n w b n1
|
|
|
265 |
pop
|
|
|
266 |
} ifelse
|
|
|
267 |
} forall % f r s c i n w b
|
|
|
268 |
{ % Do create a new name.
|
|
|
269 |
Metrics 2 index //unique_name exec % f r s c i n w nn
|
|
|
270 |
Encoding 4 index 2 index put
|
|
|
271 |
GlyphMap 1 index 5 -1 roll put % f r s c i w nn
|
|
|
272 |
exch
|
|
|
273 |
% Stack: font font-res mscale first-char index new_name width
|
|
|
274 |
} if
|
|
|
275 |
} if
|
|
|
276 |
2 copy Metrics 3 1 roll put
|
|
|
277 |
exit
|
|
|
278 |
} loop
|
|
|
279 |
pop pop pop
|
|
|
280 |
}
|
|
|
281 |
for pop
|
|
|
282 |
% Now fill in the MissingWidth for any encoded characters
|
|
|
283 |
% that aren't in Metrics already. Note that built-in
|
|
|
284 |
% fonts may have Widths/FirstChar/LastChar but no
|
|
|
285 |
% FontDescriptor, so we must check for this.
|
|
|
286 |
% Stack: font font-res mscale
|
|
|
287 |
1 index /FontDescriptor knownoget {
|
|
|
288 |
Metrics exch
|
|
|
289 |
/MissingWidth knownoget { 2 index mul } { 0 } ifelse exch
|
|
|
290 |
Encoding {
|
|
|
291 |
% Stack: font font-res mscale missing-width metrics charname
|
|
|
292 |
% Work around the abovementioned pdfTeX bug.
|
|
|
293 |
dup //null ne {
|
|
|
294 |
2 copy known not { 2 copy 4 index put } if pop
|
|
|
295 |
} {
|
|
|
296 |
pop
|
|
|
297 |
} ifelse
|
|
|
298 |
} forall pop pop pop
|
|
|
299 |
} {
|
|
|
300 |
pop
|
|
|
301 |
} ifelse
|
|
|
302 |
exch Encoding Metrics GlyphMap end
|
|
|
303 |
} {
|
|
|
304 |
//null //null
|
|
|
305 |
} ifelse
|
|
|
306 |
} bdef
|
|
|
307 |
|
|
|
308 |
currentdict /unique_name undef
|
|
|
309 |
currentdict /match_in_diff undef
|
|
|
310 |
|
|
|
311 |
/ToUnicodeCMapReader 3 dict def
|
|
|
312 |
//ToUnicodeCMapReader begin
|
|
|
313 |
/defineresource % <name> <dict> <cat-name> defineresource <dict>
|
|
|
314 |
{
|
|
|
315 |
pop
|
|
|
316 |
dup userdict exch /.lastToUnicode exch put
|
|
|
317 |
exch pop
|
|
|
318 |
} bind def
|
|
|
319 |
/CIDSystemInfo
|
|
|
320 |
{
|
|
|
321 |
( **** Warning: ToUnicode CMap has invalid syntax near CIDSystemInfo.\n) pdfformaterror
|
|
|
322 |
/CIDSystemInfo
|
|
|
323 |
} bind def % A work around a bug in Altona.Page_3.2002-09-27.pdf - a slash is missed.
|
|
|
324 |
end
|
|
|
325 |
|
|
|
326 |
/string2number % <string> string2number <number>
|
|
|
327 |
{ 0 exch dup 0 exch 1 exch length 1 sub { % n () i
|
|
|
328 |
1 index exch get % n () v
|
|
|
329 |
3 2 roll 256 mul add exch % v+n*256 ()
|
|
|
330 |
} for
|
|
|
331 |
pop % N
|
|
|
332 |
} bind def
|
|
|
333 |
|
|
|
334 |
/copy&def % <key> <value> <bool> copy&def -
|
|
|
335 |
{
|
|
|
336 |
{ true
|
|
|
337 |
} {
|
|
|
338 |
currentdict gcheck {
|
|
|
339 |
dup gcheck not
|
|
|
340 |
} {
|
|
|
341 |
false
|
|
|
342 |
} ifelse
|
|
|
343 |
} ifelse
|
|
|
344 |
{ currentglobal currentdict gcheck setglobal
|
|
|
345 |
exch dup length string copy exch
|
|
|
346 |
setglobal
|
|
|
347 |
} if
|
|
|
348 |
def
|
|
|
349 |
} bind def
|
|
|
350 |
|
|
|
351 |
/.convert_ToUnicode-into-g2u % <GlyphNames2Unicode> <Encoding|null> <CMap> .convert_ToUnicode-into-g2u -
|
|
|
352 |
{
|
|
|
353 |
PDFDEBUG {
|
|
|
354 |
(.convert_ToUnicode-into-g2u beg) =
|
|
|
355 |
} if
|
|
|
356 |
3 2 roll begin
|
|
|
357 |
/.CodeMapData get % About the data format see gs_cmap.ps, the comment after "CMap operators".
|
|
|
358 |
1 get % code maps
|
|
|
359 |
{
|
|
|
360 |
PDFDEBUG {
|
|
|
361 |
dup ==
|
|
|
362 |
} if
|
|
|
363 |
dup length 1 sub 0 exch 5 exch { % e [] i
|
|
|
364 |
2 copy get % e [] i (prefix)
|
|
|
365 |
string2number % e [] i prefix
|
|
|
366 |
2 index 2 index 1 add get % e [] i prefix (key_size,?is_range,value_type,value_size)
|
|
|
367 |
dup 0 get 8 mul % e [] i prefix (key_size,?is_range,value_type,value_size) key_size*8
|
|
|
368 |
3 2 roll exch bitshift exch % e [] i prefix<<key_size*8 (key_size,?is_range,value_type,value_size)
|
|
|
369 |
dup 0 get exch 3 get % e [] i offset key_size value_size
|
|
|
370 |
4 index 4 index 2 add get % e [] i offset key_size value_size (keys)
|
|
|
371 |
5 index 5 index 3 add get % e [] i offset key_size value_size (keys) (values)
|
|
|
372 |
PDFDEBUG {
|
|
|
373 |
( offset=) print 4 index =string cvs print
|
|
|
374 |
( key_size=) print 3 index =string cvs print
|
|
|
375 |
( value_size=) print 2 index =
|
|
|
376 |
( keys=) print 1 index ==
|
|
|
377 |
( values=) print dup ==
|
|
|
378 |
} if
|
|
|
379 |
1 index length 0 eq {
|
|
|
380 |
% A single pair.
|
|
|
381 |
exch pop exch pop exch pop exch % e [] i (values) offset
|
|
|
382 |
4 index null ne {
|
|
|
383 |
4 index exch get
|
|
|
384 |
} if % e [] i (values) cid|name
|
|
|
385 |
exch
|
|
|
386 |
PDFDEBUG {
|
|
|
387 |
( defined single: ) print 1 index =string cvs print ( ) print dup ==
|
|
|
388 |
} if
|
|
|
389 |
false copy&def % e [] i
|
|
|
390 |
pop % e []
|
|
|
391 |
} {
|
|
|
392 |
% A range. % e [] i offset key_size value_size (keys) (values)
|
|
|
393 |
dup length string copy % protect the original string from modifications below.
|
|
|
394 |
|
|
|
395 |
2 index 1 index 6 index getinterval
|
|
|
396 |
string2number % e [] i offset key_size value_size (keys) (values) j keyL
|
|
|
397 |
PDFDEBUG {
|
|
|
398 |
( keyL=) print dup =string cvs print
|
|
|
399 |
} if
|
|
|
400 |
3 index 2 index 7 index add 7 index getinterval
|
|
|
401 |
string2number % e [] i offset key_size value_size (keys) (values) j keyL keyH
|
|
|
402 |
PDFDEBUG {
|
|
|
403 |
( keyH=) print dup =
|
|
|
404 |
} if
|
|
|
405 |
3 2 roll 6 index idiv 5 index mul % e [] i offset key_size value_size (keys) (values) keyL keyH J
|
|
|
406 |
3 index exch 6 index getinterval % e [] i offset key_size value_size (keys) (values) keyL keyH (valueL)
|
|
|
407 |
3 1 roll 1 exch { % e [] i offset key_size value_size (keys) (values) (value) k
|
|
|
408 |
9 index null ne {
|
|
|
409 |
9 index exch get % e [] i offset key_size value_size (keys) (values) (value) name
|
|
|
410 |
} if % e [] i offset key_size value_size (keys) (values) (value) cid|name
|
|
|
411 |
1 index % e [] i offset key_size value_size (keys) (values) (value) cid|name (value)
|
|
|
412 |
PDFDEBUG {
|
|
|
413 |
( defined from range: ) print 1 index =string cvs print ( ) print dup ==
|
|
|
414 |
} if
|
|
|
415 |
true copy&def % e [] i offset key_size value_size (keys) (values) (value)
|
|
|
416 |
% Assuming the lowest byte of 'value' changes, others don't.
|
|
|
417 |
dup dup length 1 sub % e [] i offset key_size value_size (keys) (values) (value) (value) l
|
|
|
418 |
2 copy get % e [] i offset key_size value_size (keys) (values) (value) (value) l v
|
|
|
419 |
1 add put % e [] i offset key_size value_size (keys) (values) (value')
|
|
|
420 |
} for % e [] i offset key_size value_size (keys) (values) (value)
|
|
|
421 |
} for
|
|
|
422 |
pop pop pop pop pop pop pop % e []
|
|
|
423 |
} ifelse
|
|
|
424 |
} for
|
|
|
425 |
pop % e
|
|
|
426 |
} forall
|
|
|
427 |
end
|
|
|
428 |
pop %
|
|
|
429 |
PDFDEBUG {
|
|
|
430 |
(.convert_ToUnicode-into-g2u end) =
|
|
|
431 |
} if
|
|
|
432 |
} bind def
|
|
|
433 |
|
|
|
434 |
/.processToUnicode % <font-resource> <font-dict> <encoding|null> .processToUnicode -
|
|
|
435 |
{
|
|
|
436 |
% Currently pdfwrite is only device which can handle GlyphNames2Unicoide to
|
|
|
437 |
% generate a ToUnicode CMaps. So don't bother with other devices.
|
|
|
438 |
currentdevice .devicename /pdfwrite eq {
|
|
|
439 |
PDFDEBUG {
|
|
|
440 |
(.processToUnicode beg) =
|
|
|
441 |
} if
|
|
|
442 |
2 index /ToUnicode knownoget {
|
|
|
443 |
dup type /nametype eq {
|
|
|
444 |
% Bug687351.pdf defines /ToUnicode /Identity-H, what is incorrect.
|
|
|
445 |
( **** Warning: Ignoring bad ToUnicode CMap.\n) pdfformaterror
|
|
|
446 |
pop
|
|
|
447 |
} {
|
|
|
448 |
PDFfile fileposition exch
|
|
|
449 |
false resolvestream
|
|
|
450 |
//ToUnicodeCMapReader begin
|
|
|
451 |
cvx exec
|
|
|
452 |
end
|
|
|
453 |
PDFfile exch setfileposition
|
|
|
454 |
1 index /FontInfo .knownget not {
|
|
|
455 |
1 index /FontInfo 5 dict dup 4 1 roll put
|
|
|
456 |
} if
|
|
|
457 |
dup /GlyphNames2Unicode .knownget not {
|
|
|
458 |
currentglobal exch dup gcheck setglobal
|
|
|
459 |
dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput
|
|
|
460 |
3 2 roll setglobal
|
|
|
461 |
} if % font-res font-dict encoding|null font-info g2u
|
|
|
462 |
exch pop exch % font-res font-dict g2u encoding|null
|
|
|
463 |
userdict /.lastToUnicode get % font-res font-dict g2u Encoding|null CMap
|
|
|
464 |
.convert_ToUnicode-into-g2u % font-res font-dict
|
|
|
465 |
null % font-res font-dict null
|
|
|
466 |
} ifelse
|
|
|
467 |
} if
|
|
|
468 |
PDFDEBUG {
|
|
|
469 |
(.processToUnicode end) =
|
|
|
470 |
} if
|
|
|
471 |
} if
|
|
|
472 |
pop pop pop
|
|
|
473 |
} bind def
|
|
|
474 |
|
|
|
475 |
% ---------------- Descriptors ---------------- %
|
|
|
476 |
|
|
|
477 |
% Partial descriptors for the 14 built-in fonts. Note that
|
|
|
478 |
% from PDF 1.1 to PDF 1.2, the meaning of the Flag 6 in the FontDescriptor
|
|
|
479 |
% object has undergone a subtle change in its meaning which has serious
|
|
|
480 |
% consequences for searching with Acrobat:
|
|
|
481 |
% In PDF 1.1, the flag meant: Font has StandardEncoding
|
|
|
482 |
% In PDF 1.2, the flag means: Font has (subset of) StandardRomanCharacterSet
|
|
|
483 |
/standardfontdescriptors mark
|
|
|
484 |
/Courier mark /Flags 16#23 .dicttomark
|
|
|
485 |
/Courier-Oblique 1 index
|
|
|
486 |
/Courier-Bold 1 index
|
|
|
487 |
/Courier-BoldOblique 1 index
|
|
|
488 |
/Helvetica mark /Flags 16#20 .dicttomark
|
|
|
489 |
/Helvetica-Oblique 1 index
|
|
|
490 |
/Helvetica-Bold 1 index
|
|
|
491 |
/Helvetica-BoldOblique 1 index
|
|
|
492 |
/Times-Roman mark /Flags 16#22 .dicttomark
|
|
|
493 |
/Times-Bold 1 index
|
|
|
494 |
/Times-Italic mark /Flags 16#62 .dicttomark
|
|
|
495 |
/Times-BoldItalic 1 index
|
|
|
496 |
/Symbol mark /Flags 16#4 .dicttomark
|
|
|
497 |
/ZapfDingbats 1 index
|
|
|
498 |
.dicttomark readonly def
|
|
|
499 |
|
|
|
500 |
% ---------------- Utilities ---------------- %
|
|
|
501 |
|
|
|
502 |
|
|
|
503 |
/.pdforigfontcache_g 20 dict def
|
|
|
504 |
currentglobal false setglobal
|
|
|
505 |
systemdict /.pdforigfontcache_l 20 dict .forceput
|
|
|
506 |
setglobal
|
|
|
507 |
|
|
|
508 |
% Find an original font, using cache to prevent adjustfont to accumulate changes.
|
|
|
509 |
/pdffindcachedfont { % <font_name> pdffindcachedfont <font>
|
|
|
510 |
dup //.pdforigfontcache_g exch .knownget {
|
|
|
511 |
exch pop
|
|
|
512 |
} {
|
|
|
513 |
dup .pdforigfontcache_l exch .knownget {
|
|
|
514 |
exch pop
|
|
|
515 |
} {
|
|
|
516 |
dup findfont dup
|
|
|
517 |
dup gcheck { //.pdforigfontcache_g } { .pdforigfontcache_l } ifelse
|
|
|
518 |
% Stack : font_name font font cache
|
|
|
519 |
4 2 roll .growput
|
|
|
520 |
} ifelse
|
|
|
521 |
} ifelse
|
|
|
522 |
} bind def
|
|
|
523 |
|
|
|
524 |
% Add original font to cache to prevent adjustfont to accumulate changes.
|
|
|
525 |
/pdfaddcachedfont { % <font_name> pdfaddcachedfont <font>
|
|
|
526 |
dup findfont dup % name font font
|
|
|
527 |
dup gcheck { //.pdforigfontcache_g } {.pdforigfontcache_l} ifelse
|
|
|
528 |
4 2 roll % font d name font
|
|
|
529 |
put % font
|
|
|
530 |
} bind def
|
|
|
531 |
|
|
|
532 |
/.remove_font_name_prefix { % <name> .remove_font_name_prefix <name>
|
|
|
533 |
dup .namestring (+) search {
|
|
|
534 |
true exch
|
|
|
535 |
{ dup 65 lt exch 90 gt or {
|
|
|
536 |
pop false exit
|
|
|
537 |
} if
|
|
|
538 |
} forall
|
|
|
539 |
{ pop exch pop cvn
|
|
|
540 |
} {
|
|
|
541 |
pop pop
|
|
|
542 |
} ifelse
|
|
|
543 |
} {
|
|
|
544 |
pop
|
|
|
545 |
} ifelse
|
|
|
546 |
} bind def
|
|
|
547 |
|
|
|
548 |
% Find a font (except for embedded ones), and adjust its encoding if necessary.
|
|
|
549 |
/.pdfdfndict mark
|
|
|
550 |
/defaultfontname /Helvetica
|
|
|
551 |
.dicttomark readonly def
|
|
|
552 |
/pdffindfont { % <font-resource> <fontname> pdffindfont <font>
|
|
|
553 |
% If the font isn't available, synthesize one based on
|
|
|
554 |
% its descriptor.
|
|
|
555 |
dup /Font resourcestatus {
|
|
|
556 |
pop pop pdffindcachedfont
|
|
|
557 |
} {
|
|
|
558 |
1 index /FontDescriptor knownoget {
|
|
|
559 |
% Stack: font-res fontname fontdesc
|
|
|
560 |
dup /Flags oget
|
|
|
561 |
dup 16#40 and -6 bitshift % 1, oblique/italic
|
|
|
562 |
1 index 16#40000 and -17 bitshift add % 2, bold
|
|
|
563 |
exch 16#2 and 2 bitshift add % 8, serif
|
|
|
564 |
% We should look at the fixed flag, too.
|
|
|
565 |
% Stack: font-res fontname fontdesc properties
|
|
|
566 |
|
|
|
567 |
% Even though /FontName is a required key in FontDescriptor dict
|
|
|
568 |
% (As of the PDF 1.4 Reference Manual), In the case of missing
|
|
|
569 |
% /FontName key, we substitue /BaseFont for the value of /FontName.
|
|
|
570 |
% Yet another case of broken PDF's that Adobe Reader accepts.
|
|
|
571 |
1 index dup /FontName known {
|
|
|
572 |
/FontName oget
|
|
|
573 |
} {
|
|
|
574 |
( **** FontDescriptor missing required /FontName key. BaseFont name used.\n)
|
|
|
575 |
pdfformaterror
|
|
|
576 |
pop 2 index % grab the BaseFont from the stack.
|
|
|
577 |
} ifelse
|
|
|
578 |
.remove_font_name_prefix
|
|
|
579 |
exch
|
|
|
580 |
% Analyzes font name and extract "Narrow" property
|
|
|
581 |
% which is not described by the FontDescriptor Flags.
|
|
|
582 |
|
|
|
583 |
% Rebind the default font name to Helvetica so that
|
|
|
584 |
% fonts with no properties are handled correctly.
|
|
|
585 |
//.pdfdfndict begin .substitutefontname end
|
|
|
586 |
% Stack: font-res fontname fontdesc substname|null
|
|
|
587 |
Fontmap 1 index known not {
|
|
|
588 |
% No available good substitution, use the standard one.
|
|
|
589 |
pop 1 index .substitutefont
|
|
|
590 |
} if
|
|
|
591 |
dup 3 index ne QUIET not and {
|
|
|
592 |
(Substituting font ) print dup =only
|
|
|
593 |
( for ) print 2 index =only (.) = flush
|
|
|
594 |
} if
|
|
|
595 |
pdffindcachedfont
|
|
|
596 |
% Stack: font-res fontname fontdesc font
|
|
|
597 |
% If this is a small-caps font, replace the CharString
|
|
|
598 |
% entries for a..z.
|
|
|
599 |
exch /Flags oget 16#20000 and 0 ne {
|
|
|
600 |
true .copyfontdict
|
|
|
601 |
dup /CharStrings 2 copy get dup length dict .copydict
|
|
|
602 |
% stack: font-res fontname font font /CharStrings CharStringsdict
|
|
|
603 |
5 index /FirstChar get 97 .max
|
|
|
604 |
6 index /LastChar get 122 .min 1 exch {
|
|
|
605 |
% Stack: font-res fontname font' font' /CharStrings charstrings code
|
|
|
606 |
% Note that this only remaps a-z, not accented characters.
|
|
|
607 |
6 index /Widths oget 1 index 8 index /FirstChar get sub oget
|
|
|
608 |
1 string dup 0 5 -1 roll put
|
|
|
609 |
% Stack: font-res font' font' /CharStrings charstrings code
|
|
|
610 |
% width (x)
|
|
|
611 |
2 index exch dup cvn exch
|
|
|
612 |
dup 0 2 copy get 32 sub put 4 -1 roll {
|
|
|
613 |
% Stack: operand (X) width
|
|
|
614 |
|
|
|
615 |
currentfont /FontMatrix get matrix invertmatrix concat
|
|
|
616 |
0.7 dup scale 0 0 moveto show
|
|
|
617 |
} /exec cvx 4 packedarray cvx put
|
|
|
618 |
} for put
|
|
|
619 |
} if
|
|
|
620 |
dup /FontName get 2 index ne {
|
|
|
621 |
true .copyfontdict
|
|
|
622 |
2 copy exch /FontName exch put
|
|
|
623 |
} if
|
|
|
624 |
definefont
|
|
|
625 |
} {
|
|
|
626 |
% No descriptor available, use the default algorithm.
|
|
|
627 |
pdffindcachedfont
|
|
|
628 |
} ifelse
|
|
|
629 |
} ifelse
|
|
|
630 |
exch pop
|
|
|
631 |
} bdef
|
|
|
632 |
|
|
|
633 |
% ---------------- Type 1 fonts ---------------- %
|
|
|
634 |
|
|
|
635 |
/buildType1 % <Type1-font-resource> buildType1 <font>
|
|
|
636 |
{ dup /BaseFont get pdffindfont
|
|
|
637 |
} bdef
|
|
|
638 |
|
|
|
639 |
% The state dictionary for the embedded Type 1 font reading procedure
|
|
|
640 |
% has the following keys and values:
|
|
|
641 |
% data - stream (filter)
|
|
|
642 |
% buffer, buffer2 - string
|
|
|
643 |
% hexify - procedure to convert buffer to hex if needed
|
|
|
644 |
% leftstr - string containing (non-negative) integer
|
|
|
645 |
% sectionstr - string containing a character 0 .. 3
|
|
|
646 |
% stream - (stream) dictionary
|
|
|
647 |
% proc - procedure of the form {-dict- type1read}
|
|
|
648 |
% pfbhdr - string containing 16#80 if PFB, 0 otherwise
|
|
|
649 |
% When the procedure is executing, this dictionary is current.
|
|
|
650 |
% leftstr and sectionstr are strings so that we can change their values
|
|
|
651 |
% reliably in case the font executes a restore!
|
|
|
652 |
% We also have to do something special about embedded fonts that
|
|
|
653 |
% execute definefont more than once -- that is the function of topFontDict.
|
|
|
654 |
|
|
|
655 |
% Read an embedded Type 1 font.
|
|
|
656 |
/readfontfilter { % <proc> readfontfilter <filter>
|
|
|
657 |
|
|
|
658 |
} bdef
|
|
|
659 |
/readtype1dict 5 dict dup begin
|
|
|
660 |
/definefont {
|
|
|
661 |
dup topFontDict eq topFontDict null eq or {
|
|
|
662 |
dup wcheck not { dup length dict copy } if
|
|
|
663 |
exch pop savedFontName exch
|
|
|
664 |
} if
|
|
|
665 |
//systemdict /definefont get exec
|
|
|
666 |
} bdef
|
|
|
667 |
/eexec {
|
|
|
668 |
% Assume the font dictionary is directly below the file on the stack
|
|
|
669 |
count 0 gt { /topFontDict 2 index cvlit store } if
|
|
|
670 |
//.eexec_param_dict /eexecDecode filter
|
|
|
671 |
//systemdict begin readtype1dictcopy begin cvx stopped
|
|
|
672 |
currentdict readtype1dictcopy eq { end } if
|
|
|
673 |
currentdict //systemdict eq { end } if
|
|
|
674 |
{ stop } if
|
|
|
675 |
} bdef
|
|
|
676 |
|
|
|
677 |
/undef_proc_warning {
|
|
|
678 |
/Repaired true store % flag that we have warnings
|
|
|
679 |
UndefProcList exch 2 copy .knownget { 1 add } { 1 } ifelse put
|
|
|
680 |
} bdef
|
|
|
681 |
|
|
|
682 |
/-| { string currentfile exch readstring pop /-| undef_proc_warning } executeonly bdef
|
|
|
683 |
/RD { string currentfile exch readstring pop /RD undef_proc_warning } executeonly bdef
|
|
|
684 |
/|- { noaccess def /|- undef_proc_warning } executeonly bdef
|
|
|
685 |
/ND { noaccess def /ND undef_proc_warning } executeonly bdef
|
|
|
686 |
/| { noaccess put /| undef_proc_warning } executeonly bdef
|
|
|
687 |
/NP { noaccess put /NP undef_proc_warning } executeonly bdef
|
|
|
688 |
|
|
|
689 |
end readonly def
|
|
|
690 |
/readtype1 { % <font-resource> <stream-dict> readtype1 <font>
|
|
|
691 |
% Read the definition, using a procedure-based filter
|
|
|
692 |
% that turns binary/hex conversion on and off
|
|
|
693 |
% at the right times.
|
|
|
694 |
1 index exch
|
|
|
695 |
PDFfile fileposition 3 1 roll
|
|
|
696 |
11 dict begin
|
|
|
697 |
/leftstr ( ) 10 string copy def
|
|
|
698 |
dup /Length1 oget leftstr cvs pop
|
|
|
699 |
/sectionstr <00> 1 string copy def
|
|
|
700 |
/pfbhdr <00> 1 string copy def
|
|
|
701 |
/stream 1 index def
|
|
|
702 |
true resolvestream /data exch def
|
|
|
703 |
/buffer 1000 string def % arbitrary
|
|
|
704 |
/buffer2 buffer length 2.1 div cvi 1 sub string def
|
|
|
705 |
/hexify /buf2hex load def
|
|
|
706 |
currentdict end
|
|
|
707 |
/type1read cvx 2 array astore cvx dup 0 get /proc 2 index put
|
|
|
708 |
readfontfilter
|
|
|
709 |
% Some buggy embedded fonts leave extra junk on the stack,
|
|
|
710 |
% so we have to make a closure that records the stack depth
|
|
|
711 |
% in a fail-safe way. Also restore dictstack depth.
|
|
|
712 |
//systemdict begin
|
|
|
713 |
% The PDF specification is somewhat muddy about whether
|
|
|
714 |
% an embedded font's name is supposed to be the BaseFont
|
|
|
715 |
% from the Font object or the FontName from the descriptor.
|
|
|
716 |
% Acrobat Distiller requires the former. Save away the
|
|
|
717 |
% name so we can substitute it at definefont time.
|
|
|
718 |
//readtype1dict dup length 3 add dict copy begin
|
|
|
719 |
1 index /BaseFont oget /savedFontName exch def
|
|
|
720 |
/topFontDict null def
|
|
|
721 |
/readtype1dictcopy currentdict def
|
|
|
722 |
{ run } aload pop count 1 sub 2 packedarray cvx exec
|
|
|
723 |
% clean up the dictstack
|
|
|
724 |
{ currentdict /topFontDict known not { end } { end end exit } ifelse } loop
|
|
|
725 |
count exch sub { pop } repeat
|
|
|
726 |
PDFfile 3 -1 roll setfileposition
|
|
|
727 |
/BaseFont oget pdfaddcachedfont
|
|
|
728 |
exch pop
|
|
|
729 |
} bdef
|
|
|
730 |
|
|
|
731 |
% Execute the appropriate reading procedure.
|
|
|
732 |
/type1read % <dict> type1read <string>
|
|
|
733 |
{ begin leftstr cvi
|
|
|
734 |
{ type1read0 type1read1 type1read2 type1read3 } sectionstr 0 get get exec
|
|
|
735 |
( ) leftstr copy cvs pop end
|
|
|
736 |
} bdef
|
|
|
737 |
|
|
|
738 |
% Read the next block of data into the buffer.
|
|
|
739 |
/type1readdata % <left> <buffer> type1readdata <substring> <left'>
|
|
|
740 |
{ 0 2 index 2 index length .min getinterval
|
|
|
741 |
% Adobe requires readstring to signal an error if given
|
|
|
742 |
% an empty string. Work around this nonsense here.
|
|
|
743 |
dup length 0 ne { data exch readstring pop } if
|
|
|
744 |
dup length 3 -1 roll exch sub
|
|
|
745 |
PDFDEBUG
|
|
|
746 |
{ dup =only ( read ) print
|
|
|
747 |
1 index length =only (: ) print
|
|
|
748 |
1 index == flush
|
|
|
749 |
} if
|
|
|
750 |
} bdef
|
|
|
751 |
|
|
|
752 |
% Read the initial byte to see if we need to skip a 6 byte PFB header
|
|
|
753 |
/type1read0 { % <left> type1read0 <string> <left'>
|
|
|
754 |
sectionstr 0 1 put % either way we go to the next stage
|
|
|
755 |
pfbhdr type1readdata
|
|
|
756 |
1 index 0 get 16#80 eq {
|
|
|
757 |
( **** Warning: Embedded Type1 font in PFB format is not valid PDF.\n)
|
|
|
758 |
pdfformaterror
|
|
|
759 |
PDFDEBUG { (skipping PFB header) = flush } if
|
|
|
760 |
exch pop buffer 0 5 getinterval type1readdata exch
|
|
|
761 |
dup 4 get 256 mul 1 index 3 get add 256 mul
|
|
|
762 |
1 index 2 get add 256 mul 1 index 1 get add
|
|
|
763 |
PDFDEBUG { (PFB segment length = ) print dup = } if
|
|
|
764 |
exch pop % discard the string keeping the PFB segment length
|
|
|
765 |
2 copy ne {
|
|
|
766 |
( **** Warning: Type 1 PFB segment length and Length 1 value do not match.\n)
|
|
|
767 |
pdfformaterror
|
|
|
768 |
exch % keep the PFB length instead
|
|
|
769 |
} if
|
|
|
770 |
pop
|
|
|
771 |
buffer type1readdata % go ahead and read a block
|
|
|
772 |
}
|
|
|
773 |
if % if not PFB, return pfbhdr string (first char of file, usually %).
|
|
|
774 |
} bdef
|
|
|
775 |
|
|
|
776 |
% Read the next block of the initial text portion.
|
|
|
777 |
/type1read1 { % <left> type1read1 <string> <left'>
|
|
|
778 |
PDFDEBUG { (read1 ) print } if
|
|
|
779 |
dup 0 eq {
|
|
|
780 |
pop sectionstr 0 2 put
|
|
|
781 |
stream /Length2 oget
|
|
|
782 |
% Determine whether to hexify data for eexec.
|
|
|
783 |
dup 8 lt {
|
|
|
784 |
type1read2 % Hexify.
|
|
|
785 |
} {
|
|
|
786 |
PDFDEBUG { (read2 ) print } if
|
|
|
787 |
pfbhdr 0 get 16#80 eq {
|
|
|
788 |
% eat 6 more bytes of PFB junk before proceeding
|
|
|
789 |
PDFDEBUG { (skipping PFB header in segment 2) = flush } if
|
|
|
790 |
buffer 0 6 getinterval type1readdata exch
|
|
|
791 |
dup 5 get 256 mul 1 index 4 get add 256 mul
|
|
|
792 |
1 index 3 get add 256 mul 1 index 2 get add
|
|
|
793 |
PDFDEBUG { (PFB segment length = ) print dup = } if
|
|
|
794 |
exch pop % discard the string keeping the PFB segment length
|
|
|
795 |
2 copy ne {
|
|
|
796 |
( **** Warning: Type 1 PFB segment length and Length 2 value do not match.\n)
|
|
|
797 |
pdfformaterror
|
|
|
798 |
exch % keep the PFB length instead
|
|
|
799 |
} if
|
|
|
800 |
pop
|
|
|
801 |
} if
|
|
|
802 |
buffer2 type1readdata exch
|
|
|
803 |
% The check doesn't have to be 100% accurate:
|
|
|
804 |
% hexifying is always OK.
|
|
|
805 |
dup 0 8 getinterval 0 exch { or } forall
|
|
|
806 |
128 ge {
|
|
|
807 |
/hexify { } store
|
|
|
808 |
/buffer2 buffer def % We don't need an intermediate buffer.
|
|
|
809 |
} if hexify exch
|
|
|
810 |
} ifelse
|
|
|
811 |
} {
|
|
|
812 |
buffer type1readdata
|
|
|
813 |
} ifelse
|
|
|
814 |
} bdef
|
|
|
815 |
|
|
|
816 |
% Convert a string from binary to hex for eexec.
|
|
|
817 |
% Free variables: buffer.
|
|
|
818 |
/buf2hex { % <string> buf2hex <hexstring>
|
|
|
819 |
buffer /ASCIIHexEncode filter dup 3 -1 roll writestring closefile
|
|
|
820 |
buffer (>) search pop exch pop exch pop
|
|
|
821 |
} bdef
|
|
|
822 |
|
|
|
823 |
% Read the next block of the encrypted portion.
|
|
|
824 |
/type1trailer
|
|
|
825 |
(0000000000000000000000000000000000000000000000000000000000000000\n\
|
|
|
826 |
0000000000000000000000000000000000000000000000000000000000000000\n\
|
|
|
827 |
0000000000000000000000000000000000000000000000000000000000000000\n\
|
|
|
828 |
0000000000000000000000000000000000000000000000000000000000000000\n\
|
|
|
829 |
0000000000000000000000000000000000000000000000000000000000000000\n\
|
|
|
830 |
0000000000000000000000000000000000000000000000000000000000000000\n\
|
|
|
831 |
0000000000000000000000000000000000000000000000000000000000000000\n\
|
|
|
832 |
0000000000000000000000000000000000000000000000000000000000000000\n\
|
|
|
833 |
cleartomark\n)
|
|
|
834 |
readonly def
|
|
|
835 |
/type1read2 { % <left> type1read2 <string> <left'>
|
|
|
836 |
PDFDEBUG { (read2 ) print } if
|
|
|
837 |
dup 0 eq
|
|
|
838 |
{ pop sectionstr 0 3 put
|
|
|
839 |
stream /Length3 oget
|
|
|
840 |
dup 0 eq
|
|
|
841 |
{ PDFDEBUG { (trailer ) print } if
|
|
|
842 |
type1trailer exch
|
|
|
843 |
}
|
|
|
844 |
{
|
|
|
845 |
pfbhdr 0 get 16#80 eq {
|
|
|
846 |
% eat 6 more bytes of PFB junk before proceeding
|
|
|
847 |
PDFDEBUG { (skipping PFB header in segment 3) = flush } if
|
|
|
848 |
buffer 0 6 getinterval type1readdata exch
|
|
|
849 |
dup 5 get 256 mul 1 index 4 get add 256 mul
|
|
|
850 |
1 index 3 get add 256 mul 1 index 2 get add
|
|
|
851 |
PDFDEBUG { (PFB segment length = ) print dup = } if
|
|
|
852 |
exch pop % discard the string keeping the PFB segment length
|
|
|
853 |
2 copy ne {
|
|
|
854 |
( **** Warning: Type 1 PFB segment length and Length 3 value do not match.\n)
|
|
|
855 |
pdfformaterror
|
|
|
856 |
exch % keep the PFB length instead
|
|
|
857 |
} if
|
|
|
858 |
pop
|
|
|
859 |
} if
|
|
|
860 |
type1read3
|
|
|
861 |
}
|
|
|
862 |
ifelse
|
|
|
863 |
}
|
|
|
864 |
{ buffer2 type1readdata exch hexify exch
|
|
|
865 |
}
|
|
|
866 |
ifelse
|
|
|
867 |
} bdef
|
|
|
868 |
|
|
|
869 |
% Read the next block of the final text portion.
|
|
|
870 |
% When finished, this procedure returns an empty string.
|
|
|
871 |
/type1read3 % <left> type1read3 <string> <left'>
|
|
|
872 |
{ PDFDEBUG { (read3 ) print } if
|
|
|
873 |
buffer type1readdata
|
|
|
874 |
} bdef
|
|
|
875 |
|
|
|
876 |
% ---------------- Type 3 fonts ---------------- %
|
|
|
877 |
|
|
|
878 |
/buildType3 { % <Type3-font-resource> buildType3 <font>
|
|
|
879 |
8 dict begin
|
|
|
880 |
/FontType 3 def
|
|
|
881 |
% If the font does not contain a Resources entry, then we use
|
|
|
882 |
% the resources from our current context. Page 391 of the PDF
|
|
|
883 |
% 1.6 spec says that the Resources dict is optional and if not
|
|
|
884 |
% present then we should use the Resources for the page.
|
|
|
885 |
% However we have a test file (687989) which uses a Type3 font
|
|
|
886 |
% inside a form XObject and the desired Resources are in the
|
|
|
887 |
% XObject dict and not in the Page dict. So we are going to
|
|
|
888 |
% the parent object to find resources instead of only going to
|
|
|
889 |
% the page dict when a font does not specify its required
|
|
|
890 |
% resources.
|
|
|
891 |
/Resources 1 index /Resources knownoget {
|
|
|
892 |
oforce
|
|
|
893 |
} {
|
|
|
894 |
LocalResources
|
|
|
895 |
} ifelse def
|
|
|
896 |
/FontBBox 1 index /FontBBox get cvx def
|
|
|
897 |
/FontMatrix 1 index /FontMatrix oget def
|
|
|
898 |
/CharProcs 1 index /CharProcs oget def
|
|
|
899 |
1 index /Widths knownoget {
|
|
|
900 |
/Widths exch def
|
|
|
901 |
/FirstChar 1 index /FirstChar oget def
|
|
|
902 |
/LastChar 1 index /LastChar oget def
|
|
|
903 |
} if
|
|
|
904 |
/FontName 1 index /Name .knownget not {
|
|
|
905 |
PDFfile fileposition 16 10 string cvrs cvn
|
|
|
906 |
} if def
|
|
|
907 |
|
|
|
908 |
/Encoding .notdefEncoding 2 index getencoding def
|
|
|
909 |
% We have to define BuildChar rather than BuildGlyph:
|
|
|
910 |
% there is no PDF equivalent of glyphshow, and we need
|
|
|
911 |
% the character code to access the Widths.
|
|
|
912 |
/BuildChar {
|
|
|
913 |
% Stack: font charcode
|
|
|
914 |
1 index begin 3 dict begin
|
|
|
915 |
/Font 3 -1 roll def /CharCode 1 index def
|
|
|
916 |
% Make unknown characters map to /.notdef
|
|
|
917 |
Encoding exch get dup CharProcs exch known
|
|
|
918 |
{ CharProcs exch oget }
|
|
|
919 |
{ pop CharProcs /.notdef oget }
|
|
|
920 |
ifelse
|
|
|
921 |
PDFfile fileposition exch
|
|
|
922 |
false resolvestream
|
|
|
923 |
% Stack: filepos stream
|
|
|
924 |
% Don't let setgcolor set the color inside the BuildGlyph
|
|
|
925 |
% procedure, because this causes an /undefined error.
|
|
|
926 |
q null /FillColor gput null /StrokeColor gput
|
|
|
927 |
Font /Resources get exch pdfopdict .pdfruncontext
|
|
|
928 |
Q
|
|
|
929 |
PDFfile exch setfileposition
|
|
|
930 |
end end
|
|
|
931 |
} bdef
|
|
|
932 |
dup currentdict Encoding .processToUnicode
|
|
|
933 |
FontName currentdict end definefont exch pop
|
|
|
934 |
} bdef
|
|
|
935 |
/.adjustcharwidth { % <wx> <wy> .adjustcharwidth <wx'> <wy'>
|
|
|
936 |
/Widths where {
|
|
|
937 |
begin
|
|
|
938 |
CharCode FirstChar ge CharCode LastChar le and {
|
|
|
939 |
exch pop Widths CharCode FirstChar sub get exch
|
|
|
940 |
} if end
|
|
|
941 |
} if
|
|
|
942 |
} bdef
|
|
|
943 |
|
|
|
944 |
% ---------------- TrueType fonts ---------------- %
|
|
|
945 |
|
|
|
946 |
/TTfonts mark
|
|
|
947 |
/Arial /Helvetica
|
|
|
948 |
/Arial,Italic /Helvetica-Oblique
|
|
|
949 |
/Arial,Bold /Helvetica-Bold
|
|
|
950 |
/Arial,BoldItalic /Helvetica-BoldOblique
|
|
|
951 |
/CourierNew /Courier
|
|
|
952 |
/CourierNew,Bold /Courier-Bold
|
|
|
953 |
/TimesNewRoman /Times-Roman
|
|
|
954 |
/TimesNewRoman,Italic /Times-Italic
|
|
|
955 |
/TimesNewRoman,Bold /Times-Bold
|
|
|
956 |
/TimesNewRoman,BoldItalic /Times-BoldItalic
|
|
|
957 |
.dicttomark readonly def
|
|
|
958 |
|
|
|
959 |
/buildTrueType { % <TrueType-font-resource> buildTrueType <font>
|
|
|
960 |
dup /BaseFont oget
|
|
|
961 |
/Repaired true store % flag that we had warnings
|
|
|
962 |
TTFWarnList 1 index true put % Add fontname to the list
|
|
|
963 |
dup TTfonts exch .knownget {
|
|
|
964 |
QUIET not {
|
|
|
965 |
(Substituting font ) print dup =only
|
|
|
966 |
( for ) print 1 index =only (.) = flush
|
|
|
967 |
} if
|
|
|
968 |
exch 3 1 roll pdffindfont
|
|
|
969 |
true .copyfontdict
|
|
|
970 |
2 copy exch /FontName exch put
|
|
|
971 |
definefont
|
|
|
972 |
} {
|
|
|
973 |
pdffindfont
|
|
|
974 |
} ifelse
|
|
|
975 |
} bdef
|
|
|
976 |
|
|
|
977 |
% Read an embedded TrueType font.
|
|
|
978 |
/readtruetype { % <font-resource> <stream-dict> readtruetype <font>
|
|
|
979 |
% This is much simpler than readtype1, because we don't
|
|
|
980 |
% have to deal with the tripartite .PFB format.
|
|
|
981 |
1 index exch
|
|
|
982 |
PDFfile fileposition 3 1 roll
|
|
|
983 |
true resolvestream readfontfilter
|
|
|
984 |
% Stack: filepos fontres stream
|
|
|
985 |
1 index /Subtype get /CIDFontType2 eq {
|
|
|
986 |
.loadttcidfont
|
|
|
987 |
% Stack: filepos fontres cidfont
|
|
|
988 |
} {
|
|
|
989 |
% filepos fontres stream
|
|
|
990 |
1 index /FontDescriptor oget % filepos fontres stream fd
|
|
|
991 |
/Flags get 4 and 0 ne % filepos fontres stream is_symbolic
|
|
|
992 |
dup {
|
|
|
993 |
2 index null exch getencoding % filepos fontres stream is_symbolic Encoding
|
|
|
994 |
dup 4 index exch % filepos fontres stream is_symbolic Encoding fontres Encoding
|
|
|
995 |
/prebuilt_encoding exch put % filepos fontres stream is_symbolic Encoding
|
|
|
996 |
} {
|
|
|
997 |
null
|
|
|
998 |
} ifelse
|
|
|
999 |
.loadpdfttfont
|
|
|
1000 |
} ifelse
|
|
|
1001 |
exch pop
|
|
|
1002 |
PDFfile 3 -1 roll setfileposition
|
|
|
1003 |
% Ignore both the Encoding and the Widths.
|
|
|
1004 |
exch pop
|
|
|
1005 |
} bdef
|
|
|
1006 |
|
|
|
1007 |
% ---------------- Type 0 fonts ---------------- %
|
|
|
1008 |
|
|
|
1009 |
% Predefine the known CMaps, but only create them on demand.
|
|
|
1010 |
/knownCMaps mark
|
|
|
1011 |
/Identity-H { /Identity-H 0 makeIdentityCMap }
|
|
|
1012 |
/Identity-V { /Identity-V 1 makeIdentityCMap }
|
|
|
1013 |
.dicttomark def
|
|
|
1014 |
|
|
|
1015 |
/makeIdentityCMap { % <cmapname> <wmode> .makeIdentityCMap -
|
|
|
1016 |
.currentglobal true .setglobal 3 1 roll
|
|
|
1017 |
/CIDInit /ProcSet findresource begin
|
|
|
1018 |
12 dict begin
|
|
|
1019 |
begincmap
|
|
|
1020 |
/WMode exch def
|
|
|
1021 |
/CMapName exch def
|
|
|
1022 |
/CIDSystemInfo 3 dict dup begin
|
|
|
1023 |
/Registry (Adobe) def
|
|
|
1024 |
/Ordering (Identity) def
|
|
|
1025 |
/Supplement 0 def
|
|
|
1026 |
end def
|
|
|
1027 |
%/CMapName (see above)
|
|
|
1028 |
/CMapVersion 1 def
|
|
|
1029 |
/CMapType 1 def
|
|
|
1030 |
%WMode (see above)
|
|
|
1031 |
% The PDF documentation says that these CMaps map CIDs
|
|
|
1032 |
% "1 to 65,536". This is a misprint for 0 to 65,535.
|
|
|
1033 |
1 begincodespacerange
|
|
|
1034 |
% <0001> <00ff> <0100> <ffff>
|
|
|
1035 |
<0000> <ffff>
|
|
|
1036 |
endcodespacerange
|
|
|
1037 |
1 begincidrange
|
|
|
1038 |
% <0001> <00ff> 1 <0100> <ffff> 256
|
|
|
1039 |
<0000> <ffff> 0
|
|
|
1040 |
endcidrange
|
|
|
1041 |
endcmap
|
|
|
1042 |
CMapName currentdict /CMap defineresource
|
|
|
1043 |
knownCMaps CMapName 2 index put
|
|
|
1044 |
end % CMap
|
|
|
1045 |
end % CIDInit ProcSet
|
|
|
1046 |
exch .setglobal
|
|
|
1047 |
} bdef
|
|
|
1048 |
|
|
|
1049 |
/buildType0 { % <Type0-font-resource> buildType0 <font>
|
|
|
1050 |
dup /BaseFont get % FontName
|
|
|
1051 |
1 index /Encoding oget
|
|
|
1052 |
dup type /nametype eq {
|
|
|
1053 |
dup /CMap resourcestatus {
|
|
|
1054 |
pop pop /CMap findresource
|
|
|
1055 |
} {
|
|
|
1056 |
knownCMaps 1 index .knownget
|
|
|
1057 |
{ exch pop exec } { /undefined signalerror } ifelse
|
|
|
1058 |
} ifelse
|
|
|
1059 |
} {
|
|
|
1060 |
PDFfile fileposition exch
|
|
|
1061 |
dup /CMapName get exch true resolvestream cvx exec
|
|
|
1062 |
/CMap findresource
|
|
|
1063 |
exch PDFfile exch setfileposition
|
|
|
1064 |
} ifelse % CMap
|
|
|
1065 |
[
|
|
|
1066 |
3 index /DescendantFonts oget { exec resourcefont } forall
|
|
|
1067 |
] % subfonts
|
|
|
1068 |
composefont % composefont must insert FontInfo dictionary - see gs_cmap.ps .
|
|
|
1069 |
% Stack: fontres font
|
|
|
1070 |
2 copy null .processToUnicode
|
|
|
1071 |
1 index /FontMatrix knownoget {
|
|
|
1072 |
dup aload pop true {0 0 1 0 0 1} {3 -1 roll eq and} forall {
|
|
|
1073 |
1 index exch makefont exch /FontName get exch definefont
|
|
|
1074 |
} {
|
|
|
1075 |
pop
|
|
|
1076 |
} ifelse
|
|
|
1077 |
} if exch pop
|
|
|
1078 |
} bdef
|
|
|
1079 |
|
|
|
1080 |
% ---------------- CIDFontType0/2 fonts ---------------- %
|
|
|
1081 |
|
|
|
1082 |
% Insert metrics into a CIDFont, by saving the PDF W, W2, DW, and DW2
|
|
|
1083 |
% arrays and using a (currently very inefficient) CDevProc.
|
|
|
1084 |
% For detail, refer "PDF Reference" 2nd ed., p314 "5.6.3 CIDFonts".
|
|
|
1085 |
% It notes default DW is 0, but Acrobat Reader uses 1000 as default.
|
|
|
1086 |
% If DW is 0, currentpoint does not move by default in rendering text
|
|
|
1087 |
% horizontally, the result is unreadable. You can check it by Acrobat.
|
|
|
1088 |
|
|
|
1089 |
/.pdfDefaultDW 1000 def
|
|
|
1090 |
/.pdfDefaultDW2 [ 880 -1000 ] def
|
|
|
1091 |
|
|
|
1092 |
/addCIDmetrics { % <CIDFont-resource> <CIDFont> addCIDmetrics <fontdict>
|
|
|
1093 |
dup length 5 add dict .copydict
|
|
|
1094 |
dup /FID undef
|
|
|
1095 |
dup /UniqueID undef
|
|
|
1096 |
dup /XUID undef
|
|
|
1097 |
% Insert the widths into the font.
|
|
|
1098 |
|
|
|
1099 |
% Stack: pdfresource newfont
|
|
|
1100 |
|
|
|
1101 |
1 index /DW .knownget {
|
|
|
1102 |
1 index /DW 3 -1 roll put
|
|
|
1103 |
} {
|
|
|
1104 |
dup /DW .pdfDefaultDW put
|
|
|
1105 |
} ifelse
|
|
|
1106 |
|
|
|
1107 |
1 index /W .knownget {
|
|
|
1108 |
dup 2 index /W 3 -1 roll put
|
|
|
1109 |
.pdfMakeInternalW 1 index /.internalW 3 -1 roll put
|
|
|
1110 |
} if
|
|
|
1111 |
|
|
|
1112 |
1 index /DW2 .knownget {
|
|
|
1113 |
1 index /DW2 3 -1 roll put
|
|
|
1114 |
} {
|
|
|
1115 |
dup /DW2 .pdfDefaultDW2 put
|
|
|
1116 |
} ifelse
|
|
|
1117 |
|
|
|
1118 |
1 index /W2 .knownget {
|
|
|
1119 |
dup 2 index /W2 3 -1 roll put
|
|
|
1120 |
.pdfMakeInternalW2 1 index /.internalW2 3 -1 roll put
|
|
|
1121 |
} if
|
|
|
1122 |
|
|
|
1123 |
dup /CDevProc 1 index /CIDWProc load /exec load 3 packedarray cvx put
|
|
|
1124 |
exch pop
|
|
|
1125 |
} bdef
|
|
|
1126 |
|
|
|
1127 |
/.pdfMakeInternalMTXArray { % <mtx_array> <item_size> .pdfConvertInternalW <mtx_array'>
|
|
|
1128 |
|
|
|
1129 |
% convert /W or /W2 to internal expression
|
|
|
1130 |
%
|
|
|
1131 |
% mtx_array: original /W or /W2 array
|
|
|
1132 |
% item_size: number of metrics values per CID
|
|
|
1133 |
%
|
|
|
1134 |
% for detail of the metrics list format in PDF,
|
|
|
1135 |
% refer PDF Ref. p.317 "Glyph Metrics in CIDFonts".
|
|
|
1136 |
%
|
|
|
1137 |
% format of single entry in internal expression
|
|
|
1138 |
%
|
|
|
1139 |
% [
|
|
|
1140 |
% [cid_begin cid_end]
|
|
|
1141 |
% value_is_varied (bool)
|
|
|
1142 |
% [ [values for cid_begin...]
|
|
|
1143 |
% [values for cid_begin + 1]
|
|
|
1144 |
% ... ]
|
|
|
1145 |
% ]
|
|
|
1146 |
%
|
|
|
1147 |
|
|
|
1148 |
7 dict
|
|
|
1149 |
begin
|
|
|
1150 |
/itemSize exch def
|
|
|
1151 |
/M exch def % original /W or /W2
|
|
|
1152 |
/Msize M length def
|
|
|
1153 |
/Mi { M i get } def % W[i]
|
|
|
1154 |
/Mi1 { M i 1 add get } def % W[i + 1]
|
|
|
1155 |
/putMTXEntry <<
|
|
|
1156 |
/arraytype {
|
|
|
1157 |
[
|
|
|
1158 |
[Mi Mi Mi1 length itemSize idiv add 1 sub]
|
|
|
1159 |
true
|
|
|
1160 |
[
|
|
|
1161 |
|
|
|
1162 |
[ exch 1 1 index itemSize add 1 sub { Mi1 exch get } for ]
|
|
|
1163 |
} for
|
|
|
1164 |
]
|
|
|
1165 |
]
|
|
|
1166 |
/i i 2 add def
|
|
|
1167 |
}
|
|
|
1168 |
/integertype {
|
|
|
1169 |
[
|
|
|
1170 |
[Mi Mi1]
|
|
|
1171 |
false
|
|
|
1172 |
[[ i 2 add 1 i 1 add itemSize add { M exch get } for ]]
|
|
|
1173 |
]
|
|
|
1174 |
/i i 3 add def
|
|
|
1175 |
}
|
|
|
1176 |
>> def
|
|
|
1177 |
|
|
|
1178 |
/i 0 def
|
|
|
1179 |
|
|
|
1180 |
[ { putMTXEntry Mi1 type get exec i Msize ge { exit } if } loop ]
|
|
|
1181 |
end
|
|
|
1182 |
} def
|
|
|
1183 |
|
|
|
1184 |
/.pdfMakeInternalW { dup length 0 gt { 1 .pdfMakeInternalMTXArray } if } def
|
|
|
1185 |
/.pdfMakeInternalW2 { dup length 0 gt { 3 .pdfMakeInternalMTXArray } if } def
|
|
|
1186 |
|
|
|
1187 |
/.pdfGetMTXByCID { % <internalMTXArray> <cid>
|
|
|
1188 |
% .pdfGetMTXByCID
|
|
|
1189 |
% { <MTXEntry> true | false }
|
|
|
1190 |
|
|
|
1191 |
% get values for given CID from internal format of /W or /W2
|
|
|
1192 |
|
|
|
1193 |
exch
|
|
|
1194 |
{
|
|
|
1195 |
{
|
|
|
1196 |
dup 0 get {} forall % Stack: <cid> <entry> <cid_0> <cid_1>
|
|
|
1197 |
3 index lt { pop pop false exit } if
|
|
|
1198 |
2 index exch sub dup 0 lt { pop pop false exit } if
|
|
|
1199 |
1 index 1 get not { pop 0 } if
|
|
|
1200 |
exch 2 get exch get true exit
|
|
|
1201 |
} loop
|
|
|
1202 |
{ exit } if
|
|
|
1203 |
} forall
|
|
|
1204 |
dup type /arraytype eq { exch pop true } { pop false } ifelse
|
|
|
1205 |
} def
|
|
|
1206 |
|
|
|
1207 |
|
|
|
1208 |
% Apply the [D]W[2] metrics to a character before displaying.
|
|
|
1209 |
/CIDWProc { % <w0x> <w0y> <llx> <lly> <urx> <ury>
|
|
|
1210 |
% <w1x> <w1y> <vx> <vy> <cid> <font> CIDWproc
|
|
|
1211 |
% <w0x'> ... <vy'>
|
|
|
1212 |
begin % push <font> to currentdict
|
|
|
1213 |
% <w1x> <w1y> <vx> <vy> won't be used and replaced, discard now
|
|
|
1214 |
5 1 roll pop pop pop pop
|
|
|
1215 |
|
|
|
1216 |
{
|
|
|
1217 |
currentdict /DW .knownget not { % no DW
|
|
|
1218 |
.pdfDefaultDW exit % replace <w0x> by defaultDW
|
|
|
1219 |
} if
|
|
|
1220 |
|
|
|
1221 |
currentdict /.internalW .knownget not { % no W
|
|
|
1222 |
exit % use already-stacked DW
|
|
|
1223 |
} if
|
|
|
1224 |
|
|
|
1225 |
dup length 0 eq { % W is null array
|
|
|
1226 |
pop % discard unusable W
|
|
|
1227 |
exit % use already-stacked DW
|
|
|
1228 |
} if
|
|
|
1229 |
|
|
|
1230 |
% W is finite array, try to get W_cid
|
|
|
1231 |
2 index .pdfGetMTXByCID { % got W, discard DW
|
|
|
1232 |
exch pop {} forall
|
|
|
1233 |
exit
|
|
|
1234 |
} if
|
|
|
1235 |
|
|
|
1236 |
exit
|
|
|
1237 |
} loop
|
|
|
1238 |
|
|
|
1239 |
FontType 11 eq {
|
|
|
1240 |
1000 div % <w0x'> (normalized W)
|
|
|
1241 |
} if
|
|
|
1242 |
|
|
|
1243 |
|
|
|
1244 |
% Stack: <w0x> <w0y> <llx> <lly> <urx> <ury> <cid> <w0x'> <w0y'>
|
|
|
1245 |
9 -2 roll pop pop % discard <w0x> <w0y>
|
|
|
1246 |
7 2 roll % put <w0x'> <w0y'>
|
|
|
1247 |
|
|
|
1248 |
% Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <cid>
|
|
|
1249 |
|
|
|
1250 |
exch % put <w1x'>
|
|
|
1251 |
|
|
|
1252 |
% Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> <cid>
|
|
|
1253 |
{
|
|
|
1254 |
currentdict /DW2 .knownget not { % no DW2, use defaultDW2
|
|
|
1255 |
.pdfDefaultDW2 exit
|
|
|
1256 |
} if
|
|
|
1257 |
|
|
|
1258 |
currentdict /.internalW2 .knownget not { % has DW2, no W2
|
|
|
1259 |
exit % use already-stacked DW2
|
|
|
1260 |
} if
|
|
|
1261 |
|
|
|
1262 |
dup length 0 eq { % W2 is null array
|
|
|
1263 |
pop % discard unusable W2
|
|
|
1264 |
exit % use already-stacked DW2
|
|
|
1265 |
} if
|
|
|
1266 |
|
|
|
1267 |
2 index .pdfGetMTXByCID { % got W2_cid, discard DW2
|
|
|
1268 |
exch pop
|
|
|
1269 |
exit
|
|
|
1270 |
} if
|
|
|
1271 |
|
|
|
1272 |
% could not get W2_cid
|
|
|
1273 |
exit
|
|
|
1274 |
|
|
|
1275 |
} loop
|
|
|
1276 |
|
|
|
1277 |
exch pop % discard <cid>
|
|
|
1278 |
|
|
|
1279 |
% Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> { [<vy'> <w1y'>] | [<w1y'> <vx'> <vy'>] }
|
|
|
1280 |
dup length 2 eq { % this is DW2
|
|
|
1281 |
FontType 11 eq {{1000 div}} {{}} ifelse forall exch
|
|
|
1282 |
8 index 2 div % <vx'> = <w0x'> / 2
|
|
|
1283 |
exch
|
|
|
1284 |
}{ % assume W2
|
|
|
1285 |
FontType 11 eq {{1000 div}} {{}} ifelse forall
|
|
|
1286 |
} ifelse
|
|
|
1287 |
end % recover currentdict
|
|
|
1288 |
|
|
|
1289 |
} def
|
|
|
1290 |
|
|
|
1291 |
% <string> <match> tailmatch ==> <pre> true
|
|
|
1292 |
% ==> <string> false
|
|
|
1293 |
/tailmatch {
|
|
|
1294 |
2 copy length 1 index length .min
|
|
|
1295 |
dup 2 index length exch sub exch getinterval
|
|
|
1296 |
1 index eq {
|
|
|
1297 |
length 1 index length exch sub
|
|
|
1298 |
|
|
|
1299 |
} {
|
|
|
1300 |
pop false
|
|
|
1301 |
} ifelse
|
|
|
1302 |
} bind def
|
|
|
1303 |
|
|
|
1304 |
/makeboldfont {
|
|
|
1305 |
16 dict begin
|
|
|
1306 |
/strokewidth exch def
|
|
|
1307 |
/basecidfont exch def
|
|
|
1308 |
/FontMatrix [ 1 0 0 1 0 0 ] def
|
|
|
1309 |
|
|
|
1310 |
/CIDFontName /.boldfont def
|
|
|
1311 |
/CIDFontType 1 def
|
|
|
1312 |
|
|
|
1313 |
/basefont-H /.basefont-H /Identity-H [ basecidfont ] composefont def
|
|
|
1314 |
/basefont-V /.basefont-V /Identity-V [ basecidfont ] composefont def
|
|
|
1315 |
|
|
|
1316 |
/CIDSystemInfo dup basecidfont exch get def
|
|
|
1317 |
/FontBBox [ basecidfont /FontBBox get cvx exec
|
|
|
1318 |
4 2 roll basecidfont /FontMatrix get transform
|
|
|
1319 |
4 2 roll basecidfont /FontMatrix get transform
|
|
|
1320 |
] def
|
|
|
1321 |
|
|
|
1322 |
/tmpstr 2 string def
|
|
|
1323 |
/BuildGlyph {
|
|
|
1324 |
gsave
|
|
|
1325 |
exch begin
|
|
|
1326 |
dup 256 idiv tmpstr exch 0 exch put
|
|
|
1327 |
256 mod tmpstr exch 1 exch put
|
|
|
1328 |
rootfont /WMode known { rootfont /WMode get 1 eq } { false } ifelse
|
|
|
1329 |
{ basefont-V } { basefont-H } ifelse setfont
|
|
|
1330 |
strokewidth setlinewidth
|
|
|
1331 |
1 setlinejoin
|
|
|
1332 |
newpath
|
|
|
1333 |
|
|
|
1334 |
|
|
|
1335 |
currentpoint setcharwidth
|
|
|
1336 |
end
|
|
|
1337 |
grestore
|
|
|
1338 |
} bind def
|
|
|
1339 |
|
|
|
1340 |
currentdict
|
|
|
1341 |
end
|
|
|
1342 |
dup /CIDFontName get exch /CIDFont defineresource
|
|
|
1343 |
} bind def
|
|
|
1344 |
|
|
|
1345 |
% <CIDFont-resource> <CIDFontName> findCIDFont <CIDFont-resource> <font>
|
|
|
1346 |
% CIDFont-resource is not modified.
|
|
|
1347 |
/findCIDFont {
|
|
|
1348 |
{
|
|
|
1349 |
dup /CIDFont resourcestatus {
|
|
|
1350 |
pop pop /CIDFont findresource
|
|
|
1351 |
exit
|
|
|
1352 |
} if
|
|
|
1353 |
.remove_font_name_prefix
|
|
|
1354 |
dup dup length string cvs
|
|
|
1355 |
(,Bold) tailmatch {
|
|
|
1356 |
exch pop
|
|
|
1357 |
cvn findCIDFont 0.03 makeboldfont
|
|
|
1358 |
exit
|
|
|
1359 |
} if
|
|
|
1360 |
(,Italic) tailmatch {
|
|
|
1361 |
exch pop
|
|
|
1362 |
cvn findCIDFont
|
|
|
1363 |
[ 1 0 0.3 1 0 0 ] makefont
|
|
|
1364 |
exit
|
|
|
1365 |
} if
|
|
|
1366 |
(,BoldItalic) tailmatch {
|
|
|
1367 |
exch pop
|
|
|
1368 |
cvn findCIDFont 0.03 makeboldfont
|
|
|
1369 |
[ 1 0 0.3 1 0 0 ] makefont
|
|
|
1370 |
exit
|
|
|
1371 |
} if
|
|
|
1372 |
pop
|
|
|
1373 |
|
|
|
1374 |
1 index /CIDSystemInfo get begin Registry (-) Ordering end
|
|
|
1375 |
concatstrings concatstrings
|
|
|
1376 |
cvn
|
|
|
1377 |
QUIET not {
|
|
|
1378 |
(Substituting CID font resource) print dup ==only
|
|
|
1379 |
( for ) print 1 index ==only (.\n) print
|
|
|
1380 |
} if
|
|
|
1381 |
exch pop
|
|
|
1382 |
/CIDFont findresource
|
|
|
1383 |
exit
|
|
|
1384 |
} loop
|
|
|
1385 |
} bdef
|
|
|
1386 |
|
|
|
1387 |
/buildCIDType0 { % <CIDFontType0-font-resource> buildCIDType0 <font>
|
|
|
1388 |
dup /BaseFont get findCIDFont exch pop
|
|
|
1389 |
} bdef
|
|
|
1390 |
|
|
|
1391 |
/buildCIDType2 { % <CIDFontType2-font-resource> buildCIDType2 <font>
|
|
|
1392 |
dup /BaseFont get findCIDFont exch pop
|
|
|
1393 |
} bdef
|
|
|
1394 |
|
|
|
1395 |
/processCIDToGIDMap { % <fontres> <cidfont> processCIDToGIDMap <fontres> <cidfont>
|
|
|
1396 |
1 index /CIDToGIDMap knownoget {
|
|
|
1397 |
PDFfile fileposition 4 1 roll
|
|
|
1398 |
dup /Identity eq {
|
|
|
1399 |
pop
|
|
|
1400 |
} {
|
|
|
1401 |
true resolvestream
|
|
|
1402 |
% Stack: filepos fontres font mapstream
|
|
|
1403 |
% Can't know the length of the decompressed stream, so allocate a big buffer...
|
|
|
1404 |
dup 65534 string readstring {
|
|
|
1405 |
% Length exceeded max string size, use an array of two strings
|
|
|
1406 |
1 index 65534 string readstring pop % maybe a null string - not important.
|
|
|
1407 |
2 array astore
|
|
|
1408 |
% Stack: filepos fontres font mapstream array
|
|
|
1409 |
dup 1 get length 65534 add
|
|
|
1410 |
} {
|
|
|
1411 |
dup length
|
|
|
1412 |
} ifelse
|
|
|
1413 |
2 idiv
|
|
|
1414 |
% Stack: filepos fontres font mapstream array/string CIDCount
|
|
|
1415 |
3 index exch /CIDCount exch put
|
|
|
1416 |
exch closefile exch
|
|
|
1417 |
dup /CIDMap 4 -1 roll put
|
|
|
1418 |
} ifelse
|
|
|
1419 |
3 2 roll PDFfile exch setfileposition
|
|
|
1420 |
} if
|
|
|
1421 |
} bdef
|
|
|
1422 |
|
|
|
1423 |
% Adjust a CIDFontType0 DW[2] in the font resource.
|
|
|
1424 |
/adjustCIDType0 { % <font-resource> <font> adjustfont <font'>
|
|
|
1425 |
addCIDmetrics
|
|
|
1426 |
dup /CIDFontName get exch /CIDFont defineresource
|
|
|
1427 |
} bind def
|
|
|
1428 |
|
|
|
1429 |
% Adjust a CIDFontType2 DW[2] and CIDToGIDMap in the font resource.
|
|
|
1430 |
/adjustCIDType2 { % <font-resource> <font> adjustfont <font'>
|
|
|
1431 |
addCIDmetrics
|
|
|
1432 |
processCIDToGIDMap
|
|
|
1433 |
dup /CIDFontName get exch /CIDFont defineresource
|
|
|
1434 |
} bind def
|
|
|
1435 |
|
|
|
1436 |
% ---------------- Other embedded fonts ---------------- %
|
|
|
1437 |
|
|
|
1438 |
/fontloadprocs mark
|
|
|
1439 |
/Type1C /readType1C cvx
|
|
|
1440 |
/CIDFontType0C /readCIDFontType0C cvx
|
|
|
1441 |
.dicttomark readonly def
|
|
|
1442 |
|
|
|
1443 |
% Read an embedded compressed font.
|
|
|
1444 |
/readType1C { % <font-resource> <stream-dict> readType1C <font>
|
|
|
1445 |
1 index exch
|
|
|
1446 |
PDFfile fileposition 3 1 roll
|
|
|
1447 |
dup true resolvestream dup readfontfilter
|
|
|
1448 |
% Stack: pos resource streamdict stream filter
|
|
|
1449 |
3 index /FontDescriptor oget /FontName oget
|
|
|
1450 |
1 index FRD
|
|
|
1451 |
closefile closefile pop
|
|
|
1452 |
PDFfile 3 -1 roll setfileposition
|
|
|
1453 |
/FontDescriptor oget /FontName oget pdfaddcachedfont
|
|
|
1454 |
exch pop
|
|
|
1455 |
} bdef
|
|
|
1456 |
|
|
|
1457 |
% Read an embedded CFF CIDFont.
|
|
|
1458 |
/readCIDFontType0C { % <font-resource> <stream-dict> readCIDFontType0C <font>
|
|
|
1459 |
PDFfile fileposition 3 1 roll
|
|
|
1460 |
dup true resolvestream dup readfontfilter
|
|
|
1461 |
% Stack: pos resource streamdict stream filter
|
|
|
1462 |
3 index /FontDescriptor oget /FontName oget
|
|
|
1463 |
1 index FRD
|
|
|
1464 |
closefile closefile pop
|
|
|
1465 |
PDFfile 3 -1 roll setfileposition
|
|
|
1466 |
% Some broken Adobe software produces PDF files in which
|
|
|
1467 |
% the FontName of the CFF font and the FontName in the
|
|
|
1468 |
% FontDescriptor don't match the BaseFont in the font.
|
|
|
1469 |
% Use the FontName, rather than the BaseFont, here.
|
|
|
1470 |
dup /FontDescriptor oget /FontName oget /CIDFont findresource
|
|
|
1471 |
addCIDmetrics dup /CIDFontName get exch /CIDFont defineresource
|
|
|
1472 |
} bdef
|
|
|
1473 |
|
|
|
1474 |
% ---------------- Font lookup ---------------- %
|
|
|
1475 |
|
|
|
1476 |
/fonttypeprocs mark % <font-resource> -proc- <font>
|
|
|
1477 |
/Type0 //buildType0
|
|
|
1478 |
/Type1 //buildType1
|
|
|
1479 |
/MMType1 //buildType1
|
|
|
1480 |
/Type3 //buildType3
|
|
|
1481 |
/TrueType //buildTrueType
|
|
|
1482 |
/CIDFontType0 //buildCIDType0
|
|
|
1483 |
/CIDFontType2 //buildCIDType2
|
|
|
1484 |
.dicttomark readonly def
|
|
|
1485 |
|
|
|
1486 |
/adjustfonttypes mark
|
|
|
1487 |
/Type1 //adjustfont
|
|
|
1488 |
/MMType1 //adjustfont
|
|
|
1489 |
/TrueType //adjustfont
|
|
|
1490 |
/CIDFontType0 //adjustCIDType0
|
|
|
1491 |
/CIDFontType2 //adjustCIDType2
|
|
|
1492 |
.dicttomark readonly def
|
|
|
1493 |
|
|
|
1494 |
/resourcefont % <font-resource> resourcefont <font>
|
|
|
1495 |
{ dup /PSFont .knownget
|
|
|
1496 |
{ /FID knownoget { type /fonttype eq } { //false } ifelse }
|
|
|
1497 |
{ //false }
|
|
|
1498 |
ifelse
|
|
|
1499 |
{ /PSFont get }
|
|
|
1500 |
{ dup dup /FontDescriptor knownoget { % Stack: font-res font-res font-desc
|
|
|
1501 |
dup /FontObject .knownget {
|
|
|
1502 |
3 1 roll pop pop
|
|
|
1503 |
} {
|
|
|
1504 |
dup /FontFile knownoget
|
|
|
1505 |
{ dup /Length oget 0 eq
|
|
|
1506 |
{ pop pop dup /Subtype get fonttypeprocs exch get exec }
|
|
|
1507 |
{ exch pop readtype1 }
|
|
|
1508 |
ifelse
|
|
|
1509 |
}
|
|
|
1510 |
{
|
|
|
1511 |
dup /FontFile2 knownoget
|
|
|
1512 |
{ exch pop readtruetype }
|
|
|
1513 |
{ /FontFile3 knownoget
|
|
|
1514 |
{ dup /Subtype get fontloadprocs exch get exec }
|
|
|
1515 |
{ dup /Subtype get fonttypeprocs exch get exec }
|
|
|
1516 |
ifelse
|
|
|
1517 |
}
|
|
|
1518 |
ifelse
|
|
|
1519 |
}
|
|
|
1520 |
ifelse
|
|
|
1521 |
1 index /FontDescriptor oget
|
|
|
1522 |
1 index /FontObject exch put % Save pointer to the font
|
|
|
1523 |
}
|
|
|
1524 |
ifelse
|
|
|
1525 |
}
|
|
|
1526 |
{ dup /Subtype get fonttypeprocs exch dup () cvn eq {
|
|
|
1527 |
( **** Warning: Font missing required Subtype, /Type1 assumed.\n)
|
|
|
1528 |
pdfformaterror
|
|
|
1529 |
pop /Type1
|
|
|
1530 |
} if get exec
|
|
|
1531 |
}
|
|
|
1532 |
ifelse
|
|
|
1533 |
% Stack: font-res font
|
|
|
1534 |
1 index 3 1 roll
|
|
|
1535 |
1 index /Subtype get
|
|
|
1536 |
//adjustfonttypes exch .knownget { exec } { exch pop } ifelse
|
|
|
1537 |
dup 3 1 roll /PSFont exch put
|
|
|
1538 |
}
|
|
|
1539 |
ifelse
|
|
|
1540 |
dup checkGlyphNames2Unicode
|
|
|
1541 |
} bdef
|
|
|
1542 |
|
|
|
1543 |
drawopdict begin
|
|
|
1544 |
/d0 {
|
|
|
1545 |
.adjustcharwidth setcharwidth
|
|
|
1546 |
} bdef
|
|
|
1547 |
/d1 {
|
|
|
1548 |
4 index 0 ne {
|
|
|
1549 |
% invalid wy parameter for d1 in Type3 font (must be 0)
|
|
|
1550 |
% Even though the PDF 1.4 specification states that this must be 0,
|
|
|
1551 |
% Distiller sometimes creates Type3 fonts with non-zero wy. We set
|
|
|
1552 |
% it to 0 since this is apparently what Acrobat Reader 4 and 5 do,
|
|
|
1553 |
% but if the specification is ever changed to allow non-zero wy, this
|
|
|
1554 |
% will not work.
|
|
|
1555 |
5 -1 roll pop 0 5 1 roll % set wy to 0
|
|
|
1556 |
} if
|
|
|
1557 |
|
|
|
1558 |
2 copy % ... llx lly urx ury | urx ury
|
|
|
1559 |
|
|
|
1560 |
3 index 6 index eq and % ... llx lly urx ury | ury!=0 (urx!=0 && llx==urx)
|
|
|
1561 |
exch 2 index 5 index eq and or { % ... llx lly urx ury | (urx!=0 && llx==urx) || (ury!=0 && lly==ury)
|
|
|
1562 |
% The bounding box is empty and likely incorrect. Don't cache.
|
|
|
1563 |
pop pop pop pop .adjustcharwidth setcharwidth
|
|
|
1564 |
} {
|
|
|
1565 |
6 -2 roll .adjustcharwidth 6 2 roll setcachedevice
|
|
|
1566 |
} ifelse
|
|
|
1567 |
} bdef
|
|
|
1568 |
/Tf {
|
|
|
1569 |
1 index Page /Font rget not { 1 index /invalidfont signalerror } if
|
|
|
1570 |
resourcefont exch Tf pop
|
|
|
1571 |
} bdef
|
|
|
1572 |
end
|
|
|
1573 |
|
|
|
1574 |
end % pdfdict
|
|
|
1575 |
end % GS_PDF_ProcSet
|
|
|
1576 |
.setglobal
|