123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863 |
- % Copyright (C) 1994, 2000 Aladdin Enterprises. All rights reserved.
- %
- % This software is provided AS-IS with no warranty, either express or
- % implied.
- %
- % This software is distributed under license and may not be copied,
- % modified or distributed except as expressly authorized under the terms
- % of the license contained in the file LICENSE in this distribution.
- %
- % For more information about licensing, please refer to
- % http://www.ghostscript.com/licensing/. For information on
- % commercial licensing, go to http://www.artifex.com/licensing/ or
- % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
- % San Rafael, CA 94903, U.S.A., +1(415)492-9861.
-
- % $Id: pdf_font.ps 10722 2010-02-08 16:45:18Z ken $
- % 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
- >> 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) pdfformaterror
- }
- { dup /BaseEncoding knownoget
- { dup / eq
- { pop
- ( **** Warning: Ignoring bad BaseEncoding name.\n) pdfformaterror
- % as found in a PDF file from J.D.Edwards OneWorld (B7333), bug 687786
- }
- { findencoding 3 -1 roll pop exch }
- ifelse
- }
- if
- /Differences knownoget { updateencoding } if
- }
- ifelse
- }
- ifelse
- } {
- pop
- ( **** Warning: Encoding not present.\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 == ==} 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 { .completefont } 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. All other cases are left unchanged.
- dup /FontType get 42 eq
- 2 index /Subtype get /TrueType eq and {
- //null
- } {
- 1 index /Encoding known {
- dup /Encoding knownoget { 2 index getencoding } { //null } ifelse
- } {
- //null
- } 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 known {
- 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) pdfformaterror
- 0
- } if def
- /LastChar 2 index /LastChar knownoget not {
- ( **** Warning: /LastChar attribute is missing, assuming 255.\n) pdfformaterror
- 255
- } if def
-
- Encoding length LastChar le {
- ( **** Warning: Font Encoding array size is smaller than character range.\n)
- pdfformaterror
- } 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)
- pdfformaterror
- /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
-
- % 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 3 dict begin
- /defineresource % <name> <dict> <cat-name> defineresource <dict>
- {
- pop
- dup userdict exch /.lastToUnicode exch put
- exch pop
- } bind def
- /CIDSystemInfo
- {
- ( **** Warning: ToUnicode CMap has invalid syntax near CIDSystemInfo.\n) pdfformaterror
- /CIDSystemInfo
- } bind def % 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) pdfformaterror
- /CMap1 % arbitrary, PDF defineresource tolerates non-unique names
- } bind def % A work around incorrect ToUnicode CMap generated by GS before rev. 6201.
- 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 -
- {
- PDFDEBUG {
- (.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
- {
- PDFDEBUG {
- dup ==
- } 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)
- PDFDEBUG {
- ( offset=) print 4 index =string cvs print
- ( key_size=) print 3 index =string cvs print
- ( value_size=) print 2 index =
- ( keys=) print 1 index ==
- ( values=) print dup ==
- } 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
- PDFDEBUG {
- ( defined single: ) print 1 index =string cvs print ( ) print dup ==
- } 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
- PDFDEBUG {
- ( 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
- PDFDEBUG {
- ( 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)
- PDFDEBUG {
- ( defined from range: ) print 1 index =string cvs print ( ) print dup ==
- } if
- true copy&def % e [] i offset key_size value_size (keys) (values) (value)
- % Assuming the lowest byte of 'value' changes, others don't.
- dup dup length 1 sub % e [] i offset key_size value_size (keys) (values) (value) (value) l
- 2 copy get % e [] i offset key_size value_size (keys) (values) (value) (value) l v
- % Modulo 256 increment prevents a rangecheck error when the result is stored in a string.
- % The adjustment can happen only at the end of the loop where the string is discarded. Bug 688535.
- 1 add 255 and put % e [] i offset key_size value_size (keys) (values) (value')
- } 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 %
- PDFDEBUG {
- (.convert_ToUnicode-into-g2u end) =
- } if
- } bind def
-
- /.processToUnicode % <font-resource> <font-dict> <encoding|null> .processToUnicode -
- {
- % Currently pdfwrite is only device which can handle GlyphNames2Unicoide to
- % generate a ToUnicode CMaps. So don't bother with other devices.
- currentdevice .devicename /pdfwrite eq {
- 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) pdfformaterror
- 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
-
- //false resolvestream
- //ToUnicodeCMapReader begin
- % Following Acrobat we ignore everything outside
- % begincodespacerange .. endcmap.
- dup 0 (begincodespacerange) /SubFileDecode filter flushfile
- /CIDInit /ProcSet findresource 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
-
- PDFfile exch setfileposition
- setuserparams
-
- 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
- } if
- PDFDEBUG {
- (.processToUnicode end) =
- } if
- } if
- pop pop pop
- } bind def
-
- % ---------------- 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 {
- ( **** /FontName attribute in FontDescriptor is not a name.\n)
- pdfformaterror
- cvn
- } if
- } {
- ( **** FontDescriptor missing required /FontName key. BaseFont name used.\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.
- 0 2 index .fontnameproperties 6 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 not {
- % 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
- % 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)
- pdfformaterror
- } if
- } if
-
- dup /UniqueID .knownget {
- dup dup 0 lt exch 16#ffffff gt or {
- ( **** Warning: Ignoring invalid /UniqueID = ) exch =string cvs
- concatstrings (\n) concatstrings pdfformaterror
- dup /UniqueID undef
- } {
- pop
- } ifelse
- } 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 {
- readonly
- } {
- ( **** Warning: Type 1 font applies operator readonly to a wrong type.\n)
- pdfformaterror
- } ifelse } .bind def
-
- /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>
- 1 index exch % res res stream
- PDFfile fileposition 3 1 roll % res pos res stream
- dup /PFB known exch % res pos res pfb? stream
- true resolvestream % res pos res pfb? file
- exch {
- //false /PFBDecode filter
- } 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 3 add dict copy begin
- 1 index /BaseFont oget /savedFontName exch def
- /topFontDict null def
- /readtype1dictcopy currentdict def
- { cvx exec } aload pop count 2 sub 3 packedarray cvx exec
- % clean up the dictstack
- { currentdict /topFontDict known not { end } { exit } ifelse } loop
- count exch sub { pop } repeat
- PDFfile 3 -1 roll setfileposition
- pop pop
- currentdict end end /topFontDict get
- } 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 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 /Subtype get /CIDFontType2 eq {
- 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 get 4 and 0 ne {
- //true % symbolic
- } {
- 1 index /Encoding oknown not % no encoding => symbolic
- } ifelse
- dup {
- //null
- } {
- StandardEncoding
- 3 index getencoding
- } ifelse % filepos fontres stream is_symbolic Encoding
- dup 4 index exch % filepos fontres stream is_symbolic Encoding fontres Encoding
- /prebuilt_encoding exch put % filepos fontres stream is_symbolic Encoding
- .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
- {
- ( **** Warning: CMap has invalid syntax near CIDSystemInfo.\n) pdfformaterror
- /CIDSystemInfo
- } bdef % A work around a bug in Altona.Page_3.2002-09-27.pdf - a slash is missed.
- /CMapName
- {
- ( **** Warning: CMap has no CMapName.\n\
- See the comment to revision 6201 in gs/doc/ps2pdf.htm#Problems .\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 embedded CMap stream.
- % Following Acrobat we ignore everything outside
- % begincodespacerange .. endcmap.
- /read_CMap { % <name> <1> <stream> read_CMap <CMap>
- % <2> <stream> read_CMap <CMap>
- dup 0 (begincodespacerange) /SubFileDecode filter flushfile
-
- //CMap_read_dict begin
- /CIDInit /ProcSet findresource begin
- 12 dict begin
- /.last_CMap_def currentdict def % establish binding
- /CMapType 3 -1 roll def
- 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
- dup /CMapType get 1 eq {
- /CMap defineresource
- } if
- } 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
- } {
- PDFfile fileposition exch
- dup /CMapName oget exch
- //true resolvestream
- 1 exch read_CMap
- exch PDFfile exch setfileposition
- } 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 { 1 .pdfMakeInternalMTXArray } if } def
- /.pdfMakeInternalW2 { dup length 0 gt { 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
- cvn findCIDFont 0.03 makeboldfont
- exit
- } if
- (,Italic) tailmatch {
- exch pop
- cvn findCIDFont
- [ 1 0 0.3 1 0 0 ] makefont
- exit
- } if
- (,BoldItalic) tailmatch {
- exch pop
- cvn findCIDFont 0.03 makeboldfont
- [ 1 0 0.3 1 0 0 ] makefont
- exit
- } if
- QUIET not {
- (Can't find CID font ") print dup =string cvs print (".) =
- } if
- pop
-
- 1 index /CIDSystemInfo oget begin Registry (-) Ordering end
- concatstrings concatstrings
- cvn
- QUIET not {
- (Substituting CID font ) print dup ==only
- ( for ) print 1 index ==only (, see doc/Use.htm#CIDFontSubstitution.) =
- } if
- exch pop
- dup /CIDFont resourcestatus {
- pop pop /CIDFont findresource exit
- } if
- QUIET not {
- (The substitute CID font ") print dup =string cvs print
- (" is not provided either. Will exit with error.) =
- } 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
- % Can't know the length of the decompressed stream, so allocate a big buffer...
- dup 65534 string readstring {
- % Length exceeded max string size, use an array of two strings
- 1 index 65534 string readstring pop % maybe a null string - not important.
- 2 array astore
- % Stack: filepos fontres font mapstream array
- dup 1 get length 65534 add
- } {
- dup length
- } ifelse
- 2 idiv
- % Stack: filepos fontres font mapstream array/string CIDCount
- 3 index exch /CIDCount exch put
- exch closefile exch
- dup /CIDMap 4 -1 roll put
- } ifelse
- 3 2 roll PDFfile exch setfileposition
- } if
- } bdef
-
- % Adjust a CIDFontType0 DW[2] in the font resource.
- /adjustCIDType0 { % <font-resource> <font> adjustfont <font'>
- addCIDmetrics
- dup /CIDFontName get exch /CIDFont defineresource
- } bind def
-
- % Adjust a CIDFontType2 DW[2] and CIDToGIDMap in the font resource.
- /adjustCIDType2 { % <font-resource> <font> adjustfont <font'>
- addCIDmetrics
- dup /CIDFontType get 2 eq { % OpenType CFF font converts to CIDFontType 0
- processCIDToGIDMap % that ignores CIDMap.
- } if
- dup /CIDFontName get exch /CIDFont defineresource
- } bind def
-
- % ---------------- Other embedded fonts ---------------- %
-
- /fontloadprocs mark
- /Type1C /readType1C cvx
- /CIDFontType0C /readCIDFontType0C cvx
- .dicttomark readonly def
-
- % 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
- { exch pop exit } forall
- 7 1 roll
- 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 //false 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
-
- % <stream> run-fonttypeproc <font>
- /run-fonttypeproc {
- dup /Subtype knownoget not { 0 } if % res /subtype
- //fonttypeprocs 1 index known not {
- ( **** Warning: Font /Subtype attribute is wrong or missing, /Type1 assumed.\n)
- pdfformaterror
- pop /Type1
- } 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
- { ( **** Warning: Error reading font stream, loading font by the name\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
- dup /Subtype get
- fontloadprocs exch get exec
- } 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
-
- /resourcefont % <font-resource> resourcefont <font>
- { dup /PSFont .knownget dup {
- pop /FID knownoget dup { pop type /fonttype eq } if
- } if {
- /PSFont get
- } {
- 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 copy .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
- ( **** Warning: unrecognized font file starts with <) exch concatstrings
- pdfformaterror
- /no_stream % /key res res desc stream unknown_tag
- } ifelse
- } if
-
- //font_tag_dict exch get exec
-
- 1 index /FontDescriptor oget % /key res font desc
- 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
- 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 {
- .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 .adjustcharwidth setcharwidth
- } {
- 6 -2 roll .adjustcharwidth 6 2 roll setcachedevice
- } ifelse
- } bdef
- /Tf {
- 1 index Page /Font rget {
- resourcefont exch Tf pop
- }
- { % Bug 689037
- ( **** Warning: Tf refers to an unknown resource name: ) pdfformaterror
- 1 index .namestring pdfformaterror
- ( Assuming it's a font name.\n) pdfformaterror
- Tf
- } ifelse
- } bdef
- end
-
- end % pdfdict
- end % GS_PDF_ProcSet
- .setglobal
|