summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/tlgs/Resource/Init/pdf_font.ps')
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/pdf_font.ps296
1 files changed, 200 insertions, 96 deletions
diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps
index 9fb85f60b60..81b7af13c7b 100644
--- a/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps
@@ -621,89 +621,149 @@ currentdict end readonly def
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
+ 2 index /ToUnicode knownoget
+ {
+ dup type /nametype eq {
+ % This is contrary to the specification but it seems that Acrobat at least will accept
+ % a ToUnicode with a value of Identity-H *and* will use that for search, copy/paste.
+ % We can't pass through a name, so the best we can do is build a GlyphNames2Unicode
+ % map matching that which would have been generated by a full 16-bit Identity CMap
+ %
+ % See bug numbers 701003 and 687351
+ %
+ dup /Identity-H eq 1 index /Identity-V eq or{
+ pop
+ 1 index /FontInfo .knownget not {
+ currentglobal 2 index dup gcheck setglobal
+ /FontInfo 5 dict dup 5 1 roll .forceput
+ setglobal
+ } executeonly 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
+
+ 0 1 65535{
+ % g2u index
+ dup dup 256 mod exch 256 idiv % g2u index lo-byte hi-byte
+ 2 string dup 0 4 -1 roll % g2u index lo-byte () () 0 hi-byte
+ put % g2u index lo-byte (x)
+ dup 1 % g2u index lo-byte (x) (x) 1
+ 4 -1 roll put % g2u index (x) (x) 1 lo-byte -> dict index (xx)
+ 2 index % g2u index (xx) dict
+ 3 1 roll % g2u g2u index (xx)
+ put % g2u
+ } for
+ pop % font-res font-dict encoding|null font-info
+ pop % font-res font-dict encoding|null
+ //false % We built a GlyphNames2Unicode table, don't need to process further
+ } executeonly
+ {
+ //true % name is not Identity-V or H, fail by falling through
+ }ifelse
+ } executeonly
+ {
+ //true
+ } ifelse % not a name, try as a dictionary (as specified)
- 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
+ % If the ToUnicode isn't a name, or the name isn't Identity-V or -H then follow the specification
+ % If its not a dictionary type throw an error, otherwise decode it and build a GlyphNames2Unicode
+ %
+ {
+ 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
} {
- 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
+ /PDFScanRules .getuserparam dup //null eq {
+ pop //PDFScanRules_null
} {
- dup wcheck {
- //false % Existing, writeable G2U, don't make new one
+ 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
} {
- pop //true % Existing read only G2U, make new 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
- {
- 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
+ } if
+ PDFDEBUG {
+ (.processToUnicode end) =
+ } if
+ } executeonly if
+ } executeonly if
+ } executeonly stopped
{
.dstackdepth 1 countdictstack 1 sub
{pop end} for
@@ -850,9 +910,16 @@ setglobal
% No available good substitution, use the standard one.
pop 1 index .substitutefont
} if
- dup 3 index ne QUIET not and {
+ dup 3 index ne {
+ QUIET not {
(Substituting font ) print dup =only
( for ) print 2 index =only (.) = flush
+ } if
+ % Send a warning to the device, in case its pdfwrite and we are in PDF/A mode
+ % In that case the substituted font may not (probably doesn't) have glyphs which
+ % match the /Widths of the original font, and that will cause a fault with PDF/A
+ % so we need to let the device know.
+ /SubstitutedFont /EventInfo .special_op
} if
pdffindcachedfont
% Stack: font-res fontname fontdesc font
@@ -1233,19 +1300,20 @@ currentdict /eexec_pdf_param_dict .undef
//pdfdict /.Qqwarning_issued //true .forceput
} executeonly if
Q
- } repeat
+ } executeonly repeat
Q
- } PDFfile fileposition 2 .execn % Keep pdfcount valid.
+ } executeonly PDFfile fileposition 2 .execn % Keep pdfcount valid.
PDFfile exch setfileposition
- } ifelse
- } {
+ } executeonly ifelse
+ } executeonly
+ {
% 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
+ } executeonly bdef
dup currentdict Encoding .processToUnicode
currentdict end .completefont exch pop
} bind executeonly odef
@@ -1616,7 +1684,6 @@ currentdict /CMap_read_dict undef
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
} bind executeonly def
@@ -1864,6 +1931,12 @@ currentdict /CMap_read_dict undef
% <CIDFont-resource> <CIDFontName> findCIDFont <CIDFont-resource> <font>
% CIDFont-resource is not modified.
+% In various places we do:
+% "findCIDFont dup /OrigFont .knownget {exch pop} if"
+% because the CIDFont we find may have been "patched" to apply metrics from
+% the PDF file (W, W2, etc). We want to avoid applying those metrics more
+% than once, hence retrieving the original, unpatched CIDFont dictionary,
+% if it exists.
/findCIDFont {
{
dup /CIDFont resourcestatus {
@@ -1883,7 +1956,9 @@ currentdict /CMap_read_dict undef
% "Light,Bold" font, don't artificially bolden further
dup (Light) tailmatch
{
- pop cvn findCIDFont dup /FontName .knownget
+ pop cvn findCIDFont
+ dup /OrigFont .knownget {exch pop} if
+ dup /FontName .knownget
{
(Light) tailmatch exch pop
}
@@ -1897,13 +1972,16 @@ currentdict /CMap_read_dict undef
}
{
pop
- cvn findCIDFont 0.03 makeboldfont
+ cvn findCIDFont
+ dup /OrigFont .knownget {exch pop} if
+ 0.03 makeboldfont
} ifelse
exit
} if
(,Italic) tailmatch {
exch pop
cvn findCIDFont
+ dup /OrigFont .knownget {exch pop} if
[ 1 0 0.3 1 0 0 ] makefont
exit
} if
@@ -1912,7 +1990,9 @@ currentdict /CMap_read_dict undef
% see above
dup (Light) tailmatch
{
- pop cvn findCIDFont dup /FontName .knownget
+ pop cvn findCIDFont
+ dup /OrigFont .knownget {exch pop} if
+ dup /FontName .knownget
{
(Light) tailmatch exch pop
}
@@ -1926,7 +2006,9 @@ currentdict /CMap_read_dict undef
}
{
pop
- cvn findCIDFont 0.03 makeboldfont
+ cvn findCIDFont
+ dup /OrigFont .knownget {exch pop} if
+ 0.03 makeboldfont
} ifelse
[ 1 0 0.3 1 0 0 ] makefont
exit
@@ -2045,9 +2127,9 @@ currentdict /CMap_read_dict undef
(Will continue, but content may be missing.) = flush
} ifelse
} if
- } if
+ } executeonly if
/findresource cvx /undefined signalerror
- } loop
+ } executeonly loop
} bind executeonly odef
/buildCIDType0 { % <CIDFontType0-font-resource> buildCIDType0 <font>
@@ -2293,15 +2375,14 @@ currentdict /CMap_read_dict undef
{ exch pop readtype1
} 2 bndef
- <01000401> <01000402> <01000403> <01000404> % Type 1C
- <01000C02> <01000C03>
+ <01000401> % Type 1C
{ exch pop
1 index /Subtype knownoget dup { pop /CIDFontType0 eq } if {
readCIDFontType0C
} {
readType1C
} ifelse
- } 6 bndef
+ } bind executeonly def
<00010000> (true) (typ1) (ttcf) % TrueType OpenType
{ exch pop readtruetype
@@ -2466,14 +2547,37 @@ currentdict /bndef undef
% /key res res desc stream tag
//font_tag_dict 1 index known not {
+ %
+ % The tag is the first 4 (?) bytes frm the font stream, if we get here then
+ % it didn't match any of the keys in the dictionary. There seems to be
+ % a possibility that a PFB font could be undetected (because its only 2 bytes?)
+ % but the main problem is CFF fonts. These lack a magic number, and the header
+ % can vary in the last 3 of the 4 bytes. We've now found 7 different possible
+ % values for these bytes, adding more seems pointless and isn't future proof.
+ % Instead check the dictionary for its Subtype.
+ %
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
+ 1 index /Subtype known {
+ 1 index /Subtype get
+ dup /Type1C eq 1 index /CIDFontType0C eq or exch /CIDFontType1C eq or {
+ pop <01000401> % discard the data we read and pretend we read the original Type1C tag
+ //false
+ }{
+ //true
+ }ifelse
+ } {
+ //true % no /Subtype, give up.
+ }ifelse
+
+ {
+ (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
+ }if
} ifelse
} if
//font_tag_dict exch get % /key res res desc stream {proc}