diff options
Diffstat (limited to 'Master/texmf/doc/pdftex/manual/samplepdf')
-rw-r--r-- | Master/texmf/doc/pdftex/manual/samplepdf/pdfcolor.tex | 158 | ||||
-rw-r--r-- | Master/texmf/doc/pdftex/manual/samplepdf/pic.pdf | bin | 0 -> 36792 bytes | |||
-rw-r--r-- | Master/texmf/doc/pdftex/manual/samplepdf/rgb.icc | bin | 0 -> 744 bytes | |||
-rw-r--r-- | Master/texmf/doc/pdftex/manual/samplepdf/samplepdf.0 | 24 | ||||
-rw-r--r-- | Master/texmf/doc/pdftex/manual/samplepdf/samplepdf.tex | 1161 | ||||
-rw-r--r-- | Master/texmf/doc/pdftex/manual/samplepdf/supp-mis.tex | 695 | ||||
-rw-r--r-- | Master/texmf/doc/pdftex/manual/samplepdf/supp-pdf.tex | 2191 | ||||
-rw-r--r-- | Master/texmf/doc/pdftex/manual/samplepdf/tmp.pdf | bin | 0 -> 3031 bytes |
8 files changed, 4229 insertions, 0 deletions
diff --git a/Master/texmf/doc/pdftex/manual/samplepdf/pdfcolor.tex b/Master/texmf/doc/pdftex/manual/samplepdf/pdfcolor.tex new file mode 100644 index 00000000000..f09ecbcb750 --- /dev/null +++ b/Master/texmf/doc/pdftex/manual/samplepdf/pdfcolor.tex @@ -0,0 +1,158 @@ +% Very simple macros to show how to use colors with pdftex + +\def\cmykGreenYellow{0.15 0 0.69 0} +\def\cmykYellow{0 0 1 0} +\def\cmykGoldenrod{0 0.10 0.84 0} +\def\cmykDandelion{0 0.29 0.84 0} +\def\cmykApricot{0 0.32 0.52 0} +\def\cmykPeach{0 0.50 0.70 0} +\def\cmykMelon{0 0.46 0.50 0} +\def\cmykYellowOrange{0 0.42 1 0} +\def\cmykOrange{0 0.61 0.87 0} +\def\cmykBurntOrange{0 0.51 1 0} +\def\cmykBittersweet{0 0.75 1 0.24} +\def\cmykRedOrange{0 0.77 0.87 0} +\def\cmykMahogany{0 0.85 0.87 0.35} +\def\cmykMaroon{0 0.87 0.68 0.32} +\def\cmykBrickRed{0 0.89 0.94 0.28} +\def\cmykRed{0 1 1 0} +\def\cmykOrangeRed{0 1 0.50 0} +\def\cmykRubineRed{0 1 0.13 0} +\def\cmykWildStrawberry{0 0.96 0.39 0} +\def\cmykSalmon{0 0.53 0.38 0} +\def\cmykCarnationPink{0 0.63 0 0} +\def\cmykMagenta{0 1 0 0} +\def\cmykVioletRed{0 0.81 0 0} +\def\cmykRhodamine{0 0.82 0 0} +\def\cmykMulberry{0.34 0.90 0 0.02} +\def\cmykRedViolet{0.07 0.90 0 0.34} +\def\cmykFuchsia{0.47 0.91 0 0.08} +\def\cmykLavender{0 0.48 0 0} +\def\cmykThistle{0.12 0.59 0 0} +\def\cmykOrchid{0.32 0.64 0 0} +\def\cmykDarkOrchid{0.40 0.80 0.20 0} +\def\cmykPurple{0.45 0.86 0 0} +\def\cmykPlum{0.50 1 0 0} +\def\cmykViolet{0.79 0.88 0 0} +\def\cmykRoyalPurple{0.75 0.90 0 0} +\def\cmykBlueViolet{0.86 0.91 0 0.04} +\def\cmykPeriwinkle{0.57 0.55 0 0} +\def\cmykCadetBlue{0.62 0.57 0.23 0} +\def\cmykCornflowerBlue{0.65 0.13 0 0} +\def\cmykMidnightBlue{0.98 0.13 0 0.43} +\def\cmykNavyBlue{0.94 0.54 0 0} +\def\cmykRoyalBlue{1 0.50 0 0} +\def\cmykBlue{1 1 0 0} +\def\cmykCerulean{0.94 0.11 0 0} +\def\cmykCyan{1 0 0 0} +\def\cmykProcessBlue{0.96 0 0 0} +\def\cmykSkyBlue{0.62 0 0.12 0} +\def\cmykTurquoise{0.85 0 0.20 0} +\def\cmykTealBlue{0.86 0 0.34 0.02} +\def\cmykAquamarine{0.82 0 0.30 0} +\def\cmykBlueGreen{0.85 0 0.33 0} +\def\cmykEmerald{1 0 0.50 0} +\def\cmykJungleGreen{0.99 0 0.52 0} +\def\cmykSeaGreen{0.69 0 0.50 0} +\def\cmykGreen{1 0 1 0} +\def\cmykForestGreen{0.91 0 0.88 0.12} +\def\cmykPineGreen{0.92 0 0.59 0.25} +\def\cmykLimeGreen{0.50 0 1 0} +\def\cmykYellowGreen{0.44 0 0.74 0} +\def\cmykSpringGreen{0.26 0 0.76 0} +\def\cmykOliveGreen{0.64 0 0.95 0.40} +\def\cmykRawSienna{0 0.72 1 0.45} +\def\cmykSepia{0 0.83 1 0.70} +\def\cmykBrown{0 0.81 1 0.60} +\def\cmykTan{0.14 0.42 0.56 0} +\def\cmykGray{0 0 0 0.50} +\def\cmykBlack{0 0 0 1} +\def\cmykWhite{0 0 0 0} + +\def\GreenYellow{\pdfsetcolor{\cmykGreenYellow}} +\def\Yellow{\pdfsetcolor{\cmykYellow}} +\def\Goldenrod{\pdfsetcolor{\cmykGoldenrod}} +\def\Dandelion{\pdfsetcolor{\cmykDandelion}} +\def\Apricot{\pdfsetcolor{\cmykApricot}} +\def\Peach{\pdfsetcolor{\cmykPeach}} +\def\Melon{\pdfsetcolor{\cmykMelon}} +\def\YellowOrange{\pdfsetcolor{\cmykYellowOrange}} +\def\Orange{\pdfsetcolor{\cmykOrange}} +\def\BurntOrange{\pdfsetcolor{\cmykBurntOrange}} +\def\Bittersweet{\pdfsetcolor{\cmykBittersweet}} +\def\RedOrange{\pdfsetcolor{\cmykRedOrange}} +\def\Mahogany{\pdfsetcolor{\cmykMahogany}} +\def\Maroon{\pdfsetcolor{\cmykMaroon}} +\def\BrickRed{\pdfsetcolor{\cmykBrickRed}} +\def\Red{\pdfsetcolor{\cmykRed}} +\def\OrangeRed{\pdfsetcolor{\cmykOrangeRed}} +\def\RubineRed{\pdfsetcolor{\cmykRubineRed}} +\def\WildStrawberry{\pdfsetcolor{\cmykWildStrawberry}} +\def\Salmon{\pdfsetcolor{\cmykSalmon}} +\def\CarnationPink{\pdfsetcolor{\cmykCarnationPink}} +\def\Magenta{\pdfsetcolor{\cmykMagenta}} +\def\VioletRed{\pdfsetcolor{\cmykVioletRed}} +\def\Rhodamine{\pdfsetcolor{\cmykRhodamine}} +\def\Mulberry{\pdfsetcolor{\cmykMulberry}} +\def\RedViolet{\pdfsetcolor{\cmykRedViolet}} +\def\Fuchsia{\pdfsetcolor{\cmykFuchsia}} +\def\Lavender{\pdfsetcolor{\cmykLavender}} +\def\Thistle{\pdfsetcolor{\cmykThistle}} +\def\Orchid{\pdfsetcolor{\cmykOrchid}} +\def\DarkOrchid{\pdfsetcolor{\cmykDarkOrchid}} +\def\Purple{\pdfsetcolor{\cmykPurple}} +\def\Plum{\pdfsetcolor{\cmykPlum}} +\def\Violet{\pdfsetcolor{\cmykViolet}} +\def\RoyalPurple{\pdfsetcolor{\cmykRoyalPurple}} +\def\BlueViolet{\pdfsetcolor{\cmykBlueViolet}} +\def\Periwinkle{\pdfsetcolor{\cmykPeriwinkle}} +\def\CadetBlue{\pdfsetcolor{\cmykCadetBlue}} +\def\CornflowerBlue{\pdfsetcolor{\cmykCornflowerBlue}} +\def\MidnightBlue{\pdfsetcolor{\cmykMidnightBlue}} +\def\NavyBlue{\pdfsetcolor{\cmykNavyBlue}} +\def\RoyalBlue{\pdfsetcolor{\cmykRoyalBlue}} +\def\Blue{\pdfsetcolor{\cmykBlue}} +\def\Cerulean{\pdfsetcolor{\cmykCerulean}} +\def\Cyan{\pdfsetcolor{\cmykCyan}} +\def\ProcessBlue{\pdfsetcolor{\cmykProcessBlue}} +\def\SkyBlue{\pdfsetcolor{\cmykSkyBlue}} +\def\Turquoise{\pdfsetcolor{\cmykTurquoise}} +\def\TealBlue{\pdfsetcolor{\cmykTealBlue}} +\def\Aquamarine{\pdfsetcolor{\cmykAquamarine}} +\def\BlueGreen{\pdfsetcolor{\cmykBlueGreen}} +\def\Emerald{\pdfsetcolor{\cmykEmerald}} +\def\JungleGreen{\pdfsetcolor{\cmykJungleGreen}} +\def\SeaGreen{\pdfsetcolor{\cmykSeaGreen}} +\def\Green{\pdfsetcolor{\cmykGreen}} +\def\ForestGreen{\pdfsetcolor{\cmykForestGreen}} +\def\PineGreen{\pdfsetcolor{\cmykPineGreen}} +\def\LimeGreen{\pdfsetcolor{\cmykLimeGreen}} +\def\YellowGreen{\pdfsetcolor{\cmykYellowGreen}} +\def\SpringGreen{\pdfsetcolor{\cmykSpringGreen}} +\def\OliveGreen{\pdfsetcolor{\cmykOliveGreen}} +\def\RawSienna{\pdfsetcolor{\cmykRawSienna}} +\def\Sepia{\pdfsetcolor{\cmykSepia}} +\def\Brown{\pdfsetcolor{\cmykBrown}} +\def\Tan{\pdfsetcolor{\cmykTan}} +\def\Gray{\pdfsetcolor{\cmykGray}} +\def\Black{\pdfsetcolor{\cmykBlack}} +\def\White{\pdfsetcolor{\cmykWhite}} + +\def\pdfsetcolor#1{\pdfliteral{#1 k}} +\def\setcolor#1{\mark{#1}\pdfsetcolor{#1}} + +\pdfoutput=1 +\def\maincolor{\cmykBlack} +\pdfsetcolor{\maincolor} + +\def\makefootline{ + \baselineskip24pt + \line{\pdfsetcolor{\maincolor}\the\footline}} + +\def\makeheadline{% + \edef\M{\topmark} + \ifx\M\empty\let\M=\maincolor\fi + \vbox to 0pt{\vskip-22.5pt + \line{\vbox to8.5pt{}% + \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\M}}\vss}% + \nointerlineskip} diff --git a/Master/texmf/doc/pdftex/manual/samplepdf/pic.pdf b/Master/texmf/doc/pdftex/manual/samplepdf/pic.pdf Binary files differnew file mode 100644 index 00000000000..4f20d12a6d0 --- /dev/null +++ b/Master/texmf/doc/pdftex/manual/samplepdf/pic.pdf diff --git a/Master/texmf/doc/pdftex/manual/samplepdf/rgb.icc b/Master/texmf/doc/pdftex/manual/samplepdf/rgb.icc Binary files differnew file mode 100644 index 00000000000..d9c712f6905 --- /dev/null +++ b/Master/texmf/doc/pdftex/manual/samplepdf/rgb.icc diff --git a/Master/texmf/doc/pdftex/manual/samplepdf/samplepdf.0 b/Master/texmf/doc/pdftex/manual/samplepdf/samplepdf.0 new file mode 100644 index 00000000000..9622d8d13fd --- /dev/null +++ b/Master/texmf/doc/pdftex/manual/samplepdf/samplepdf.0 @@ -0,0 +1,24 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: -2 -2 403 252 +%%HiResBoundingBox: -1.99992 -2 402.00008 252 +%%Creator: MetaPost 0.901 +%%CreationDate: 2005.06.23:1538 +%%Pages: 1 +%%BeginProlog +%%EndProlog +%%Page: 1 1 + 0 0.6 0 setrgbcolor 0 4 dtransform truncate idtransform setlinewidth pop + [] 0 setdash 1 setlinecap 1 setlinejoin 10 setmiterlimit +gsave newpath 400.00008 0 moveto +388.05362 20.69193 369.76968 36.62247 350.00008 50 curveto +236.22455 126.98863 70.53836 127.82376 0.00008 250 curveto +-1 1 scale stroke grestore + 0 2 dtransform truncate idtransform setlinewidth pop +gsave newpath 350.00008 50 moveto +309.8453 199.85959 97.68582 152.31425 0.00008 250 curveto +-1 1 scale stroke grestore +gsave newpath 350.00008 50 moveto +195.84702 50 37.96687 108.30608 0.00008 250 curveto +-1 1 scale stroke grestore +showpage +%%EOF diff --git a/Master/texmf/doc/pdftex/manual/samplepdf/samplepdf.tex b/Master/texmf/doc/pdftex/manual/samplepdf/samplepdf.tex new file mode 100644 index 00000000000..a9e2d655774 --- /dev/null +++ b/Master/texmf/doc/pdftex/manual/samplepdf/samplepdf.tex @@ -0,0 +1,1161 @@ +% This example shows how to use pdfTeX primitives. High-level macros are provided +% by macros packages like LaTeX or ConTeXt. We present basic set of commands, +% extended with some more sophisticated issues (like MP to PDF conversion). All +% the functionality other than provided by pdfTeX itself is commented by default. +% Please follow the code below and uncomment fragments you want. + +% Many new features has been implemented since the first release of pdfTeX. To +% make this sample version independent, we use compatibility sections. + +\def\ifversion#1.#2#3#4 {% 1.20, 1.30.0 ... + \ifnum\pdftexversion<#1#2#3 + \notsupported + \else + \supported + \fi} + +\def\supported{\expandafter\iftrue} +\def\notsupported{\expandafter\iffalse} + +\def\feature#1.#2#3#4#{\dofeature{#1#2#3}{#1.#2#3#4}} +\long\def\dofeature#1#2#3#4\endfeature{% + \ifnum#1>\pdftexversion + #3 not supported by this version of \pdfTeX.\par + \else#4\fi} + +\def\pdfTeX{pdf\TeX} +\def\primitive#1{{\tt\char92\relax#1}} +\def\newpage{\null\vfill\eject} + +\parindent=0pt + +\input pdfcolor.tex % simple macros to use color with pdftex; + % color names derived from dvicolor.tex + +% Unless mentioned explicitly, the default values of new parameters +% are: 1) zero for integer/dimension parameters; 2) empty for tokens +% parameters. + +% In previous versions of pdfTeX, integer parameters took their corresponding +% values from pdftex.cfg config file. Starting from pdfTeX 1.20, the config file +% id not read at all. All the parameters are specified in TeX code, optionally +% dumped into format file. + +\pdfoutput=1 % positive value turns on PDF output; + % this parameter can not be changed after the pdf + % output has been opened + +\pdfcompresslevel=0 % compression level for text and image; allowed + % values are 0..9; + % 0 = no compression + % 1 = fastest compression + % 9 = best compression + % 2..8 = something between + % numbers out of range will be fixed to the most + % closed allowed value. Recommended value for most + % cases is 6 or 7. + +\pdfdecimaldigits=3 % number of digits after decimal point for real + % number in pdf output; the larger value the + % better accuracy but also larger output size; + % allowed range of values is 0..4 + +%\pdfmovechars=2 % 1 turns on moving lower chars 0..32 to higher + % slots for fonts with last char code < 128, + % 2 or larger even for fonts with last char code > 127 + % (rather obsolete) + +\pdfpkresolution=300 % resolution for bitmap (PK) fonts; allowed values + % are 72..1200, default is 600 + +\pdfuniqueresname=0 % positive value turns on prepending unique + % prefix for each named resources + % pdftex-0.14[ef] has a bug with this feature + % turned on + +% dimension parameters + +\pdfhorigin=1in % horizontal origin (offset); + % for common purposes it is advised to use + % \hoffset + +\pdfvorigin=1in % vertical origin (offset); similar to \pdfhorigin, + % advised to use \voffset + + +\pdfpagewidth=8.5in % paper size of the pdf output (letter in this case) +\pdfpageheight=11in + +\pdflinkmargin=1pt % margin added to dimensions of link (see below) + +\pdfdestmargin=10pt % margin added to dimensions of destination (see + % below) + +\pdfthreadmargin=1em % margin added to dimensions of bead in article thread + % (see below) + +% tokens registers + +\pdfpagesattr={/MyPageAttribute /MyValue} + % optional attributes for the root Pages object; + % all pages inherit these attributes + +\pdfpageattr={/MyPagesAttribute /MyValue} + % optional attributes for individual pages; + % attributes specified here overwrite any + % attributes given by `\pdfpagesattr' (see PDF spec for details) + +\pdfpageresources{/MyPageResourceAttribute /MyValue} + % optional page resources dict content + +% And some more parameters that need special care. + +\ifversion 1.30.0 \else + \let\pdfforcepagebox\pdfoptionalwaysusepdfpagebox +\fi + +\pdfforcepagebox=0 % a page box of PDF inclusions to be used + % as a clipping area. Here we use default (CropBox) + % \pdfforcepagebox is a shortened synonym of + % obsolete \pdfoptionalwaysusepdfpagebox. + +\ifversion 1.30.0 \else + \let\pdfminorversion\pdfoptionpdfminorversion +\fi + +\pdfminorversion=5 % version of created PDF files and allowed PDF inclusions. + % The default value is 4 that is enough in most cases (PDF 1.4). + % However, some pdfTeX features presented here requires + % PDF 1.5. Starting from pdfTeX 1.30.0, the command is called + % \pdfminorversion. + + + +\ifversion 1.30.0 \else + \let\pdfinclusionerrorlevel\pdfoptionpdfinclusionerrorlevel +\fi + +\pdfinclusionerrorlevel=0 % If the version of included PDF is greater than + % the one being typeset, by default an error is issued. + % If \pdfinclusionerrorlevel is set to one, warning only + % (synonym of obsolete \pdfoptionpdfinclusionerrorlevel). + +\ifversion1.30.0 +\pdfimagehicolor=1 % enables 16-bit colors for PNG inclusions; + % defaults to 1 if \pdfminorversion>=5, +\pdfimageapplygamma=1 % enables gamma correction for PNG inclusions, +\pdfgamma=1000 % sets pdfTeX `device gamma,' +\pdfimagegamma=2200 % sets image gamma, if can't be taken from the image itself. +\fi % (see below for details). + +% Version of pdftex can be accessed via \pdftexversion and \pdftexrevision. + +This is version \the\pdftexversion\ (revision \pdftexrevision) of \pdfTeX. + +% Version of created PDF (and the highest allowed version of PDF inclusions) +% can be controlled with \pdfminorversion. In pdfTeX versions below 1.30.0, the +% primitive was called \pdfoptionpdfminorversion. + +This file is PDF version 1.\the\pdfminorversion. +\bigskip + +% Font resource in the pdf output has the form +% "/F<number> <object number> 0 R", where <number> is accessible via +% \pdffontname and <object number> via \pdffontobjnum. + +Font \fontname\font\ has resource name tag +\pdffontname\font\ and object number \pdffontobjnum\font\ in the PDF output. +Font size is \pdffontsize\font.\par + +\feature 1.30.0 {Disabling ligatures} + +Ligatures: ffont, fint, flint\par +{\font\noli=cmr10 at\pdffontsize\font + \pdfnoligatures\noli No ligatures: ffont, fint, flint} +\bigskip + +\endfeature + +% \pdfincludechars can be used to ensure certain characters to be +% included in the font file. Normally only used characters are +% included (subset is created). + +\pdfincludechars\font{ABCDEF} + +% pdfTeX ignores \special's text if \pdfoutput is set, unless they have +% prefix "pdf:" or "PDF:" (in this case the prefix is not written out, of +% course). \pdfliteral is intended to replace \special in pdf output mode. + +Changing color can be done by inserting `raw' PDF code, like +\pdfliteral direct{0 1 1 0 k} % switch color to red; using \pdfliteral is +this. % recommended + +\special{PDF:0 g} % switch color back to black; \special can be + % used with prefix "pdf:" or "PDF:", optionally appended with + % "direct:" + % A `direct' keyword is optional; it ensures that what one + % types into \pdfliteral is inserted literally indeed. + % Otherwise pdfTeX moves the space origin to the place after + % the last types item on the page, inserts the user code and + % restores its internal position. + +A simple picture: +\pdfliteral {q 1 j 0 1 0 rg 0 0 1 RG 0 0 10 10 re B Q} + +% Roughly speaking, pdfTeX typeset text having an origin in lower-left corner of +% the page (native PDF space origin). \pdfliteral used without `direct' keyword +% changes this position temporarily to the point user probably expect. Thanks to +% that, the rectangle painted above appears in-line, not in the lower-left corner +% of the page. If one say \pdfliteral{...}\pdfliteral{...}, pdfTeX makes the +% offset only once; it moves to current point of the page before the first +% literal content, and comes back after the last one. + +\bigskip + +% User-defined object can be inserted into the pdf output by \pdfobj. The +% object is written out as specified, apart from case when \pdfobj is used with +% "stream" option. An object created by \pdfobj is held in memory and will +% not be written to the pdf output, unless 1) the object is referenced by +% saying \pdfrefobj <object number>; or 2) \pdfobj is preceded by +% \immediate. The object number of the last object created by \pdfobj is +% accessible via \pdflastobj + +\pdfobj{Hello} % the simplest case +\pdfrefobj \pdflastobj % mark the object to be written out; it can be + % understood as a reference to the object + +\immediate \pdfobj stream % create the object as a stream a write it to + {Hello} % the pdf output immediately + +\pdfobj stream % create the object as a stream with + attr {/MyStreamAttribute /MyValue} % additional attributes + {Hello} +\pdfrefobj \pdflastobj + +\pdfobj file {obj.dat} % read the object contents from file obj.dat +\pdfrefobj \pdflastobj + +\pdfobj stream % read the stream contents from file obj.dat + file {obj.dat} +\pdfrefobj \pdflastobj + +\pdfobj stream % read the stream contents from file obj.dat + attr {/MyStreamAttribute /MyValue} % with additional attributes + file {obj.dat} +\pdfrefobj \pdflastobj + +% \pdflastobj is always global, as all others \pdflast* read-only integers (see +% below). PDF object numbers are unique within the document. One may notice, that +% if \pdfobj is preceded by \immediate, \pdflastobj seems to return subsequent +% values (i.e 5,6,7,8...). Since \pdfobj is not the only command that creates PDF +% objects, one can't simply assume, that if current \pdflastobj returns 5, the +% next one will always return 6. Thus, pdfTeX provides a forward-referencing +% mechanism (introduced in pdfTeX 1.20). + +\feature 1.20 {Forward object referencing} + +\pdfobj reserveobjnum +We have an access to PDF object numbers, even before defining those objects. +\pdfobj useobjnum\pdflastobj {(This is object number \the\pdflastobj)} +\pdfrefobj\pdflastobj + +\endfeature + +% TeX boxes can be written into so-called XObject form, which is very +% similar to a normal page in the pdf output. Additional data can be +% inserted to the XObject form dictionary itself as well as the Resource +% dictionary of the XObject form + +\setbox0=\hbox{This is a box saved as a XObject form} +\pdfxform + attr {/MyXObjectFormAttribute /MyValue} + resources {/MyXObjectFormResourceAttribute /MyValue} + 0 + +% Similarly to \pdfobj, the object created by \pdfxform is held in memory +% and is not written to the pdf output, unless 1) the object is referenced +% by saying \pdfrefxform <object number>; or 2) \pdfxform is preceded by +% \immediate. The object number of the last XObject form created +% by \pdfxform is accessible via \pdflastxform. Note that +% \immediate\pdfxform does not typeset anything; it just ensures that the +% XObject form is written out to the output. To display the form, it is +% necessary to say \pdfrefxform <object number> in the intended place. +% Another point is that \pdfrefxform acts similarly rather to rules than to +% boxes concerning dimensions and space setting. It's highly recommended to +% wrap \pdfrefxform by a box in order to ensure spacing will be correct. + +\hbox{\pdfrefxform \pdflastxform} + +% Similarly to \pdflastobj, \pdflastxform returns the PDF object number assigned +% for XObject form just created. pdfTeX also provides \pdfxformname primitive, that +% returns a resource name identifier of the XObject written to PDF output with given +% object number. + +XObject above has been written as object \the\pdflastxform. + +\feature 1.30.0 {Access to XObject names} + +Its resource name tag is \pdfxformname\pdflastxform\ +({\tt/Fm\pdfxformname\pdflastxform\ \the\pdflastxform\space 0 R} +entry in page resources dictionary). + +\endfeature + +\bigskip + +% Thanks to Taco Hoekwater pdfTeX 1.30.0 and higher provides precise time +% measuring mechanism. \pdfelapsedtime primitive returns the time elapsed from +% the current run start. Time is measured in `scaled seconds' meaning that 65536 +% scaled seconds is 1 second. There is also \pdfresettimer primitive that causes +% zeroing the internal clock. + +{\catcode`\p=12 \catcode`\t=12 \gdef\WITHOUTPT#1pt{#1}} + \def\withoutpt#1{\expandafter\WITHOUTPT#1} % returns float-like string + +\feature 1.30.0 {Precise timer} + +\dimen0=\pdfelapsedtime sp +\pdfresettimer +It took \withoutpt\the\dimen0 \ seconds to typeset the whole stuff above. +To typeset the last two sentences it took \the\pdfelapsedtime\ `scaled seconds' +(1s/65536). +\bigskip + +\endfeature + +% Taco Hoekwater has also implemented random number support (introduced in 1.30.0) + +\feature 1.30.0 {Random numbers} + +Random seed initialized to \the\pdfrandomseed. +\pdfsetrandomseed\dimen0 % just saved elapsed time +We may change it, lets say to \the\pdfrandomseed.\par + +10 uniformly distributed random numbers [0..100]: +\count100=0 \loop + \pdfuniformdeviate101 + \advance\count100 by1 + \ifnum\count100<10, +\repeat.\par + +10 normally distributed random numbers: +\count100=0 \loop + \dimen0=\pdfnormaldeviate sp + $\withoutpt\the\dimen0$% + \advance\count100 by1 + \ifnum\count100<10, +\repeat.\par + +\bigskip + +\endfeature + +% Starting from pdfTeX 1.30.0, there is an expandable string comparison in pdfTeX. +% You can compare two strings lexicographically using \pdfstrcmp{<str1>}{<str2>}. +% The command returns -1, 0, or 1 as a comparison result. +% Both strings are expanded before being compared. +% \feature 1.30.0 {String comparison} +% \pdfstrcmp{a}{aa} returns -1 since 'a'<'aa' +% \pdfstrcmp{aa}{aa} returns 0 since 'aa'='aa' +% \pdfstrcmp{aaa}{abc} returns -1 since 'aaa'<'abc' +% \pdfstrcmp{abc}{ABC} returns 1 since 'aaa'>'ABC' +% \endfeature +% This is still experimental, as well as regex support + +% Thanks to Heiko Oberdiek, starting from pdfTeX 1.30.0 a set of expandable +% string handlers are available. \pdfescapestring converts its parameter into a +% form readable for PDF interpreters, escaping those characters that can be used +% in PDF string objects without quotation. Similarly, \pdfescapename converts its +% argument into PDF name, replacing special PDF characters with their hexadecimal +% representation preceded by `#'. \pdfescapehex takes an ASCII code of each +% character of its argument and converts this number into hexadecimal form. Last +% but not least, \pdfunescapehex treats each pair of characters as a hexadecimal +% number and returns an ASCII characters of given codes. All those commands +% expand their arguments before applying conversion. + +\feature 1.30.0 {PDF string handling} + +\def\sometext{Some text/(1)} +If there is a text `{\tt\sometext}',\par +in PDF string one should use {\tt(\pdfescapestring{\sometext}},\par +and in PDF name it would be {\tt/\pdfescapename {\sometext}}.\par +In hex form it looks like {\tt<\pdfescapehex{\sometext}>},\par +but you can always reverse it to get {\tt\pdfunescapehex{\pdfescapehex{\sometext}}}. +\bigskip + +\endfeature + +% Also handling external files has been greatly improved. Starting from pdfTeX 1.30.0 +% you can check external files modification date, file size and even md5 check sum. + +\feature 1.30.0 {External file handling} + +The source of this document is {\tt\pdffilesize{\jobname}} bytes long. Last modification date +is {\tt\pdffilemoddate{\jobname}}. The md5 sum is {\tt\pdfmdfivesum{\jobname}}. +Bytes 7 to 13 of the source are hex {\tt\pdffiledump offset 7 length 7{\jobname}} +(string `\pdfunescapehex{\pdffiledump offset 7 length 7 {\jobname}}'). + +\endfeature + +% \pdfsavepos saves coordinates of the current position on the page relative to +% lower-left corner. \pdflastxpos and \pdflastypos are available while shipping +% out the page. Both are integers; the position is expressed in scaled points. + +\pdfsavepos +\write16{Position: X=\number\pdflastxpos sp, Y=\number\pdflastypos sp.} + +\newpage + +% pdfTeX 1.20 and higher allows to get the object number of already typeset page + +\feature 1.20 {Page object reference} + +The previous page has been written as object \pdfpageref1. + +\endfeature + +% Images can be included with pdftex using \pdfximage. Supported formats +% are determined by file name extension: +% .pdf/.PDF: PDF +% .png/.PNG: PNG +% .jpg/.JPG/.jpeg/.JPEG: JPEG +% +% Sorry, TIFF files are no longer supported. +% +% pdfTeX itself does not support EPS and Postscript codes at all, however +% it's possible to include Metapost output. EPS files can be converted to +% PDF for use with pdfTeX. See below for further info about using Metapost +% and EPS. + +\pdfximage {pic.pdf} % read image pic.pdf (search for it in TEXINPUTS path) + +% It also possible to select which page to include. Pages are numbered from +% 1. Out-of-range values are fixed to 1 and bitmapped images have always 1 +% page. To include let's say the 2nd page of a pdf image, one can use +% \pdfximage page 2 {file.pdf} + +% Similarly to \pdfobj, the image created by \pdfximage is held in memory +% and is not written to the pdf output, unless 1) the image is referenced +% by saying \pdfrefximage <object number>; or 2) \pdfximage is preceded by +% \immediate. The object number of the last image created by \pdfximage is +% accessible via \pdflastximage. Note that \immediate\pdfximage does not +% typeset anything; it just ensures that the image is written out to the +% output. To display the image, it is necessary to say +% \pdfrefximage <object number> in the intended place. Another point is +% \pdfrefximage act similarly rather to rules than to boxes concerning +% dimensions and space setting. In order to make images act as boxes +% (concerning dimensions and spacing), it's necessary to wrap them into a +% box. + +\hbox{\pdfrefximage \pdflastximage} + +% Since a pdf image may have more than 1 page, the number of the last image +% opened by \pdfximage is accessible via \pdflastximagepages + +The last image has \the\pdflastximagepages\ page(s). + +% The dimensions of the image can be also controlled via <rule spec>. The +% default values are zero for depth and `running' for height and width. If +% all of them are given, the image will be scaled to fit the specified +% values. If some of them (but not all) are given, the rest will be set to +% a value corresponding to the remaining ones so as to make the image size +% to yield the same proportion of width : (height + depth) as the original +% image size, where depth is treated as zero. If none of them is given then +% the image will take its natural size. An image inserted at its natural +% size often has a resolution of \pdfimageresolution (or 72 if +% \pdfimageresolution is set to zero) given in dots per inch in the output +% file, but some images may contain data specifying the image resolution, +% and in such a case the image will be scaled to the original resolution. +% The dimension of the image can be accessed by enclosing the \pdfrefximage +% command to a box and checking the dimensions of the box. + +\pdfximage width 6cm {pic.pdf} % set the image width and keep the +\pdfrefximage \pdflastximage % `nature' proportion width : height + +\pdfximage height 4cm {pic.png} % set the image height and keep the + % `nature' proportion width : height + +\edef\MyImg{\the\pdflastximage} % save the image number for later reuse +\pdfrefximage\MyImg + +\pdfximage width 6cm height 4cm % set both image width and height; the + {pic.jpg} % final proportion width : height may be + % different from the `nature' one + +\pdfimageresolution=72 % to open an image at 72 dpi +\pdfximage {pic.pdf} +\setbox0=\hbox{\pdfrefximage\pdflastximage} % get dimensions of the image + % in order to include the image + % at a specific resolution +\dimen0=.06\wd0 % calculate the image width at 1200 dpi (0.06 = 72/1200) +\pdfximage % include the image at resolution 1200 dpi + width \dimen0 {pic.pdf} % by setting image width to the calculated value +\pdfrefximage \pdflastximage + +\newpage + +% While embedding PDF image one may decide which area of the image (mediabox, +% cropbox, bleedbox, trimbox or artbox) should be treated as a final (visible) +% bounding box. There is \pdfoptionalwaysusepdfpagebox parameter that specifies +% the default behaviour (1 for mediabox, 2 for cropbox, 3 for bleedbox, 4 for +% trimbox and 5 for artbox). For sake of backward compatibility, if set to 0 +% cropbox is used. Starting from pdfTeX 1.30.0, a synonym \pdfforcepagebox is +% used. One may also override the default settings by providing page box +% specification in \pdfximage syntax. In example, \pdfximage trimbox {<file>} +% causes clipping the image to the trimbox area. Obviously, those settings take an +% effect only if the desired box page is defined in the image being included. +% According to PDF spec, PDF page boxes act as follows: +% mediabox % the entire page area (the only one always present) +% cropbox % the visible page area (defaults to mediabox) +% bleedbox % the page area with trimming margins (defaults to cropbox) +% trimbox % the page area without bleeds (defaults to cropbox) +% artbox % the logical page content (defaults to cropbox) + +% pdfTeX takes care about version of included PDF images. By default, an error is +% issued if this version is newer than the PDF being created (controlled by +% \pdfminorversion). If the \pdfoptionpdfinclusionerrorlevel is set to 0, only +% warning is issued. Starting pdfTeX 1.30.0 \pdfinclusionerrorlevel synonym is used +% instead. + +% Thanks to Taco Hoekwater pdfTeX 1.30.0 and higher provides advanced PNG +% inclusions handling. Nonzero \pdfimagehicolor parameter enables embedding +% of PNG images with 16 bit wide color channels at their full color resolution. +% This functionality is automatically disabled if \pdfminorversion<5, and automatically +% enabled if \pdfminorversion>=5 +% Another primitive -- \pdfimageapplygamma -- enables gamma correction of embedded +% PNG files on the base of two parameters: +% \pdfgamma % device gamma for pdfTex +% \pdfimagegamma % image gamma (used if one can't be derived from the image) +% Both values are integers measured in promile (1000 = gamma 1.0) +% All the parameters of gamma correction have to be set before any data +% is written to the PDF output; thus we put them at the very beginning of this sample. + +% \ifx\undefined\quitvmode % primitive `\leavevmode' introduced in pdfTeX 1.30.0 +% \let\quitvmode\leavevmode +% \fi + +\pdfximage width8cm {pic16.png}% +\pdfrefximage\pdflastximage +The image had originally 16 bits-per-channel. + +\feature 1.21 {Image color depth info} +Embedded one has \the\pdflastximagecolordepth\ bits-per-channel; +\endfeature + +\feature 1.30.0 {16-bit color mode for PNG inclusions} +the image has been read in 16-bit color resolution. +\endfeature + +\feature 1.30.0 {Gamma correction} +Try out different gamma parameters. % we have to set them before any data +\endfeature % is written to the output + +\bigskip + +% From pdfTeX 1.21 \pdfximage command can be followed by `colorspace <objnum>', +% where <objnum> is a number of user-defined color space object. Simply speaking, +% we may instructs the viewer, how the image should be rendered. However, this +% works only for JPEGs. Here we perform some sort of `color management' by +% applying a color profile to the JPEG image. + +% Be aware; this is viewer dependent. + +\feature 1.21 {User-defined image color space hook} + +\immediate\pdfobj + stream + attr {/N 3 /Alternate /DeviceRGB} + file {rgb.icc} % color profile + +\immediate\pdfobj{[/ICCBased \the\pdflastobj\space 0 R]} + +\edef\objnum{\the\pdflastobj} + +\pdfximage width 8cm colorspace\objnum {pic.jpg} +\pdfrefximage\pdflastximage +The image is calibrated with ICC profile. + +\immediate\pdfobj + stream attr + {/FunctionType 4 + /Domain [0 1 0 1 0 1] + /Range [0 1 0 1 0 1]}{{exch pop exch pop 0 exch 0 exch}} + +\immediate\pdfobj % don't treat it serious %) + {[/DeviceN [/Red /Green /Blue] /DeviceRGB \the\pdflastobj\space 0 R]} + +\edef\objnum{\the\pdflastobj} + +\pdfximage width8cm colorspace\objnum {pic.jpg} +\pdfrefximage\pdflastximage +Hacked image color space. + +\endfeature + +\newpage + +% Thanks to Hans Hagen pictures created by Metapost can be easily used with +% pdftex. The following files come from ConTeXt distribution. Another +% place to get them is http://www.tug.org/applications/pdftex/, where +% is also possible to get the latest driver file for using LaTeX graphicx +% package with pdftex. + +\input supp-mis.tex % supp-mis.tex is loaded by supp-pdf.tex +\input supp-pdf.tex % automatically, so the above line could be left + % out (it's given here to make clear what all files + % are needed to use \convertMPtoPDF) + +% the figure cmr10.103 was created by running Metapost on cmr10.mf + +% \convertMPtoPDF {filename} {x scale} {y scale} +\convertMPtoPDF{cmr10.103}{1}{1} +\newpage + +% It is possible to have Metapost code inside the tex sources and call +% Metapost to generate the figure before calling \convertMPtoPDF. + +% define some contants that will be used in the Metapost code +\def\pointA{(50, 50)} +\def\pointB{(400, 250)} + +\newwrite\mpfile % temporary file for metapost code +\immediate\openout\mpfile = \jobname.mp + +\immediate \write \mpfile {% +prologues := 1; +def drawleaf(expr A, B, C) = + pickup pencircle scaled 4bp; + draw (0, 0) {dir 60} .. A .. {dir 60} B withcolor C; + pickup pencircle scaled 2bp; + draw A {dir 75} .. {dir 45} B withcolor C; + draw A {right} .. {dir 75} B withcolor C; +enddef; +beginfig(0); + drawleaf(\pointA, \pointB, .6green); + d := .5 xpart \pointB; + currentpicture := currentpicture reflectedabout ((d, 0), (d, 1)); +endfig; +beginfig(1); + drawleaf(\pointA, \pointB, .6blue); + currentpicture := currentpicture reflectedabout (\pointA, \pointB); +endfig; +end; +} +\immediate \closeout \mpfile % close the file before running Metapost + +% Now we call Metapost to generate the ps output; this is system-dependent +% and has been tested for web2c only. It is necessary to have +% +% shell_escape = t +% +% in texmf.cnf in order to run it. +% +% Starting from pdfTeX 1.21a, one may test if this option is enabled using +% \ifeof condition (distribution dependent): + +\feature 1.21 {Shell escape detection (via \primitive{ifeof})} +Shell escape (via \primitive{ifeof}) seems to be +\ifeof18 disabled\else enabled\fi. +\endfeature + +% ...pdfTeX 1.30.0 introduces its own primitive integer flag + +\feature 1.30.0 {Shell escape detection (via \primitive{pdfshellescape})} +Shell escape (via \primitive{pdfshellescape}) seems to be +\ifnum\pdfshellescape=1 disabled\else enabled\fi. +\endfeature + +% Uncomment line below, if there is Metapost available in your system (should be!) +% \immediate \write 18 {mpost \jobname.mp} % call Metapost on \jobname.mp +\convertMPtoPDF{\jobname.0}{1}{1} +\convertMPtoPDF{\jobname.1}{1}{1} + +\newpage + +% EPS pictures cannot be inserted directly by pdfTeX, but it's possible to +% convert them to PDF using a Postscript-to-PDF converter, like Acrobat +% Distiller or Ghostscript. The below example calls epstopdf (available +% from http://www.tug.org/applications/pdftex), which preprocess the EPS +% and afterwards uses Ghostscript to convert to PDF. In order to convert +% EPS with embedded Type 1 fonts, a later version (beta) of Ghostscript is +% required. + +% Uncomment line below, if there is epstopdf utility available in your system + +%\immediate \write 18 {epstopdf --outfile=tmp.pdf cmr10.103} % call epstopdf +\pdfximage height \vsize {tmp.pdf} % insert the PDF converted from EPS +\topskip=0pt +\pdfrefximage \pdflastximage +\newpage + +% some text to try using threads + +\def\text{% +Ah! perhaps a burning match might be some good, if she could draw it from +the bundle and strike it against the wall, just to warm her fingers. She +drew one out---"scratch!" how it sputtered as it burnt! It gave a warm, +bright light, like a little candle, as she held her hand over it. It was +really a wonderful light. It seemed to the little girl that she was sitting +by a large iron stove, with polished brass feet and a brass ornament. How +the fire burned! and seemed so beautifully warm that the child stretched +out her feet as if to warm them, when, lo! the flame of the match went out, +the stove vanished, and she had only the remains of the half-burnt match in +her hand. + + She rubbed another match on the wall. It burst into a flame, and +where its light fell upon the wall it became as transparent as a veil, +and she could see into the room. The table was covered with a snowy +white table-cloth, on which stood a splendid dinner service, and a +steaming roast goose, stuffed with apples and dried plums. And what +was still more wonderful, the goose jumped down from the dish and +waddled across the floor, with a knife and fork in its breast, to +the little girl. Then the match went out, and there remained nothing +but the thick, damp, cold wall before her. + + She lighted another match, and then she found herself sitting +under a beautiful Christmas-tree. It was larger and more beautifully +decorated than the one which she had seen through the glass door at +the rich merchant's. Thousands of tapers were burning upon the green +branches, and colored pictures, like those she had seen in the +show-windows, looked down upon it all. The little one stretched out +her hand towards them, and the match went out. + + The Christmas lights rose higher and higher, till they looked to +her like the stars in the sky. Then she saw a star fall, leaving +behind it a bright streak of fire. "Some one is dying," thought the +little girl, for her old grandmother, the only one who had ever +loved her, and who was now dead, had told her that when a star +falls, a soul was going up to God. + + She again rubbed a match on the wall, and the light shone round +her; in the brightness stood her old grandmother, clear and shining, +yet mild and loving in her appearance. "Grandmother," cried the little +one, "O take me with you; I know you will go away when the match burns +out; you will vanish like the warm stove, the roast goose, and the +large, glorious Christmas-tree." And she made haste to light the whole +bundle of matches, for she wished to keep her grandmother there. And +the matches glowed with a light that was brighter than the noon-day, +and her grandmother had never appeared so large or so beautiful. She +took the little girl in her arms, and they both flew upwards in +brightness and joy far above the earth, where there was neither cold +nor hunger nor pain, for they were with God. +} + +\pdfannot % generic annotation + % + width 10cm % the dimension of the annotation can be controlled + height 0cm % via <rule spec>; if some of dimensions in + depth 4cm % <rule spec> is not given, the corresponding + % value of the parent box will be used. +{ % + /Subtype /Text % text annotation + % /Open true % if given then the text annotation will be opened + % by default + /Contents % text contents + (This text is from THE LITTLE MATCH-SELLER by Hans Christian + Andersen) +} + +\def\colsep{\qquad} % column separator +\setbox0=\vbox{% + \baselineskip=1.2em plus 1pt minus 1pt + \hsize=2in + \tolerance=1000 + \rightskip=0pt plus 1em + \hfuzz=1em + \parskip=\baselineskip + \null % will use \vsplit to remove this null box and + % insert \splittopskip glue to top of the + % first column. I don't know how to make the + % first column have the same height as other + % columns so have to use this trick to ensure + % that all columns will have \splittopskip glue + % properly inserted at the top + \text + \vfil} + +\setbox1=\vsplit0 to 0pt % remove the null box and insert \splittopskip glue +\setbox3=\copy0 % make a copy of box0 for later use + +% Using thread by explicit determination which boxes will belong to a thread + +\setbox2=\hbox{} +\loop + \setbox1=\vsplit0 to .75\vsize + \setbox2=\hbox{\unhbox2 \vtop{% + \pdfthread % add a bead to the thread with id=`num 1' (given + % below) + % <rule spec> % dimensions of the bead can be controlled + % via <rule spec>; if some of dimensions in + % <rule spec> is not given, the corresponding + % value of the parent box will be used. If + % \pdfthreadmargin is not zero then its value + % will be added to the margins of the bead + % + % additional attributes of thread + attr {/I <</Title (THE LITTLE MATCH-SELLER by Hans Christian)>>} + % + % identifier specification (exactly one of the + % following must be specified): + % + num 1 % num identifier (must be positive), or + % name {thread1} % name identifier; \pdfthread with the same id + % will be joined together. Attributes of the + % final thread is the last one if any was + % given. + \unvbox1}\colsep} +\ifdim \ht0 > 0pt \repeat +\box2 + +\newpage + +% Using thread by automatic determination which boxes will belong to a +% thread; \pdfstartthread has the same syntax as \pdfthread, apart that it +% must be followed by a \pdfendthread. \pdfstartthread and the +% corresponding \pdfendthread must end up in vboxes with the same +% nesting level; all vboxes between them with the same nesting level will +% be added into the thread. Note that during output routine if there are +% other newly created boxes which have the same nesting level as vboxes +% containing \pdfstartthread and \pdfendthread, they will be also added +% into the thread, which is probably not what we want. To avoid such +% unconsidered behaviour, it's often enough to wrap the box that shouldn't +% belong to the thread by another box to change the nesting level. + +\setbox0=\vbox{% + \pdfstartthread + attr {/I <</Title (THE LITTLE MATCH-SELLER by Hans Christian)>>}% + name {thread2}% + \unvbox3 + \pdfendthread +} +\setbox2=\hbox{} +\loop + \setbox1=\vsplit0 to .75\vsize + \setbox2=\hbox{\unhbox2 \vtop{\unvbox1}\colsep} +\ifdim \ht0 > 0pt \repeat +\box2 + +\newpage + +\pdfdest % destination for link and outlines + % + % identifier specification (exactly one of the + % following must be specified): + % + num 1 % num identifier (must be positive), or + % name {dest1} % name identifier. Must be unique in one document + % + % appearance of destination (exactly one of the + % following must be specified): + % + fit % fit whole page in window + % fith % fit whole width of page + % fitv % fit whole height of page + % fitb % fit whole "Bounding Box" page + % fitbh % fit whole width of "Bounding Box" of page + % fitbv % fit whole height of "Bounding Box" of page + % fitr <rule spec> % fit the rectangle specified by <rule spec>; if + % some of dimensions in <rule spec> is not given, + % the corresponding value of the parent box will be + % used. If \pdfdestmargin is not zero then its + % value will be added to the margins of the + % rectangle + % xyz % goto the current position + +This is a page containing destination `num 1' + +\newpage + +% \pdfstartlink and \pdfendlink are similar to \pdfstartthread and +% \pdfendthread, but they must end up in hboxes instead of vboxes + +\leftline{This is a link to destination +\pdfstartlink % start a link + % + height 10pt % dimensions of the link can be controlled + depth 3pt % via <rule spec>; if some of dimensions in + % <rule spec> is not given, the corresponding + % value of the parent box will be used. If + % \pdflinkmargin is not zero then its value + % will be added to the margins of the link + % + attr{/C [0.9 0 0] % additional attributes of link + /Border [0 0 2]} % + % + % action specification (exactly one of the + % following must be specified): + % + goto % goto action + % + % file{file.pdf} % optional file specification; can be used only with + % `goto' action or `thread' action (see below). If + % action identifier is name then there should be a + % destination or a thread with same name identifier + % in the file; if action identifier is number then it + % means page number for `goto' action (in this case it + % will take effect as `fitb' specification) and index + % number of thread for `thread' action (the first + % thread in a document has index number 0) + % + % goto action identifier (exactly one of the following + % must be specified): + % + num 1 % goto destination with num identifier + % name{dest1} % goto destination with name identifier + % page 1 {/Fit} % goto page 1 and fit the whole page + % + % + % thread % thread action; start to read a thread + % + %file{file.pdf} % optional file specification + % + % thread action type (exactly one of the following + % must be specified): + % + % num 1 % read thread with num identifier id=`num 1' + % name{thread2} % read thread with name identifier id=`name{thread2}' + % + % + % user{ % user-defined action; a URI action can be specified + % % as below + % /Subtype /Link + % /A << + % /Type /Action + % /S /URI + % /URI (http://www.tug.org/) + % >>} +`num 1'% +\pdfendlink % end of link; if \pdfstartlink and + % \pdfendlink end up in different hboxes (in this + % case the boxes must have the same box nesting + % level), all hboxes between them will be treated + % as part of the link. Line breaks and even page + % breaks are allowed between \pdfstartlink and + % \pdfendlink +} + +% more link examples + +\leftline{% + This is a link to the + \pdfstartlink + goto + page 1 {/FitB}% % goto the 1st page and fit the page BBox in the + % window + first page% + \pdfendlink} + +\leftline{% + This is a link to the + \pdfstartlink + thread num 1 % read the thread `num 1' + thread `num 1'% + \pdfendlink} + +\leftline{% + This is a link to + \pdfstartlink + attr{ /Border [0 0 0]} % make the bbox of the link invisible + user {% % a named action (undocumented in PDF spec) + /Subtype /Link + /A << + /S /Named + /N /GoBack + >>}% + \Cyan the previous view\Black % color text inside the link + \pdfendlink} + +\leftline{% + This is a link to + \pdfstartlink user{% + /Subtype /Link + /A << + /Type /Action + /S /URI + /URI (http://www.fi.muni.cz/) + >>}% + \Red our faculty\Black + \pdfendlink} + +{\hsize2in \raggedright \noindent + This is an example of + \pdfstartlink + attr{ /Border [0 0 0]} % make the bbox of the link invisible + goto page 1 {/FitB}% + \Red multiple line link. Make sure that the link and + its end must be in horizontal mode and the parent boxes must have the + same box nesting level.\Black + \pdfendlink + A common mistake here is using \primitive{pdfstartlink} at the + beginning of the text without \primitive{indent}, \primitive{noindent} + or \primitive{leavevmode}, so \primitive{pdfstartlink} + will end up in vertical mode and cause an error. + \par} + +% A sound or movie annotation can be created as below. Using such kinds of +% annotation or Java script causes the pdf output to be system-dependent. +% More info about this topic can be found in PDF spec. + +% \leftline{% +% \pdfannot width 4in height 0in depth 3in {% +% /Subtype /Movie +% /Movie << /F (MovieFile.mov) >>} +% An example of movie annotation} + +% \leftline{% +% \pdfannot width 0in height 0in depth 0in {% +% /Subtype /Sound +% /Sound << /F (SoundFile.wav) >>} +% An example of sound annotation} + +% \leftline{% +% \pdfannot width 0in height 0in depth 0in {% +% /Subtype /Movie +% /Movie << /F (SoundFile.wav) >>} +% Sound can be also embedded using Movie annotation} + +% outlines (bookmarks): +\pdfoutline % outline entry specification + % + goto num 1 % action specification. This is the same as the action + % specification of `\pdfstartlink' + % + count 3 % number of direct subentries of this entry, 0 if this + % entry has no subentries (in this case it may be + % omitted). If after `count' follows an negative number + % then all subentries will be closed and the absolute + % value of this number specifies the number of + % direct subentries (see the following entries) + % + {Outline 1} % text contents of outline entry + + \pdfoutline goto num 1 count -2{Outline 1.1} + \pdfoutline goto num 1 {Outline 1.1.1} + \pdfoutline goto num 1 {Outline 1.1.2} + \pdfoutline goto num 1 {Outline 1.2} + \pdfoutline goto num 1 {Outline 1.3} +\pdfoutline goto page 1 {/Fit} {Outline 2} + +\newpage + +% Transformations are done by changing transformation matrices. See PDF spec for +% more details how to use it. Generally, a transformation matrix is given as six +% real numbers followed by operator `cm'. Before doing any transformation we must +% store current graphic state (by operator `q') and restore it (by operator `Q') +% after transformation. `q' and `Q' operators acts more or less like `gsave' and +% `grestore' in Postscript. See examples below. Make sure that *no spacing* +% can be produced during transformation and afterwards we must adjust spacing `by +% hand'. + +\font\f=cmb10 at 50pt +\setbox0=\hbox{\f Rotated text} +\setbox1=\hbox{\f Scaled text} +\setbox2=\hbox{\f Skewed text} + +\newdimen\d +\newbox\tmpbox +\def\avoidboxdimen#1{% + \setbox\tmpbox=\hbox{\box#1}% + \wd\tmpbox=0pt + \ht\tmpbox=0pt + \dp\tmpbox=0pt + \box\tmpbox} + +\hrule + +% rotation by `t' degrees counterclockwise is specified as +% `cos(t) sin(t) -sin(t) cos(t) 0 0'. +\vskip\wd0 +\leftline{\hskip\ht0\hskip\dp0% +\pdfliteral{q 0 1 -1 0 0 0 cm}% +\avoidboxdimen 0 +\pdfliteral{Q}} + +\hrule + +% scaling is specified as `Sx 0 0 Sy 0 0' +\d=\ht1 \advance\d by \dp1 +\vskip3\d +\pdfliteral{q 2 0 0 3 0 0 cm}% +\avoidboxdimen 1 +\pdfliteral{Q}% + +\hrule + +% skewing x-axis by `u' degrees and y-axis by `v' degrees is specified as +% `1 tan(u) tan(v) 1 0 0'. +\d=\ht2 \advance\d by \dp2 +\vskip\d +\d=0.57735\wd2 %tan(30) = 0.57735 +\pdfliteral{q 1 -0.57735 0 1 0 0 cm}% +\avoidboxdimen 2 +\pdfliteral{Q} +\vskip\d + +% To have a smoothly readable PDF output one may use a newline character to +% separate entries written directly do PDF code. No matter for the viewer. + +\def\n{^^J} + +% If the file is modified are released oftenly (as this one) it might be convenient to +% keep trace of modification time. In pdfTeX 1.30.0 there is a +% \pdfcreationdate that returns a date of the file being created. +% Date is formated in PDF way. + +\ifversion 1.30.0 \else + +\count100=\time +\divide\count100 by60 +\edef\pdfcreationdate{\ifnum\count100<10 0\fi\the\count100} % hours +\multiply\count100 by-60 +\advance\count100 by\time +\edef\pdfcreationdate{% + \pdfcreationdate + \ifnum\count100<10 0\fi\the\count100 00} % minutes (seconds zeroed) +\edef\pdfcreationdate{% + D:\the\year + \ifnum\month<10 0\fi\the\month + \ifnum\day<10 0\fi\the\day + \pdfcreationdate} % time zone discarded + +\fi + +\pdfinfo{% % Info dictionary of PDF output; + % all keys are optional. + /Author (Han The Thanh) + \n/CreationDate (D:20001212000000) % (D:YYYYMMDDhhmmss) + % YYYY year + % MM month + % DD day + % hh hour + % mm minutes + % ss seconds + % + % default: the actual date + % + \n/ModDate (\pdfcreationdate) % ModDate is similar + \n/Creator (TeX) % default: "TeX" + \n/Producer (pdfTeX) % default: "pdfTeX" + pdftex version + \n/Title (samplepdf.pdf) % + \n/Subject (Example) % + \n/Keywords (PDF TeX) % +} + +\pdfcatalog{ % Catalog dictionary of PDF output. + /PageMode /UseOutlines % + /URI (http://www.fi.muni.cz/) % +% pdfscreen-like setting might look like: +% /PageMode /none +% /ViewerPreferences << +% /HideToolbar true +% /HideMenubar true +% /HideWindowUI true +% /FitWindow true +% /CenterWindow true +% >> +} +openaction goto page 1 {/Fit} % the action to be activated when + % opening the document; this is the + % same as <action spec> for links + % and outlines +\end diff --git a/Master/texmf/doc/pdftex/manual/samplepdf/supp-mis.tex b/Master/texmf/doc/pdftex/manual/samplepdf/supp-mis.tex new file mode 100644 index 00000000000..ab089a297e1 --- /dev/null +++ b/Master/texmf/doc/pdftex/manual/samplepdf/supp-mis.tex @@ -0,0 +1,695 @@ +%D \module +%D [ file=supp-mis, +%D version=2004.10.26, % 1997.01.04, +%D title=\CONTEXT\ Support Macros, +%D subtitle=Missing (For Generic Use), +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D Some support modules are more or less independant. This +%D module, which is not part of plain \CONTEXT, provides the +%D missing macros and declarations of registers. + +\ifx \undefined \writestatus \else \expandafter \endinput \fi + +%D Because \LATEX\ has no safe package loading mechanism, we +%D need to take care of possible interference. + +\def\StartLatexHack + {\edef\StopLatexHack + {\catcode`\noexpand/=\the\catcode`/ + \catcode`\noexpand:=\the\catcode`: + \catcode`\noexpand;=\the\catcode`; + \catcode`\noexpand"=\the\catcode`" + \catcode`\noexpand<=\the\catcode`< + \catcode`\noexpand>=\the\catcode`>}% + \catcode`/=12 \catcode`:=12 \catcode`;=12 + \catcode`"=12 \catcode`<=12 \catcode`>=12 } + +%D This hack is needed especially for \LATEX\ users who use +%D the Babel package. The Germans have active \type {"}'s, the +%D Poles have \type {/}, while the French have \type {:} and +%D \type {;} defines as command (thanks to Daniel Flipo for +%D pointing that out and testing). Potentially active \type +%D {?}'s and \type {!}'s are less dangerous since they are +%D handled by the \type {\protect} and \type {\unprotect} +%D macros. + +\StartLatexHack + +%D \macros +%D {ifnocontextobject} +%D +%D First we take care of redundant defining. The next set of +%D macros are a bit complicated by the fact that Plain +%D \TEX\ defines the \type{\new}||macros as being outer. +%D Furthermore nested \type{\if}'s can get us into +%D trouble. + +\def\definecontextobject + {\iftrue} + +\def\gobblecontextobject + {\setbox0\hbox + \bgroup + \long\def\gobblecontextobject##1\fi{\egroup}% + \expandafter\gobblecontextobject\string} + +\long\def\ifnocontextobject#1\do + {\ifx#1\undefined + \expandafter\definecontextobject + \else + %\writestatus{system}{beware of conflicting \string#1}% + \expandafter\gobblecontextobject + \fi} + +%D \macros +%D {beginETEX,beginTEX} +%D +%D Outside \CONTEXT\ we will not be \ETEX||aware. + +\long\def\beginETEX #1\endETEX {} +\long\def\beginOMEGA#1\endOMEGA{} + +\let\beginTEX\relax \let\endTEX\relax + +%D \macros +%D {writestatus} +%D +%D We start each module with a message. Normally the output is +%D formatted, but here we keep things simple. + +\ifnocontextobject \writestatus \do + + \def\writestatus#1#2% + {\immediate\write16{#1 : #2}} + +\fi + +%D Let's see if it works. + +\writestatus{loading}{Context Support Macros / Miscellaneous (2004.10.26)} + +%D \macros +%D {protect,unprotect} +%D +%D Next we present a poor mans alternative for \type{\protect} +%D and \type{\unprotect}, two commands that enable us to use +%D the characters \type{@}, \type{!} and \type{?} in macro +%D names. + +\ifnocontextobject \protect \do + + \let\protect\relax + +\fi + +\newcount\protectiondepth + +\ifnocontextobject \unprotect \do + + \def\unprotect + {\advance\protectiondepth 1 + \ifnum\protectiondepth=1 + \let\normalprotect=\protect + \def\protect + {\ifnum\protectiondepth>0 + \advance\protectiondepth -1 + \ifnum\protectiondepth=0 + \doprotect + \let\protect=\normalprotect + \fi + \fi} + \edef\doprotect + {\catcode`\noexpand @=\the\catcode`@\relax + \catcode`\noexpand !=\the\catcode`!\relax + \catcode`\noexpand ?=\the\catcode`?\relax} + \catcode`@=11 + \catcode`!=11 + \catcode`?=11 + \fi} + +\fi + +%D We start using this one it at once. + +\unprotect + +%D \macros +%D {scratch...,if...,next...} +%D +%D We need some scratch registers. Users are free to use them, +%D but can never be sure of their value once another macro is +%D called. We only allocate things when they are yet +%D undefined. This way we can't mess up other macro packages, +%D but of course previous definitions can mess up our modules. + +\ifnocontextobject \donetrue \do \newif\ifdone \fi + +% no time now, will do a better test later (based on dimendef) + +\def\!!stringa{plain} \ifx\!!stringa\fmtname \donetrue \else +\def\!!stringa{babel-plain} \ifx\!!stringa\fmtname \donetrue \else + \donefalse \fi \fi + +\ifdone + % plain defines some 15 dimens, so we need to define a few + % dummies in order to get out of the scratch area + \newdimen\scratchdimen % 16 + \newdimen\scratchdimen % 17 + \newdimen\scratchdimen % 18 + \newdimen\scratchdimen % 19 + \newdimen\scratchdimen % 20 + \newdimen\scratchdimen % 21 +\fi + +\ifnocontextobject \scratchcounter \do \newcount \scratchcounter \fi +\ifnocontextobject \scratchtoks \do \newtoks \scratchtoks \fi +\ifnocontextobject \scratchdimen \do \newdimen \scratchdimen \fi +\ifnocontextobject \scratchskip \do \newskip \scratchskip \fi +\ifnocontextobject \scratchmuskip \do \newmuskip \scratchmuskip \fi +\ifnocontextobject \scratchbox \do \newbox \scratchbox \fi +\ifnocontextobject \scratchread \do \newread \scratchread \fi +\ifnocontextobject \scratchwrite \do \newwrite \scratchwrite \fi + +%D Watch out, in the past we ran into troubles with \type {\onepoint} +%D (and others) mening something different in \LATEX\ then here. In +%D such situations clashes are bound to happen. For this reason the +%D assignments are no inside the test. We try to catch those situations +%D but we cannot keep ahead of teh future. + +\ifnocontextobject \zeropoint \do \newdimen \zeropoint \zeropoint = 0pt \fi % else problems with dimen12 +\ifnocontextobject \onepoint \do \newdimen \onepoint \onepoint = 1pt \fi +\ifnocontextobject \onebasepoint \do \newdimen \onebasepoint \onebasepoint = 1bp \fi +\ifnocontextobject \zerocount \do \chardef \zerocount = 0 \fi +\ifnocontextobject \plusone \do \chardef \plusone = 1 \fi +\ifnocontextobject \minusone \do \newcount \minusone \minusone = -1 \fi +\ifnocontextobject \thousandpoint \do \newdimen \thousandpoint \thousandpoint = 1000pt \fi +\ifnocontextobject \onerealpoint \do \newdimen \onerealpoint \onerealpoint = 1pt \fi % latex has a funny \onepoint + +\ifnocontextobject \emptytoks \do \newtoks \emptytoks \fi +\ifnocontextobject \nextbox \do \newbox \nextbox \fi +\ifnocontextobject \nextdepth \do \newdimen \nextdepth \fi + +\ifnocontextobject \CONTEXTtrue \do \newif\ifCONTEXT \fi +\ifnocontextobject \eightbitcharacterstrue \do \newif\ifeightbitcharacters \fi +\ifnocontextobject \MPdrawingdonetrue \do \newif\ifMPdrawingdone \fi + +\ifnocontextobject \ifzeropt \do \let\ifzeropt\ifcase \fi + +%D \macros +%D {@@...} +%D +%D We use symbolic name for \CATCODES. They can only be used +%D when we are in unprotected state. + +\ifnocontextobject \@@escape \do \chardef\@@escape = 0 \fi +\ifnocontextobject \@@begingroup \do \chardef\@@begingroup = 1 \fi +\ifnocontextobject \@@endgroup \do \chardef\@@endgroup = 2 \fi +\ifnocontextobject \@@endofline \do \chardef\@@endofline = 5 \fi +\ifnocontextobject \@@ignore \do \chardef\@@ignore = 9 \fi +\ifnocontextobject \@@space \do \chardef\@@space = 10 \fi +\ifnocontextobject \@@letter \do \chardef\@@letter = 11 \fi +\ifnocontextobject \@@other \do \chardef\@@other = 12 \fi +\ifnocontextobject \@@active \do \chardef\@@active = 13 \fi +\ifnocontextobject \@@comment \do \chardef\@@comment = 14 \fi + +\def\s!sp{sp} +\def\s!pt{pt} +\def\s!bp{bp} + +%D \macros +%D {@EA,expanded,expandoneargafter,expandtwoargsafter} +%D +%D Also needed: + +\let\@EA=\expandafter \let\@@expanded\empty + +\def\expanded#1% + {\long\xdef\@@expanded{\noexpand#1}\@@expanded} + +\def\expandoneargafter#1#2% + {\@EA#1\@EA{#2}} + +\def\expandtwoargsafter#1#2#3% + {\@EA\@EA\@EA#1\@EA\@EA\@EA{\@EA#2\@EA}\@EA{#3}} + +\def\@EAEAEA{\@EA\@EA\@EA} + +%D \macros +%D {everyline,EveryLine,EveryPar} +%D +%D In \CONTEXT\ we use \type{\everypar} for special purposes +%D and provide \type{\EveryPar} as an alternative. The same +%D goes for \type{\everyline} and \type{\EveryLine}. + +\ifnocontextobject \everyline \do \newtoks\everyline \fi +\ifnocontextobject \EveryPar \do \let\EveryPar =\everypar \fi +\ifnocontextobject \EveryLine \do \let\EveryLine=\everyline \fi + +%D \macros +%D {globallet} + +\def\globallet{\global\let} + +%D \macros +%D {!!...} +%D +%D We reserve ourselves some scratch strings (i.e. macros) +%D and some more counters. + +\ifnocontextobject \!!stringa \do \def\!!stringa {} \fi +\ifnocontextobject \!!stringb \do \def\!!stringb {} \fi +\ifnocontextobject \!!stringc \do \def\!!stringc {} \fi +\ifnocontextobject \!!stringd \do \def\!!stringd {} \fi + +\ifnocontextobject \!!counta \do \newcount\!!counta {} \fi +\ifnocontextobject \!!countb \do \newcount\!!countb {} \fi + +%D \macros +%D {!!...} +%D +%D The next set of definitions speed up processing a bit. +%D Furthermore it saves memory. + +\ifnocontextobject \!!zeropoint \do \def\!!zeropoint {0pt} \fi +\ifnocontextobject \!!zerocount \do \def\!!zerocount {0} \fi +\ifnocontextobject \!!tenthousand \do \def\!!tenthousand {10000} \fi + +\ifnocontextobject \!!width \do \def\!!width {width} \fi +\ifnocontextobject \!!height \do \def\!!height {height} \fi +\ifnocontextobject \!!depth \do \def\!!depth {depth} \fi + +\ifnocontextobject \!!plus \do \def\!!plus {plus} \fi +\ifnocontextobject \!!minus \do \def\!!minus {minus} \fi +\ifnocontextobject \!!to \do \def\!!to {to} \fi + +%D \macros +%D {smashbox} +%D +%D The system modules offer a range of smashing macros, of +%D which we only copied \type{\smashbox}. + +\ifnocontextobject \smashbox \do + + \def\smashbox#1% + {\wd#1\zeropoint + \ht#1\zeropoint + \dp#1\zeropoint} + +\fi + +%D \macros +%D {dowithnextbox} +%D +%D Also without further comment, we introduce a macro that +%D gets the next box and does something usefull with it. +%D Because the \type{\afterassignment} is executed inside the +%D box, we have to use a \type{\aftergroup} too. + +\ifnocontextobject \dowithnextbox \do + + \def\dowithnextbox#1% + {\def\dodowithnextbox{#1}% + \afterassignment\dododowithnextbox + \setbox\nextbox} + + \def\dododowithnextbox% + {\aftergroup\dodowithnextbox} + +\fi + +%D \macros +%D {setvalue,setevalue,setxvalue,,setgvalue, +%D getvalue, +%D letvalue,letgvalue} +%D +%D The next two macros expand their argument to +%D \type{\argument}. The first one is used to define macro's +%D the second one executes them. + +\ifnocontextobject \setvalue \do + + \def\setvalue #1{\expandafter\def\csname#1\endcsname} + \def\setevalue#1{\expandafter\edef\csname#1\endcsname} + \def\setgvalue#1{\expandafter\gdef\csname#1\endcsname} + \def\setxvalue#1{\expandafter\xdef\csname#1\endcsname} + \def\getvalue #1{\csname#1\endcsname} + \def\letvalue #1{\expandafter\let\csname#1\endcsname} + \def\letgvalue#1{\global\expandafter\let\csname#1\endcsname} +\fi + +%D \macros +%D {unexpanded} +%D +%D The next command can be used as prefixed for commands that +%D need protection during tests and writing to files. This +%D is a very \CONTEXT\ specific one. + +\ifnocontextobject \unexpanded \do + + \let\unexpanded\relax + +\fi + +%D \macros +%D {convertargument} +%D +%D The original one offers a bit more, like global assignment, the +%D the next implementation is however a bit more byte saving. + +\ifnocontextobject \convertargument \do + + \def\doconvertargument#1>{} + + \long\def\convertargument#1\to#2% + {\long\def\convertedargument{#1}% + \edef#2{\expandafter\doconvertargument\meaning\convertedargument}} + +\fi + +%D \macros +%D {forgetall} +%D +%D Sometimes we have to disable interference of whatever kind +%D of skips and mechanisms. The next macro resets some. + +\ifnocontextobject \forgetall \do + + \def\forgetall + {\parskip\zeropoint + \leftskip\zeropoint + \parindent\zeropoint + \everypar{}} + +\fi + +%D \macros +%D {withoutpt, +%D ScaledPointsToBigPoints,ScaledPointsToWholeBigPoints} +%D +%D \TEX\ lacks some real datastructure. We can however use +%D \DIMENSIONS. This kind of trickery is needed when we want +%D \TEX\ to communicate with the outside world (by means of +%D \type{\specials}). + +\ifnocontextobject \withoutpt \do + + {\catcode`\.=\@@other + \catcode`\p=\@@other + \catcode`\t=\@@other + \gdef\WITHOUTPT#1pt{#1}} + + \def\withoutpt#1% + {\expandafter\WITHOUTPT#1} + + \def\ScaledPointsToBigPoints#1#2% + {\scratchdimen=#1sp\relax + \scratchdimen=.996264\scratchdimen + \edef#2{\withoutpt{\the\scratchdimen}}} + + \def\ScaledPointsToWholeBigPoints#1#2% + {\scratchdimen=#1sp + \scratchdimen=.996264\scratchdimen + \scratchcounter=\scratchdimen + \advance\scratchcounter by 32768 + \divide\scratchcounter by 65536 + \edef#2{\the\scratchcounter}} + +\fi + +%D \macros +%D {doprocessfile} +%D +%D This macro takes three arguments: the file number, the +%D filename and a macro that handles the content of a read +%D line. + +\newif\iffileprocessed + +\ifnocontextobject \doprocessfile \do + + \def\doprocessfile#1#2#3% + {\openin#1=#2\relax + \ifeof#1% + \fileprocessedfalse + \closein#1\relax + \else + \fileprocessedtrue + \gdef\dofinishfile% + {\closein#1\relax + \global\let\doprocessline\relax}% + \gdef\doprocessline% + {\ifeof#1% + \dofinishfile + \else + \global\read#1 to \fileline + #3\relax + \expandafter\doprocessline + \fi}% + \expandafter\doprocessline + \fi} + +\fi + +%D \macros +%D {uncatcodespecials} +%D +%D This one is taken from the \TEX\ book. The \CONTEXT\ +%D alternative is a bit different, but we hope this one works +%D here. + +\ifx\dospecials\undefined + + \def\dospecials + {\do\ \do\\\do\{\do\}\do\$% + \do\#\do\^\do\_\do\&\do\%% + \do\~\do\^^A\do\^^K} + +\fi + +\ifnocontextobject \uncatcodespecials \do + + \def\uncatcodespecials + {\def\do##1{\catcode`##1=12 }\dospecials + \catcode`\ =\@@space + \catcode`\^^L=\@@ignore + \catcode`\^^M=\@@endofline + \catcode`\^^?=\@@ignore} + +\fi + +\ifnocontextobject \setnaturalcatcodes \do + +\def\setnaturalcatcodes + {\catcode`\!=\@@other \catcode`\?=\@@other \catcode`\@=\@@other + \catcode`\#=\@@other \catcode`\&=\@@other \catcode`\|=\@@other + \catcode`\$=\@@other \catcode`\^=\@@other \catcode`\_=\@@other + \catcode`\*=\@@other \catcode`\/=\@@other + \catcode`\-=\@@other \catcode`+=\@@other + \catcode`\==\@@other \catcode`\<=\@@other \catcode`\>=\@@other + \catcode`\"=\@@other \catcode`\'=\@@other \catcode`\`=\@@other + \catcode`\:=\@@other \catcode`\;=\@@other + \catcode`\,=\@@other \catcode`\.=\@@other \catcode`\~=\@@other + \catcode`\(=\@@other \catcode`\)=\@@other + \catcode`\{=\@@other \catcode`\}=\@@other + \catcode`\\=\@@other \catcode`\%=\@@other } + +\fi + +%D \macros +%D {doglobal} +%D +%D Some \CONTEXT\ low level macros can have a \type{\doglobal} +%D prefix. Let's just forget about that here: + +\ifnocontextobject \doglobal \do \let\doglobal\relax \fi + +%D The next obscure one is needed in the generic verbatim +%D environment. When we end up with more of these, it's time +%D to load the module \type{syst-gen}. + +\ifnocontextobject \doifincsnameelse \do + + \def\dodoifincsnameelse#1#2% + {\def\dododoifincsnameelse##1#1##2##3\war% + {\csname\if##2@iffalse\else iftrue\fi\endcsname}% + \expandafter\dododoifincsnameelse#2#1@@\war} + + \long\def\doifincsnameelse#1#2#3#4% + {\edef\@@instring{#1}% + \expandafter\dodoifincsnameelse\expandafter{\@@instring}{#2}% + #3% + \else + #4% + \fi} + +\fi + +%D \macros +%D {dostepwiserecurse, dorecurse, doloop, exitloop} +%D +%D The next loop macro is a real weak one, and does not offer +%D the full \CONTEXT\ functionality, let alone nesting, but +%D for simple purposes, its behaviour is acceptable. + +\newcount\recursecounter + +\def\dostepwiserecurse#1#2#3#4% very weak and rubishly version + {\ifnum#2<#1\relax\else\dodostepwiserecurse{#1}{#2}{#3}{#4}\fi} + +\def\dodostepwiserecurse#1#2#3#4% very weak and rubishly version + {\recursecounter=#1\relax + \loop + \edef\recurselevel{\the\recursecounter}% + #4\relax + \ifnum\recursecounter<#2\relax + \advance\recursecounter by #3\relax + \repeat} + +\def\dorecurse#1% + {\dostepwiserecurse{1}{#1}{1}} + +\def\doloop + {\dostepwiserecurse{1}{\maxdimen}{1}} + +\def\exitloop + {\recursecounter=\maxdimen} + +%D \macros +%D {ifundefined,doifdefined,doifundefined, +%D doifdefinedelse,doifundefinedelse} +%D +%D These alteratives are not robust but suitable for simple +%D usage. The official ones are a bit faster. + +\ifnocontextobject \doifdefined \do + + \def\ifundefined#1% + {\expandafter\ifx\csname#1\endcsname\relax} + + \def\doifdefinedelse#1#2#3% + {\expandafter\ifx\csname#1\endcsname\relax#3\else#2\fi} + + \def\doifundefinedelse#1#2#3% + {\expandafter\ifx\csname#1\endcsname\relax#2\else#3\fi} + + \def\doifdefined#1#2% + {\expandafter\ifx\csname#1\endcsname\relax\else#2\fi} + + \def\doifundefined#1#2% + {\expandafter\ifx\csname#1\endcsname\relax#2\fi} + +\fi + +%D \macros +%D {doifinstringelse} +%D +%D It seems like we end up with more and more macros here. +%D Sigh. + +\ifnocontextobject \doifinstringelse \do + + \def\p!doifinstringelse#1#2% + {\def\pp!doifinstringelse##1#1##2##3\war% + {\csname if\if##2@fals\else tru\fi e\endcsname}% + \expanded{\pp!doifinstringelse#2#1@@\noexpand\war}} + + \long\def\doifinstringelse#1#2#3#4% + {\edef\@@@instring{#1}% + \@EA\p!doifinstringelse\@EA{\@@@instring}{#2}#3\else#4\fi} + +\fi + +%D \macros +%D {twodigitrounding} +%D +%D We don't support rounding outside \CONTEXT. Sorry. + +\def\twodigitrounding#1{#1} + +%D \macros +%D {lineheight} +%D +%D In \CONTEXT\ we have \type{\lineheight}, which in many +%D cases matches \type {\baselineskip}. + +\ifnocontextobject \lineheight \do + + \def\lineheight{\baselineskip} + +\fi + +%D \macros +%D {dohandletokens} +%D +%D The following macro is the simplified version, but good +%D enough for day to day hacks. +%D +%D \starttyping +%D \dohandletokens some text\with\somemacro +%D \stoptyping + +\ifnocontextobject \dohandletokens \do + +\def\dodohandletokens + {\ifx\next\end \else + \docommando{\next}% + \expandafter\dohandletokens + \fi} + +\def\dohandletokens + {\afterassignment\dodohandletokens\let\next= } + +\long\def\handletokens#1\with#2% + {\let\docommando=#2% + \dohandletokens#1\end} + +\fi + +%D Very reduced: + +\long\def\appendtoks#1\to#2% + {\scratchtoks{#1}\expanded{#2{\the#2\the\scratchtoks}}} + +%D Well, also handy. + +\def\doiffileelse#1#2#3% + {\immediate\openin\scratchread=#1\relax + \ifeof\scratchread + \def\next{#3}% + \else + \def\next{#2}% + \fi + \immediate\closein\scratchread + \next} + +%D New. + +\let\donothing\empty + +%D Also new: + +\def\letempty #1{\let#1\empty} +\def\globalletempty#1{\global\let#1\empty} + +\def\letvalueempty #1{\expandafter\let\csname#1\endcsname\empty} +\def\letgvalueempty#1{\global\expandafter\let\csname#1\endcsname\empty} + +%D Sigh + +\def\settrue #1{\chardef#1\zerocount} +\def\setfalse#1{\chardef#1\plusone} + +\let\newconditional = \setfalse +\let\ifconditional = \ifcase + +%D That's it. Please forget this junk and take a look at how +%D it should be done. + +\StopLatexHack \protect \endinput diff --git a/Master/texmf/doc/pdftex/manual/samplepdf/supp-pdf.tex b/Master/texmf/doc/pdftex/manual/samplepdf/supp-pdf.tex new file mode 100644 index 00000000000..184cfb81582 --- /dev/null +++ b/Master/texmf/doc/pdftex/manual/samplepdf/supp-pdf.tex @@ -0,0 +1,2191 @@ +%D \module +%D [ file=supp-pdf, +%D version=2004.12.16, +%D title=\CONTEXT\ Support Macros, +%D subtitle=\METAPOST\ to \PDF\ conversion, +%D author=Hans Hagen \& others (see text), +%D date=\currentdate, +%D copyright=\PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D These macros are written as generic as possible. Some +%D general support macro's are loaded from a small module +%D especially made for non \CONTEXT\ use. In this module I +%D use a matrix transformation macro written by Tanmoy +%D Bhattacharya. Thanks to extensive testing by Sebastian +%D Ratz I was able to complete this module within reasonable +%D time. This module has support for \METAPOST\ extensions +%D built in. +%D +%D Daniel H. Luecking came up with a better (more precise) +%D transformation method. You can recognize his comment by +%D his initials. (We keep the old code around because it's a +%D nice illustration on how a module like this evolves.) + +% Beware, we cannot use \zeropoint here since it may be +% defined in the range \dimen 0 - 20 which we happen to use +% as scratch registers; inside context we may consider +% using dedicated registers. + +% fails: ( ) vect10 9.96265 fshow % \040\040\040\040 +% +% some optimizations are possible, but we need to be generic + +%D First we take care of non||\CONTEXT\ use (newlines needed, +%D expandafter not -). + +\ifx \undefined \writestatus \input supp-mis.tex \relax \fi + +\ifx \undefined \convertMPtoPDF \else \expandafter \endinput \fi + +\ifx \undefined \StartLatexHack \else \StartLatexHack \fi + +%D This module handles some \PDF\ conversion and insertions +%D topics. By default, the macros use the \PDFTEX\ primitive +%D \type{\pdfliteral} when available. Since \PDFTEX\ is now the +%D default engine for \TEX\ distributions, we need a more complex +%D test. + +\writestatus{loading}{Context Support Macros / PDF (2004.03.26)} + +\unprotect + +\ifx\PDFcode\undefined + \ifx\pdfliteral\undefined + \def\PDFcode#1{\special{PDF: #1}} + \else\ifx\pdfoutput\undefined + \def\PDFcode#1{\special{PDF: #1}} + \else\ifcase\pdfoutput + \def\PDFcode#1{\special{PDF: #1}} + \else % pdftex as well as in pdf mode + \let\PDFcode\pdfliteral + \fi\fi\fi +\else + % we probably use context +\fi + +%D First we define a handy constant: + +\bgroup \catcode`\%=\@@other \xdef\letterpercent{\string%} \egroup + +%D \macros +%D {pdfimage,pdfimages,pdfclippedimage} +%D +%D Starting with pdftex version 14, images are included more +%D natural to the form embedding. This enables alternative +%D images to be embedded. +%D +%D \starttyping +%D \pdfimage <optional dimensions> {file} +%D \pdfimages <optional dimensions> {high res file} {low res file} +%D \stoptyping +%D +%D The first one replaces the pre||version||14 original, +%D while the latter provides alternative images. +%D +%D The next macro is dedicated to Maarten Gelderman, who +%D needed to paste prepared \PDF\ pages into conference +%D proceedings. +%D +%D \starttyping +%D \pdfclippedimage <optional dimensions> {file} {l} {r} {t} {b} +%D \stoptyping + +% \ifx\pdftexversion\undefined % no \m!systems for the sake of latex +% \writestatus{systems}{Why not use pdf(e)TeX binaries?} +% \protect +% \expandafter\endinput +% \fi + +\ifx\pdftexversion\undefined \else \ifnum\pdftexversion>13 + + \def\pdfimage#1#% + {\dopdfimage{#1}} + + \def\dopdfimage#1#2% + {\immediate\pdfximage#1{#2}% + \pdfrefximage\pdflastximage} + + \def\pdfimages#1#% + {\dopdfimages{#1}} + + \def\dopdfimages#1#2#3% + {\immediate\pdfximage#1{#2}% + \immediate\pdfobj + {[ << /Image \the\pdflastximage\space0 R + /DefaultForPrinting true >> ]}% + \immediate\pdfximage#1 + attr {/Alternates \the\pdflastobj\space0 R}{#3}% + \pdfrefximage\pdflastximage} + + \def\pdfclippedimage#1#% specs {file}{left}{right}{top}{bottom} + {\dopdfclippedimage{#1}} + + \def\dopdfclippedimage#1#2#3#4#5#6% + {\bgroup + \pdfximage#1{#2}% + \setbox\scratchbox\hbox + {\pdfrefximage\pdflastximage}% + \hsize\wd\scratchbox + \advance\hsize -#3 + \advance\hsize -#4 + \vsize\ht\scratchbox + \advance\vsize -#5 + \advance\vsize -#6 + \setbox\scratchbox\vbox to \vsize + {\vskip-#5\hbox to \hsize{\hskip-#3\box\scratchbox\hss}}% + \pdfxform\scratchbox + \pdfrefxform\pdflastxform + \egroup} + +\fi \fi + +%D If you want to save a few hash entries, you may prefer the +%D less readable alternatives, like: +%D +%D \starttyping +%D \def\pdfimage#1#% This one is less readable but needs no additional +%D {\bgroup % hash entry for the second stage macro. +%D \def\pdfimage##1% +%D {\immediate\pdfximage##1{#2}% +%D \pdfrefximage\pdflastximage\egroup}} +%D \stoptyping + +%D For old times sake we provide a few aliases. These will be +%D removed some day. + +\ifx\pdftexversion\undefined \else \ifnum\pdftexversion>13 + + \let\pdfform =\pdfxform + \let\pdflastform=\pdflastxform + \let\pdfrefform =\pdfrefxform + +\fi \fi + +%D \macros +%D {convertPDFtoPDF} +%D +%D \PDFTEX\ supports verbatim inclusion of \PDF\ code. The +%D following macro takes care of inserting externally defined +%D illustrations in \PDF\ format. According to a suggestion +%D Tanmoy Bhattacharya posted to the \PDFTEX\ mailing list, we +%D first skip lines until \type{stream} is reached and then +%D copy lines until \type{endstream} is encountered. This +%D scheme only works with vectorized graphics in which no +%D indirect references to objects are used. Bitmaps also don't +%D work. Interpreting their specifications is beyond the +%D current implementation. +%D +%D \starttyping +%D \convertPDFtoPDF +%D {filename} +%D {x scale} {y scale} +%D {x offset } {y offset} +%D {width} {height} +%D \stoptyping +%D +%D When the scales are set to~1, the last last four values +%D are the same as the bounding box, e.g. +%D +%D \starttyping +%D \convertPDFtoPDF{mp-pra-1.pdf} {1} {1}{-1bp}{-1bp}{398bp}{398bp} +%D \convertPDFtoPDF{mp-pra-1.pdf}{.5}{.5} {0bp} {0bp}{199bp}{199bp} +%D \stoptyping +%D +%D Keep in mind, that this kind of copying only works for +%D pure and valid pdf code (without fonts). + +%D The scanning and copying is straightforward and quite fast. +%D To speed up things we use two constants. + +\def\@@PDFstream@@ {stream} +\def\@@PDFendstream@@ {endstream} + +%D \macros +%D {PDFmediaboxprefered} +%D +%D If needed, the macros can scan for the mediabox that +%D specifies the dimensions and offsets of the graphic. When +%D we say: +%D +%D \starttyping +%D \PDFmediaboxpreferedtrue +%D \stoptyping +%D +%D the mediabox present in the file superseded the user +%D specified, already scaled and calculated offset and +%D dimensions. Beware: the user supplied values are not the +%D bounding box ones! + +%D This code has become obsolete. + +% \newif\ifPDFmediaboxprefered + +\def\setPDFboundingbox#1#2#3#4#5#6% + {\dimen0=#1\dimen0=#5\dimen0 + \ScaledPointsToBigPoints{\number\dimen0}\PDFxoffset + \dimen0=#3\dimen0=#5\dimen0 + \xdef\PDFwidth{\the\dimen0}% + \dimen0=#2\dimen0=#6\dimen0 + \ScaledPointsToBigPoints{\number\dimen0}\PDFyoffset + \dimen0=#4\dimen0=#6\dimen0 + \xdef\PDFheight{\the\dimen0}% + \global\let\PDFxoffset\PDFxoffset + \global\let\PDFyoffset\PDFyoffset} + +\def\setPDFmediabox#1[#2 #3 #4 #5]#6\done + {\dimen2=#2bp\dimen2=-\dimen2 % \dimen2=-#2bp also works since tex handles -- + \dimen4=#3bp\dimen4=-\dimen4 % \dimen4=-#3bp also works since tex handles -- + \dimen6=#4bp\advance\dimen6 \dimen2 + \dimen8=#5bp\advance\dimen8 \dimen4 + \setPDFboundingbox{\dimen2}{\dimen4}{\dimen6}{\dimen8}\PDFxscale\PDFyscale} + +% \def\checkPDFmediabox#1/MediaBox#2#3\done +% {\ifx#2\relax \else +% \message{mediabox}% +% \setPDFmediabox#2#3\done +% \fi} + +%D We use the general macro \type{\doprocessfile} and feed this +%D with a line handling macro that changes it's behavior when +%D the stream operators are encountered. + +% \def\handlePDFline +% {\ifx\@@PDFstream@@\fileline +% \let\doprocessPDFline\copyPDFobject +% \startPDFtoPDF +% \else\ifPDFmediaboxprefered +% \expandafter\checkPDFmediabox\fileline/MediaBox\relax\done +% \fi\fi} + +% \def\copyPDFobject +% {\ifx\@@PDFendstream@@\fileline +% \ifPDFmediaboxprefered +% \let\doprocessPDFline\findPDFmediabox +% \else +% \let\doprocessPDFline\relax +% \fi +% \else +% \advance\scratchcounter 1 +% \PDFcode{\fileline}% +% \fi} + +% \def\findPDFmediabox +% {\expandafter\checkPDFmediabox\fileline/MediaBox\relax\done} + +%D The main conversion macro wraps the \PDF\ codes in a box +%D that is output as an object. The graphics are embedded +%D in~\type{q} and~\type{Q} and are scaled and positioned using +%D one transform call (\type{cm}). This saves some additional +%D scaling. + +%D \starttyping +%D \def\startPDFtoPDF% +%D {\setbox0=\vbox\bgroup +%D \message{[PDF to PDF \PDFfilename}% +%D \forgetall +%D \scratchcounter=0 +%D \let\stopPDFtoPDF=\dostopPDFtoPDF} +%D +%D \def\dostopPDFtoPDF% +%D {\ifnum\scratchcounter<0 \scratchcounter=1 \fi +%D \message{(\the\scratchcounter\space lines)]}% +%D \egroup +%D \wd0=\PDFwidth +%D \vbox to \PDFheight +%D {\forgetall +%D \vfill +%D \PDFcode{q}% +%D \PDFcode{1 0 0 1 \PDFxoffset\space \PDFyoffset\space cm}% +%D \PDFcode{\PDFxscale\space 0 0 \PDFyscale\space 0 0 cm}% +%D \box0 +%D \PDFcode{Q}}} +%D +%D \def\stopPDFtoPDF% +%D {\message{[PDF to PDF \PDFfilename\space not found]}} +%D +%D \def\convertPDFtoPDF#1#2#3#4#5#6#7% +%D {\bgroup +%D \def\PDFfilename{#1}% +%D \def\PDFxscale {#2}% +%D \def\PDFyscale {#3}% +%D \setPDFboundingbox{#4}{#5}{#6}{#7}{1}{1}% +%D \uncatcodespecials +%D \endlinechar=-1 +%D \let\doprocessPDFline=\handlePDFline +%D \doprocessfile\scratchread\PDFfilename\doprocessPDFline +%D \stopPDFtoPDF +%D \egroup} + +\def\convertPDFtoPDF#1#2#3#4#5#6#7% + {\message{[PDF to PDF use \string\PDFcode instead]}% + \vbox{use the direct method instead}} + +%D \macros +%D {dogetPDFmediabox} +%D +%D The next macro can be used to find the mediabox of a \PDF\ +%D illustration. +%D +%D \starttyping +%D \dogetPDFmediabox +%D {filename} +%D {new dimen}{new dimen}{new dimen}{new dimen} +%D \stoptyping +%D +%D Beware of dimen clashes: this macro uses the 5~default +%D scratch registers! When no file or mediabox is found, the +%D dimensions are zeroed. + +\def\dogetPDFmediabox#1#2#3#4#5% + {\bgroup + \def\PDFxscale{1}% + \def\PDFyscale{1}% + \uncatcodespecials + \endlinechar\minusone + \def\checkPDFtypepage##1/Type /Page##2##3\done% + {\ifx##2\relax + \else\if##2s% accept /Page and /Pages + \let\doprocessPDFline\findPDFmediabox + \else + \let\doprocessPDFline\findPDFmediabox + \fi\fi}% + \def\findPDFtypepage + {\expandafter\checkPDFtypepage\fileline/Type /Page\relax\done}% + \def\checkPDFmediabox##1/MediaBox##2##3\done% + {\ifx##2\relax \else + \setPDFmediabox##2##3\done + \fileprocessedtrue + \fi}% + \def\findPDFmediabox + {\expandafter\checkPDFmediabox\fileline/MediaBox\relax\done}% + \let\doprocessPDFline\findPDFtypepage + \doprocessfile\scratchread{#1}\doprocessPDFline + \egroup + \ifx\PDFxoffset\undefined + #2\zeropoint + #3\zeropoint + #4\zeropoint + #5\zeropoint + \else + #2=\PDFxoffset\onebasepoint + #3=\PDFyoffset\onebasepoint + #4=\PDFwidth + #5=\PDFheight + \fi} + +%D \macros +%D {convertMPtoPDF} +%D +%D The next set of macros implements \METAPOST\ to \PDF\ +%D conversion. Because we want to test as fast as possible, we +%D first define the \POSTSCRIPT\ operators that \METAPOST\ +%D uses. We don't define irrelevant ones, because these are +%D skipped anyway. + +%D The converter can be made a bit faster by replacing the +%D two test macros (the ones with the many \type {\if's}) by +%D a call to named branch macros (something \typ {\getvalue +%D {xPSmoveto}}. For everyday documents with relatively +%D small graphics the gain in speed can be neglected. + +\def \PScurveto {curveto} +\def \PSlineto {lineto} +\def \PSmoveto {moveto} +\def \PSshowpage {showpage} +\def \PSnewpath {newpath} +\def \PSfshow {fshow} +\def \PSclosepath {closepath} +\def \PSfill {fill} +\def \PSstroke {stroke} +\def \PSclip {clip} +\def \PSrlineto {rlineto} +\def \PSsetlinejoin {setlinejoin} +\def \PSsetlinecap {setlinecap} +\def \PSsetmiterlimit {setmiterlimit} +\def \PSsetgray {setgray} +\def \PSsetrgbcolor {setrgbcolor} +\def \PSsetcmykcolor {setcmykcolor} +\def \PSsetdash {setdash} +\def \PSgsave {gsave} +\def \PSgrestore {grestore} +\def \PStranslate {translate} +\def \PSscale {scale} +\def \PSconcat {concat} +\def \PSdtransform {dtransform} +\def \PSsetlinewidth {setlinewidth} +\def \PSpop {pop} + +\def \PSnfont {nfont} % was needed for TUG98 proceedings +\def \PSspecial {special} % extensions to MetaPost + +%D A previous version set \type {%} to ignore, which +%D simplified the following definitions. At the start of +%D conversion the percent character was made active again. +%D Because the whole graphic is one paragraph (there are no +%D empty lines) this does not give the desired effect. This +%D went unnoticed untill Scott Pakin sent me a test file +%D percent characters in a string. So, from now on we have +%D to prefix the following strings with percentages. + +\edef \PSBoundingBox {\letterpercent\letterpercent BoundingBox:} +\edef \PSHiResBoundingBox {\letterpercent\letterpercent HiResBoundingBox:} +\edef \PSExactBoundingBox {\letterpercent\letterpercent ExactBoundingBox:} +\edef \PSMetaPostSpecial {\letterpercent\letterpercent MetaPostSpecial:} +\edef \PSMetaPostSpecials {\letterpercent\letterpercent MetaPostSpecials:} +\edef \PSPage {\letterpercent\letterpercent Page:} + +%D By the way, the \type {setcmykcolor} operator is not +%D output by \METAPOST\ but can result from converting the +%D \cap{RGB} color specifications, as implemented in +%D \type{supp-mps}. + +%D In \POSTSCRIPT\ arguments precede the operators. Due to the +%D fact that in some translations we need access to those +%D arguments, and also because sometimes we have to skip them, +%D we stack them up. The stack is one||dimensional for non path +%D operators and two||dimensional for operators inside a path. +%D This is because we have to save the whole path for +%D (optional) postprocessing. Values are pushed onto the stack +%D by: +%D +%D \starttyping +%D \setMPargument {value} +%D \stoptyping +%D +%D They can be retrieved by the short named macros: +%D +%D \starttyping +%D \gMPa {number} +%D \gMPs {number} +%D \stoptyping +%D +%D When scanning a path specification, we also save the +%D operator, using +%D +%D \starttyping +%D \setMPkeyword {n} +%D \stoptyping +%D +%D The path drawing operators are coded for speed: \type{clip}, +%D \type{stroke}, \type{fill} and \type{fillstroke} become +%D 1, 2, 3 and~4. +%D +%D When processing the path this code can be retrieved +%D using +%D +%D \starttyping +%D \getMPkeyword % {n} +%D \stoptyping +%D +%D When setting an argument, the exact position on the stack +%D depends on the current value of the \COUNTERS\ +%D \type{\nofMPsegments} and \type{\nofMParguments}. + +\newcount\nofMPsegments +\newcount\nofMParguments + +%D These variables hold the coordinates. The argument part of +%D the stack is reset by: +%D +%D \starttyping +%D \resetMPstack +%D \stoptyping +%D +%D We use the prefix \type{@@MP} to keep the stack from +%D conflicting with existing macros. To speed up things a bit +%D more, we use the constant \type{\@@MP}. + +\def\@@MP{@@MP} + +\def\setMPargument% #1% + {\advance\nofMParguments \plusone + \expandafter\def + \csname\@@MP\the\nofMPsegments\the\nofMParguments\endcsname} % {#1} + +\def\letMPargument + {\advance\nofMParguments \plusone + \expandafter\let + \csname\@@MP\the\nofMPsegments\the\nofMParguments\endcsname} + +\def\setMPsequence#1 % + {\advance\nofMParguments \plusone + \expandafter\def + \csname\@@MP\the\nofMPsegments\the\nofMParguments\endcsname{#1}% + \handleMPsequence} + +\def\gMPa#1% + {\csname\@@MP0\number#1\endcsname} + +\def\gMPs#1% + {\csname\@@MP\the\nofMPsegments\number#1\endcsname} + +\def\dogMPa#1% + {\@EAEAEA\do\csname\@@MP0\number#1\endcsname} + +\def\setMPkeyword#1 % + {\expandafter\def\csname\@@MP\the\nofMPsegments0\endcsname{#1}% + \advance\nofMPsegments \plusone + \nofMParguments\zerocount} + +\def\getMPkeyword% #1% + {\csname\@@MP\the\nofMPsegments0\endcsname} % {\csname\@@MP#10\endcsname} + +%D When we reset the stack, we can assume that all further +%D comment is to be ignored and handled in strings. +%D By redefining the reset macro after the first call, we +%D save some run time. Only use this macro after all +%D comments are processed and use the simple alternative +%D when dealing with comments. + +\def\doresetMPstack + {\nofMParguments\zerocount} + +\def\resetMPstack + {\let\handleMPgraphic\handleMPendgraphic + \let\resetMPstack\doresetMPstack + \resetMPstack} + +%D The arguments are saved with the preceding command +%D \type{\do}. By default this command expands to nothing, but +%D when we deal with strings it's used to strip off the +%D \type{(} and \type{)}. +%D +%D Strings are kind of tricky, because characters can be +%D passed verbatim \type{(hello)}, by octal number +%D \type{(\005)} or as command \type{(\()}. We therefore +%D cannot simply ignore \type{(} and \type{)}, the way we do +%D with \type{[} and \type{]}. Another complication is that +%D strings may contain characters that normally have a +%D special meaning in \TEX, like \type{$} and \type{{}}. +%D +%D A previous solution made \type{\} an active character and +%D let it look ahead for a number or characters. We had to +%D abandon this scheme because of the need for verbatim +%D support. The next solution involved some \CATCODE\ +%D trickery but works well. + +\def\octalMPcharacter#1#2#3% + {\char'#1#2#3\relax} + +\bgroup +\catcode`\|=\@@comment +\catcode`\%=\@@active +\catcode`\[=\@@active +\catcode`\]=\@@active +\catcode`\{=\@@active +\catcode`\}=\@@active +\catcode`B=\@@begingroup +\catcode`E=\@@endgroup +\gdef\ignoreMPspecials| + B\let%\letterpercent| + \def[BE| + \def]BE| + \def{BE| + \def}BEE +\gdef\obeyMPspecials| + B\def%B\char 37\relax E| + \def[B\char 91\relax E| + \def]B\char 93\relax E| + \def{B\char123\relax E| + \def}B\char125\relax EE +\gdef\setMPspecials| + B\setnaturalcatcodes + \catcode`\\=\@@escape + \catcode`\%=\@@active + \catcode`\[=\@@active + \catcode`\]=\@@active + \catcode`\{=\@@active + \catcode`\}=\@@active + \lccode`\-=0 | latex sets this to `\- + \lccode`\%=`\% | otherwise it's seen as a number + \def\(B\char40\relax E| + \def\)B\char41\relax E| + \def\\B\char92\relax E| + \def\0B\octalMPcharacter0E| + \def\1B\octalMPcharacter1E| + \def\2B\octalMPcharacter2E| + \def\3B\octalMPcharacter3E| + \def\4B\octalMPcharacter4E| + \def\5B\octalMPcharacter5E| + \def\6B\octalMPcharacter6E| + \def\7B\octalMPcharacter7E| + \def\8B\octalMPcharacter8E| + \def\9B\octalMPcharacter9EE +\egroup + +%D We use the comment symbol as a sort of trigger. Beware! +%D The whole graphic is seen as on eparagraph, which means +%D that we cannot change the catcodes in between. + +\bgroup +\catcode`\%=\@@active +\gdef\startMPscanning{\let%=\startMPconversion} +\egroup + +%D In earlier versions we used the sequence +%D +%D \starttyping +%D \expandafter\handleMPsequence\input filename\relax +%D \stoptyping +%D +%D Persistent problems in \LATEX\ however forced us to use a +%D different scheme. Every \POSTSCRIPT\ file starts with a +%D \type{%}, so we temporary make this an active character +%D that starts the scanning and redefines itself. (The problem +%D originates in the redefinition by \LATEX\ of the +%D \type{\input} primitive.) + +\def\startMPconversion + {\ignoreMPspecials + \handleMPsequence} + +%D Here comes the main loop. Most arguments are numbers. This +%D means that they can be recognized by their \type{\lccode}. +%D This method saves a lot of processing time. We could +%D speed up the conversion by handling the \type{path} +%D seperately. + +\def\@EAEAEA{\expandafter\expandafter\expandafter} % to be sure + +\def\dohandleMPsequence#1% + {\ifdone + \ifcase\lccode`#1\relax + \@EAEAEA\dohandleMPsequenceA + \else + \@EAEAEA\dohandleMPsequenceB + \fi + \else + \@EA\dohandleMPsequenceC + \fi#1} + +%\def\dohandleMPsequenceA#1 % +% {\setMPargument{#1}% +% \handleMPsequence} + +\let\dohandleMPsequenceA\setMPsequence + +\def\dohandleMPsequenceB#1 % + {\edef\somestring{#1}% + \ifx\somestring\PSmoveto + \edef\lastMPmoveX{\gMPa1}% + \edef\lastMPmoveY{\gMPa2}% + \PDFcode{\!MPgMPa1 \!MPgMPa2 m}% + \resetMPstack + \else\ifx\somestring\PSnewpath + \let\handleMPsequence\handleMPpath + \else\ifx\somestring\PSgsave + \PDFcode{q}% + \resetMPstack + \else\ifx\somestring\PSgrestore + \PDFcode{Q}% + \resetMPstack + \else\ifx\somestring\PSdtransform % == setlinewidth + \let\handleMPsequence\handleMPdtransform + % after that we will encounter more tokens until setlinewidth+pop + % or pop+setlinewidth which we catch next; we explicitly need to + % reset the stack since [] n setdash may follow; a more clever + % approach would be to read on till the condition is met, but it's + % the only pop / setlinewidth we will encounter so ... + \else\ifx\somestring\PSsetlinewidth + % already handled in dtransform + \resetMPstack + \else\ifx\somestring\PSpop + % already handled in dtransform + \resetMPstack + \else\ifx\somestring\PSconcat + \PDFcode{\gMPa1 \gMPa2 \gMPa3 \gMPa4 \gMPa5 \gMPa6 cm}% + \resetMPstack + \else\ifx\somestring\PSsetrgbcolor + \handleMPrgbcolor + \resetMPstack + \else\ifx\somestring\PSsetcmykcolor + \handleMPcmykcolor + \resetMPstack + \else\ifx\somestring\PSsetgray + \handleMPgraycolor + \resetMPstack + \else\ifx\somestring\PStranslate + \PDFcode{1 0 0 1 \gMPa1 \gMPa2 cm}% + \resetMPstack + \else\ifx\somestring\PSsetdash + \handleMPsetdash + \resetMPstack + \else\ifx\somestring\PSsetlinejoin + \PDFcode{\gMPa1 j}% + \resetMPstack + \else\ifx\somestring\PSsetmiterlimit + \PDFcode{\gMPa1 M}% + \resetMPstack + \else\ifx\somestring\PSfshow + \PDFcode{n}% + \handleMPfshow + \resetMPstack + \else\ifx\somestring\PSsetlinecap + \PDFcode{\gMPa1 J}% + \resetMPstack + \else\ifx\somestring\PSrlineto + \PDFcode{\!MP\lastMPmoveX\space\!MP\lastMPmoveY\space l S}% + \resetMPstack + \else\ifx\somestring\PSscale + \PDFcode{\gMPa1 0 0 \gMPa2 0 0 cm}% + \resetMPstack + \else\ifx\somestring\PSspecial + \handleMPspecialcommand + \resetMPstack + \else + \handleMPgraphic% {#1}% + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \handleMPsequence} + +\def\dohandleMPsequenceC#1 % + {\edef\somestring{#1}% + \handleMPgraphic % {#1}% + \handleMPsequence} + +%D Since colors are not sensitive to transformations, they +%D are sometimes used for signaling. Therefore, we handle them +%D separately. The next macro can be redefined if needed. + +\def\handleMPrgbcolor + {\PDFcode{\!MPgMPa1 \!MPgMPa2 \!MPgMPa3 rg + \!MPgMPa1 \!MPgMPa2 \!MPgMPa3 RG}} + +\def\handleMPcmykcolor + {\PDFcode{\!MPgMPa1 \!MPgMPa2 \!MPgMPa3 \!MPgMPa4 k + \!MPgMPa1 \!MPgMPa2 \!MPgMPa3 \!MPgMPa4 K}} + +\def\handleMPgraycolor + {\PDFcode{\!MPgMPa1 g + \!MPgMPa1 G}} + +\def\handleMPspotcolor + {\PDFcode{0 g + 0 G}} + +%D Beginning and ending the graphics is taken care of by the +%D macro \type{\handleMPgraphic}, which is redefined when +%D the first graphics operator is met. + +\def\handleMPendgraphic % #1% + {\ifx\somestring\PSshowpage + \let\handleMPsequence\finishMPgraphic + \else + \letMPargument\somestring % {#1}% + \fi} + +\def\handleMPbegingraphic % #1% + {\ifx\somestring\PSBoundingBox + \def\handleMPsequence{\handleMPboundingbox1}% + \else\ifx\somestring\PSHiResBoundingBox + \def\handleMPsequence{\handleMPboundingbox2}% + \else\ifx\somestring\PSExactBoundingBox + \def\handleMPsequence{\handleMPboundingbox3}% + \else\ifx\somestring\PSshowpage + \let\handleMPsequence\finishMPgraphic + \else\ifx\somestring\PSPage + \let\handleMPsequence\handleMPpage + \else\ifx\somestring\PSMetaPostSpecials + \let\handleMPsequence\handleMPspecialscomment + \else\ifx\somestring\PSMetaPostSpecial + \let\handleMPsequence\handleMPspecialcomment + \else + \letMPargument\somestring % {#1}% + \fi\fi\fi\fi\fi\fi\fi} + +\let\handleMPgraphic=\handleMPbegingraphic + +%D We check for three kind of bounding boxes: the normal one +%D and two high precision ones: +%D +%D \starttyping +%D BoundingBox: llx lly ucx ucy +%D HiResBoundingBox: llx lly ucx ucy +%D ExactBoundingBox: llx lly ucx ucy +%D \stoptyping +%D +%D The original as well as the recalculated dimensions are +%D saved for later use. + +\newif\ifskipemptyMPgraphic \skipemptyMPgraphicfalse + +\chardef\currentMPboundingbox=0 + +\def\handleMPboundingbox#1#2 #3 #4 #5 + {\ifnum#1>\currentMPboundingbox + \xdef\MPllx{#2}\xdef\MPlly{#3}% + \xdef\MPurx{#4}\xdef\MPury{#5}% + \dimen0=#2\onepoint + \dimen0=-\MPxscale\dimen0 + \dimen2=#3\onepoint + \dimen2=-\MPyscale\dimen2 + \xdef\MPxoffset{\withoutpt\the\dimen0}% + \xdef\MPyoffset{\withoutpt\the\dimen2}% + \dimen0=#2\onebasepoint + \dimen0=-\dimen0 + \dimen2=#3\onebasepoint + \dimen2=-\dimen2 + \advance\dimen0 #4\onebasepoint + \dimen0=\MPxscale\dimen0 + \xdef\MPwidth{\the\dimen0}% + \advance\dimen2 #5\onebasepoint + \xdef\MPyshift{\the\dimen2}% unscaled + \dimen2=\MPyscale\dimen2 + \xdef\MPheight{\the\dimen2}% + \chardef\currentMPboundingbox#1\relax + \fi + \doresetMPstack + \let\handleMPsequence\dohandleMPsequence + \let\next\handleMPsequence + \ifskipemptyMPgraphic + \ifdim\MPheight=\zeropoint\relax\ifdim\MPwidth=\zeropoint\relax + \def\next{\endinput\finishMPgraphic}% + \fi\fi + \fi + \next} + +%D Unless defined otherwise, we simply ignore specialcomments. + +\def\handleMPspecialcomment + {\doresetMPstack + \let\handleMPsequence\dohandleMPsequence + \handleMPsequence} + +\let\handleMPspecialscomment\handleMPspecialcomment + +%D We use the \type{page} comment as a signal that +%D stackbuilding can be started. + +\def\handleMPpage #1 #2 + {\doresetMPstack + \donetrue + \let\handleMPsequence\dohandleMPsequence + \handleMPsequence} + +%D The same applies to the special extensions. + +\def\handleMPspecialcommand + {\doresetMPstack + \let\handleMPsequence\dohandleMPsequence + \handleMPsequence} + +%D \METAPOST\ draws its dots by moving to a location and +%D invoking \type{0 0 rlineto}. This operator is not +%D available in \PDF. Our solution is straightforward: we draw +%D a line from $(current\_x, current\_y)$ to itself. This +%D means that the arguments of the preceding \type{moveto} have +%D to be saved. + +\def\lastMPmoveX{0} +\def\lastMPmoveY{0} + +%D These saved coordinates are also used when we handle the +%D texts. Text handling proved to be a bit of a nuisance, but +%D finally I saw the light. It proved that we also had to +%D take care of \type{(split arguments)}. + +\def\setMPfshowfont#1#2% + {\font\temp=#1\space at #2\relax\temp} + +\let\MPfshowcommand\empty + +\def\dohandleMPfshow + {\bgroup + \setbox\scratchbox\hbox + {\obeyMPspecials + \edef\size{\gMPa\nofMParguments}% + \ifx\size\PSnfont % round font size (to pt) + \advance\nofMParguments \minusone + \expandafter\scratchdimen\gMPa\nofMParguments\onepoint\relax + \ifdim\scratchdimen<\onepoint + \def\size{1pt}% + \else + \advance\scratchdimen .5\onepoint + \def\size##1.##2\relax{\def\size{##1pt}}% + \expandafter\size\the\scratchdimen\relax + \fi + \else + \edef\size{\size bp}% + \fi + \advance\nofMParguments \minusone + %\font\temp=\gMPa\nofMParguments\space at \size + \let\temp\relax % to be sure + \setMPfshowfont{\gMPa\nofMParguments}\size + \advance\nofMParguments \minusone + \temp + \MPfshowcommand + {\ifnum\nofMParguments=\plusone + \def\do(##1){##1}% + \dogMPa1% + \else + % we need to catch ( a ) (a a a) (\123 \123 \123) etc + \scratchcounter\plusone + \def\dodo##1% Andreas Fieger's bug: (\304...) + {\edef\!!stringa{##1\empty\empty}% and another one: ( 11) -> \ifx 11 + \ifx\!!stringa\MPspacechar\MPspacechar\else\expandafter##1\fi}% + \def\do(##1{\dodo{##1}}% + \dogMPa\scratchcounter\MPspacechar + \let\do\relax + \loop + \advance\scratchcounter \plusone + \ifnum\scratchcounter<\nofMParguments\relax + \gMPa\scratchcounter\MPspacechar + \repeat + \def\do##1){\dodo{##1}}% + \dogMPa\scratchcounter + \fi + \unskip}}% + % + % this fails in some versions of pdftex + % + % \dimen0=\lastMPmoveY bp + % \advance\dimen0 by \ht0 + % \ScaledPointsToBigPoints{\number\dimen0}\lastMPmoveY + % \PDFcode{n q 1 0 0 1 \lastMPmoveX\space\lastMPmoveY\space cm}% + % \dimen0=\ht0 + % \advance\dimen0 by \dp0 + % \box0 + % \vskip-\dimen0 + % \PDFcode{Q}% + % \egroup} + % + \setbox\scratchbox\hbox + {\hskip\lastMPmoveX\onebasepoint\raise\lastMPmoveY\onebasepoint\box\scratchbox}% + \ht\scratchbox\zeropoint + \dp\scratchbox\zeropoint + \wd\scratchbox\zeropoint + \box\scratchbox + \egroup} + +\let\handleMPfshow\dohandleMPfshow % so we can overload this one later + +%D You could consider the following definition to be the most +%D natural one. + +% \def\MPspacechar{\space} % normal case + +\def\MPspacechar{\char32\relax} % old solution does not work with math + +%D However, the following implementation is more robust, since +%D some fonts have funny visible spaces in the space slot. This +%D gives a mismatch between the space that \METAPOST\ took into +%D account and the \quote {natural} space. This only happens in +%D labels, since \type {btex}||\type {etex} thingies don't have +%D spaces. This phenomena showed up when preparing the +%D \METAFUN\ manual, where Palatino fonts are used. We can +%D safely assume that \METAPOST\ considers \type {\char32} to +%D be the space. + +\def\MPspacechar{\setbox\scratchbox\hbox{\char32}\kern\wd\scratchbox} + +%D Well, this does not work with math fonts, so: + +\def\MPspacechar{\char32\relax} + +%D Most operators are just converted and keep their +%D arguments. Dashes however need a bit different treatment, +%D otherwise \PDF\ viewers complain loudly. Another +%D complication is that one argument comes after the \type{]}. +%D When reading the data, we simply ignore the array boundary +%D characters. We save ourselves some redundant newlines and +%D at the same time keep the output readable by packing the +%D literals. + +\def\handleMPsetdash + {\bgroup + \def\somestring{[}% + \scratchcounter\plusone + \loop + \ifnum\scratchcounter<\nofMParguments + \edef\somestring{\somestring\space\gMPa\scratchcounter}% + \advance\scratchcounter \plusone + \repeat + \edef\somestring{\somestring]\gMPa\scratchcounter\space d}% + \PDFcode{\somestring}% + \egroup} + +%D The \type{setlinewidth} commands looks a bit complicated. There are +%D two alternatives, that result in a similar look in both +%D $x$- and $y$-dorection. As John Hobby says: +%D +%D \startnarrower \switchtobodyfont[ss] +%D \starttyping +%D x 0 dtransform exch truncate exch idtransform pop setlinewidth +%D 0 y dtransform truncate idtransform setlinewidth pop +%D \stoptyping +%D +%D These are just fancy versions of \type{x setlinewidth} and +%D \type{y setlinewidth}. The \type{x 0 ...} form is used if +%D the path is {\em primarily vertical}. It rounds the width +%D so that vertical lines come out an integer number of pixels +%D wide in device space. The \type{0 y ...} form does the same +%D for paths that are {\em primarily horizontal}. The reason +%D why I did this is Knuth insists on getting exactly the +%D widths \TEX\ intends for the horizontal and vertical rules +%D in \type{btex...etex} output. (Note that PostScript scan +%D conversion rules cause a horizontal or vertical line of +%D integer width $n$ in device space to come out $n+1$ pixels +%D wide, regardless of the phase relative to the pixel grid.) +%D \stopnarrower +%D +%D The common operator in these sequences is \type{dtransform}, +%D so we can use this one to trigger setting the linewidth. + +\def\handleMPdtransform + {\ifdim\gMPa1\onepoint>\zeropoint + \PDFcode{\gMPa1 w}% + \def\next##1 ##2 ##3 ##4 ##5 ##6 {\handleMPsequence}% + \else + \PDFcode{\gMPa2 w}% + \def\next##1 ##2 ##3 ##4 {\handleMPsequence}% + \fi + \let\handleMPsequence\dohandleMPsequence + \resetMPstack + \next} + +%D The most complicated command is \type{concat}. \METAPOST\ +%D applies this operator to \type{stroke}. At that moment the +%D points set by \type{curveto} and \type{moveto}, are already +%D fixed. In \PDF\ however the \type{cm} operator affects the +%D points as well as the pen (stroke). Like more \PDF\ +%D operators, \type{cm} is defined in a bit ambiguous way. +%D The only save route for non||circular penshapes, is saving +%D the path, recalculating the points and applying the +%D transformation matrix in such a way that we can be sure +%D that its behavior is well defined. This comes down to +%D inverting the path and applying \type{cm} to that path as +%D well as the pen. This all means that we have to save the +%D path. + +%D In \METAPOST\ there are three ways to handle a path $p$: +%D +%D \starttyping +%D draw p; fill p; filldraw p; +%D \stoptyping +%D +%D The last case outputs a \type{gsave fill grestore} before +%D \type{stroke}. Handling the path outside the main loops +%D saves about 40\% run time.\footnoot{We can save some more by +%D following the \METAPOST\ output routine, but for the moment +%D we keep things simple.} Switching between the main loop and +%D the path loop is done by means of the recursely called +%D macro \type{\handleMPsequence}. + +\def\handleMPpath + {\chardef\finiMPpath0 + \let\closeMPpath\relax + \let\flushMPpath\flushnormalMPpath + \resetMPstack + \nofMPsegments\plusone + \let\handleMPsequence\dohandleMPpath + \dohandleMPpath} + +%D Most paths are drawn with simple round pens. Therefore we've +%D split up the routine in two. + +\def\flushnormalMPsegment + {\ifcase\getMPkeyword\relax + \PDFcode{\!MPgMPs1 \!MPgMPs2 l}% + \or + \PDFcode{\!MPgMPs1 \!MPgMPs2 \!MPgMPs3 \!MPgMPs4 \!MPgMPs5 \!MPgMPs6 c}% + \or + \PDFcode{\!MP\lastMPmoveX\space\!MP\lastMPmoveY\space l S}% + \or + \edef\lastMPmoveX{\gMPs1}% evt \!MP here + \edef\lastMPmoveY{\gMPs2}% + \PDFcode{\!MP\lastMPmoveX\space \!MP\lastMPmoveY\space m}% + \fi} + +\def\flushconcatMPsegment + {\ifcase\getMPkeyword\relax + \doMPconcat{\gMPs1}\a{\gMPs2}\b% + \PDFcode{\!MP\a\space\!MP\b\space l}% + \or + \doMPconcat{\gMPs1}\a{\gMPs2}\b% + \doMPconcat{\gMPs3}\c{\gMPs4}\d% + \doMPconcat{\gMPs5}\e{\gMPs6}\f% + \PDFcode{\!MP\a\space\!MP\b\space + \!MP\c\space\!MP\d\space + \!MP\e\space\!MP\f\space c}% + \or + \bgroup + \noMPtranslate + \doMPconcat\lastMPmoveX\a\lastMPmoveY\b% + \PDFcode{\!MP\a\space\!MP\b\space l S}% + \egroup + \or + \edef\lastMPmoveX{\gMPs1}% + \edef\lastMPmoveY{\gMPs2}% + \doMPconcat\lastMPmoveX\a\lastMPmoveY\b% + \PDFcode{\!MP\a\space\!MP\b\space m}% + \fi} + +% \def\flushnormalMPpath +% {\scratchcounter\nofMPsegments +% \nofMPsegments\plusone +% \loop +% \flushnormalMPsegment +% \advance\nofMPsegments \plusone +% \ifnum\nofMPsegments<\scratchcounter +% \repeat} +% +% \def\flushconcatMPpath +% {\scratchcounter\nofMPsegments +% \nofMPsegments\plusone +% \loop +% \flushconcatMPsegment +% \advance\nofMPsegments \plusone +% \ifnum\nofMPsegments<\scratchcounter +% \repeat} +% +% an alternative is presented below: (no \def assignment) + +\def\doflushsomeMPpath + {\dodoflushsomeMPpath + \advance\nofMPsegments \plusone + \ifnum\nofMPsegments<\scratchcounter + \expandafter\doflushsomeMPpath + \fi} + +\def\flushsomeMPpath + {\scratchcounter\nofMPsegments + \nofMPsegments\plusone + \doflushsomeMPpath} + +\def\flushnormalMPpath{\let\dodoflushsomeMPpath\flushnormalMPsegment\flushsomeMPpath} + +%OLD \def\flushconcatMPpath{\let\dodoflushsomeMPpath\flushconcatMPsegment\flushsomeMPpath} + +%NEW pre-calculate 1/D so it needn't be repeated for each control point. + +\def\flushconcatMPpath + {\MPreciprocaldeterminant + \let\dodoflushsomeMPpath\flushconcatMPsegment\flushsomeMPpath} + +%D The transformation of the coordinates is handled by one of +%D the macros Tanmoy posted to the \PDFTEX\ mailing list. +%D I rewrote and optimized the original macro to suit the other +%D macros in this module. +%D +%D \starttyping +%D \doMPconcat {x position} \xresult {y position} \yresult +%D \stoptyping +%D +%D By setting the auxiliary \DIMENSIONS\ \type{\dimen0} upto +%D \type{\dimen10} only once per path, we save over 20\% run +%D time. Some more speed was gained by removing some parameter +%D passing. These macros can be optimized a bit more by using +%D more constants. There is however not much need for further +%D optimization because penshapes usually are round and +%D therefore need no transformation. Nevertheless we move the +%D factor to the outer level and use a bit different \type{pt} +%D removal macro. Although the values represent base points, +%D we converted them to pure points, simply because those can +%D be converted back. + +%OLD \mathchardef\MPconcatfactor=256 % beware don't remove spaces before it + +%OLD \def\doMPreducedimen#1 +%OLD {\count0\MPconcatfactor +%OLD \advance\dimen#1 \ifdim\dimen#1>\zeropoint .5\else -.5\fi\count0 +%OLD \divide\dimen#1 \count0\relax} + +%OLD % too inaccurate (see old pragma logo) +%OLD +%OLD \def\doMPreducedimen#1 +%OLD {\count0=\MPconcatfactor +%OLD \divide\dimen#1 \count0\relax} + +%OLD \def\doMPreducedimen#1 +%OLD {\advance\dimen#1 \ifdim\dimen#1>\zeropoint .5\else -.5\fi\MPconcatfactor +%OLD \divide\dimen#1 \MPconcatfactor} + +%D The transformation code is rewritten by Daniel H. Luecking who +%D describes his patch as follows: +%D +%D We would like to divide 1 by $X4, but all divisions are integer so +%D for accuracy we want to convert to large integers and make sure the +%D integer quotient has as many significant digits as possible. Thus we +%D need to replace $1/X$ with $M/N$ where $N$ is as large as possible +%D and $M/N$ is as large as possible. Also for simplicity $M$ should be +%D a power of 2. So we make $M = 2^{30}$ \footnote{$2^{31} - 1$ is the +%D largest legal integer. Using it (and simply ignoring the inaccuracy +%D caused by $-1$) turns out to be at least as accurate in all cases, +%D and more accurate in some.} (largest legal power of 2) and adjust +%D $X4 downward (if necessary) to the the range $1-2^{16}$. This gives +%D at least 15 significant binary digits, (almost as accurate as +%D \METAPOST\ for numbers near 1) or almost 5 significant figures +%D (decimal). + +\newcount\MPscratchCnt +\newdimen\MPscratchDim % will be assigned global + +\def\MPadjustdimen % sets \MPscratchDim and \MPscratchCnt + {\MPscratchCnt\zerocount + \doMPadjustdimen} + +\def\doMPadjustdimen + {\ifdim\MPscratchDim>\onepoint + \divide\MPscratchDim 2 + \advance\MPscratchCnt \plusone + \expandafter\doMPadjustdimen + \fi} + +%OLD \def\doMPexpanddimen#1 +%OLD {\multiply\dimen#1 \MPconcatfactor\relax} + +%D DHL: When viewed as an integer, $1 \hbox{pt}=2^{16}$ so $2^{32}/X$ +%D is the right way to do $(1 \hbox{pt})/(X \hbox{pt})$ and get the +%D answer in points. But we are limited to $2^{30}/X$. However, we +%D actually do $[ 2^{30} / (X/2^K) ]*2^{2-K}$ where $K$ is the number +%D of halvings it takes to bring $X4 below $1 \hbox{pt}$. If $K$ is 0 +%D or 1 we readjust by multiplying by 4 or 2, otherwise by halving +%D $(K-2)$ times \type {\MPscratchCnt} holds the value of $K$ from +%D \type {\MPadjustdimen}. + +\def\MPreadjustdimen % acts on \MPscratchDim and MPscratchCnt + {\ifcase\MPscratchCnt + \multiply\MPscratchDim 4 + \or + \multiply\MPscratchDim 2 + \else + \expandafter\doMPreadjustdimen + \fi} + +\def\doMPreadjustdimen + {\ifnum\MPscratchCnt > 2 + \divide\MPscratchDim 2 + \advance\MPscratchCnt \minusone + \expandafter\doMPreadjustdimen + \fi} + +\def\MPreciprocaldeterminant + {\MPscratchDim\withoutpt\the\dimen0 \dimen6 % s_x*s_y + \advance\MPscratchDim - \withoutpt\the\dimen2 \dimen4 % s_x*s_y - r_x*r_y + \ifdim\MPscratchDim<\zeropoint % we need a positive dimension + \MPscratchDim-\MPscratchDim % for \MPadjustdimen + \doMPreciprocal + \MPscratchDim-\MPscratchDim + \else + \doMPreciprocal + \fi} + +\newcount\MPnumerator \MPnumerator = 1073741824 % 2^{30} + +% todo: dimexpr + +\def\doMPreciprocal % replace \MPscratchDim with its reciprocal + {\ifdim\MPscratchDim=\onepoint \else + \MPadjustdimen + \scratchcounter\MPnumerator + \divide\scratchcounter\MPscratchDim + \MPscratchDim1\scratchcounter % 1 needed ! + \MPreadjustdimen + \fi} + +%OLD \def\presetMPconcat +%OLD {\dimen 0=\gMPs1\onepoint \doMPreducedimen 0 % r_x +%OLD \dimen 2=\gMPs2\onepoint \doMPreducedimen 2 % s_x +%OLD \dimen 4=\gMPs3\onepoint \doMPreducedimen 4 % s_y +%OLD \dimen 6=\gMPs4\onepoint \doMPreducedimen 6 % r_y +%OLD \dimen 8=\gMPs5\onepoint \doMPreducedimen 8 % t_x +%OLD \dimen10=\gMPs6\onepoint \doMPreducedimen10 } % t_y +%OLD +%OLD \def\presetMPscale +%OLD {\dimen 0=\gMPs1\onepoint \doMPreducedimen 0 +%OLD \dimen 2 \zeropoint +%OLD \dimen 4 \zeropoint +%OLD \dimen 6=\gMPs2\onepoint \doMPreducedimen 6 +%OLD \dimen 8 \zeropoint +%OLD \dimen10 \zeropoint} + +\def\presetMPconcat + {\dimen 0=\gMPs1\onepoint % s_x + \dimen 2=\gMPs2\onepoint % r_x + \dimen 4=\gMPs3\onepoint % r_y + \dimen 6=\gMPs4\onepoint % s_y + \dimen 8=\gMPs5\onepoint % t_x + \dimen10=\gMPs6\onepoint} % t_y + +\def\presetMPscale + {\dimen 0=\gMPs1\onepoint + \dimen 2 \zeropoint + \dimen 4 \zeropoint + \dimen 6=\gMPs2\onepoint + \dimen 8 \zeropoint + \dimen10 \zeropoint} + +\def\noMPtranslate % use this one grouped + {\dimen 8 \zeropoint % t_x + \dimen10 \zeropoint} % t_y + +%D \starttyping +%D \def\doMPconcat#1#2#3#4% +%D {\dimen12=#1 pt \doMPreducedimen12 % p_x +%D \dimen14=#3 pt \doMPreducedimen14 % p_y +%D % +%D \dimen16 \dimen 0 +%D \multiply \dimen16 \dimen 6 +%D \dimen20 \dimen 2 +%D \multiply \dimen20 \dimen 4 +%D \advance \dimen16 -\dimen20 +%D % +%D \dimen18 \dimen12 +%D \multiply \dimen18 \dimen 6 +%D \dimen20 \dimen14 +%D \multiply \dimen20 \dimen 4 +%D \advance \dimen18 -\dimen20 +%D \dimen20 \dimen 4 +%D \multiply \dimen20 \dimen10 +%D \advance \dimen18 \dimen20 +%D \dimen20 \dimen 6 +%D \multiply \dimen20 \dimen 8 +%D \advance \dimen18 -\dimen20 +%D % +%D \multiply \dimen12 -\dimen 2 +%D \multiply \dimen14 \dimen 0 +%D \advance \dimen12 \dimen14 +%D \dimen20 \dimen 2 +%D \multiply \dimen20 \dimen 8 +%D \advance \dimen12 \dimen20 +%D \dimen20 \dimen 0 +%D \multiply \dimen20 \dimen10 +%D \advance \dimen12 -\dimen20 +%D % +%D \doMPreducedimen16 +%D \divide \dimen18 \dimen16 \doMPexpanddimen18 +%D \divide \dimen12 \dimen16 \doMPexpanddimen12 +%D % +%D \edef#2{\withoutpt\the\dimen18}% % p_x^\prime +%D \edef#4{\withoutpt\the\dimen12}} % p_y^\prime +%D \stoptyping + +%D The following optimization resulted from some tests by +%D and email exchanges with Sanjoy Mahajan. +%D +%D \starttyping +%D \def\doMPconcat#1#2#3#4% +%D {\dimen12=#1 pt \doMPreducedimen12 % p_x +%D \dimen14=#3 pt \doMPreducedimen14 % p_y +%D % +%D \dimen16 \dimen 0 +%D \multiply \dimen16 \dimen 6 +%D \dimen20 \dimen 2 +%D \multiply \dimen20 \dimen 4 +%D \advance \dimen16 -\dimen20 +%D % +%D \dimen18 \dimen12 +%D \multiply \dimen18 \dimen 6 +%D \dimen20 \dimen14 +%D \multiply \dimen20 \dimen 4 +%D \advance \dimen18 -\dimen20 +%D \dimen20 \dimen 4 +%D \multiply \dimen20 \dimen10 +%D \advance \dimen18 \dimen20 +%D \dimen20 \dimen 6 +%D \multiply \dimen20 \dimen 8 +%D \advance \dimen18 -\dimen20 +%D % +%D \multiply \dimen12 -\dimen 2 +%D \multiply \dimen14 \dimen 0 +%D \advance \dimen12 \dimen14 +%D \dimen20 \dimen 2 +%D \multiply \dimen20 \dimen 8 +%D \advance \dimen12 \dimen20 +%D \dimen20 \dimen 0 +%D \multiply \dimen20 \dimen10 +%D \advance \dimen12 -\dimen20 +%D % +%D %\ifdim\dimen16>1pt % oeps, can be < 1pt too +%D \ifdim\dimen16=1pt \else +%D \ifdim\dimen16>\MPconcatfactor pt +%D \doMPreducedimen16 +%D \divide \dimen18 \dimen16 \doMPexpanddimen18 +%D \divide \dimen12 \dimen16 \doMPexpanddimen12 +%D \else +%D \divide \dimen18 \dimen16 \doMPexpanddimen18 \doMPexpanddimen18 +%D \divide \dimen12 \dimen16 \doMPexpanddimen12 \doMPexpanddimen12 +%D \fi +%D \fi +%D % +%D \edef#2{\withoutpt\the\dimen18}% % p_x^\prime +%D \edef#4{\withoutpt\the\dimen12}} % p_y^\prime +%D \stoptyping +%D +%D But, this one is still too inaccurate, so we now have: + +% \def\doMPconcat#1#2#3#4% +% {\dimen12=#1pt % p_x +% \dimen14=#3pt % p_y +% % +% % we should test for >-1024 too, but for the moment take the gamble +% \chardef\MPfactor1\ifdim\dimen12<1024pt \ifdim\dimen14<1024pt 6\fi\fi +% % +% \multiply\dimen12 \MPfactor +% \multiply\dimen14 \MPfactor +% % +% \doMPreducedimen12 +% \doMPreducedimen14 +% % +% \dimen16 \dimen 0 +% \multiply \dimen16 \dimen 6 +% \dimen20 \dimen 2 +% \multiply \dimen20 \dimen 4 +% \advance \dimen16 -\dimen20 +% % +% \dimen18 \dimen12 +% \multiply \dimen18 \dimen 6 +% \dimen20 \dimen14 +% \multiply \dimen20 \dimen 4 +% \advance \dimen18 -\dimen20 +% \dimen20 \dimen 4 +% \multiply \dimen20 \dimen10 +% \advance \dimen18 \dimen20 +% \dimen20 \dimen 6 +% \multiply \dimen20 \dimen 8 +% \advance \dimen18 -\dimen20 +% % +% \multiply \dimen12 -\dimen 2 +% \multiply \dimen14 \dimen 0 +% \advance \dimen12 \dimen14 +% \dimen20 \dimen 2 +% \multiply \dimen20 \dimen 8 +% \advance \dimen12 \dimen20 +% \dimen20 \dimen 0 +% \multiply \dimen20 \dimen10 +% \advance \dimen12 -\dimen20 +% % +% \ifdim\dimen16=1pt \else +% \ifdim\dimen16>\MPconcatfactor pt +% \doMPreducedimen16 +% \divide \dimen18 \dimen16 \doMPexpanddimen18 +% \divide \dimen12 \dimen16 \doMPexpanddimen12 +% \else +% \divide \dimen18 \dimen16 \doMPexpanddimen18 \doMPexpanddimen18 +% \divide \dimen12 \dimen16 \doMPexpanddimen12 \doMPexpanddimen12 +% \fi +% \fi +% % +% \divide\dimen18 \MPfactor +% \divide\dimen12 \MPfactor +% % +% \edef#2{\withoutpt\the\dimen18}% % p_x^\prime +% \edef#4{\withoutpt\the\dimen12}} % p_y^\prime + +%D We cannot use \type {\beginETEX} here since in plain we +%D get \type {\outer} problems, sigh. + +%OLD \beginTEX +%OLD +%OLD \def\MPcriteriumA {512pt} % scale +%OLD \def\MPcriteriumB {2pt} % scale +%OLD +%OLD \endTEX +%OLD +%OLD \ifx\MPcriteriumA\undefined +%OLD +%OLD \newdimen\MPcriteriumA \MPcriteriumA=512pt +%OLD \newdimen\MPcriteriumB \MPcriteriumB= 2pt +%OLD +%OLD \fi + +%OLD \def\doMPconcat#1#2#3#4% +%OLD {\dimen12=#1pt % p_x +%OLD \dimen14=#3pt % p_y +%OLD % +%OLD \chardef\MPfactor\zerocount +%OLD \ifdim\dimen4<\MPcriteriumB\ifdim\dimen4>-\MPcriteriumB +%OLD \ifdim\dimen6<\MPcriteriumB\ifdim\dimen6>-\MPcriteriumB +%OLD \ifdim\dimen8<\MPcriteriumB\ifdim\dimen8>-\MPcriteriumB +%OLD \ifdim\dimen10<\MPcriteriumB\ifdim\dimen10>-\MPcriteriumB +%OLD \chardef\MPfactor\plusone +%OLD \fi\fi +%OLD \fi\fi +%OLD \fi\fi +%OLD \fi\fi +%OLD \ifcase\MPfactor % spurious 0 removed +%OLD \chardef\MPfactor\plusone +%OLD \ifdim\dimen12<\MPcriteriumA\ifdim\dimen12>-\MPcriteriumA +%OLD \ifdim\dimen14<\MPcriteriumA\ifdim\dimen14>-\MPcriteriumA +%OLD \chardef\MPfactor16 +%OLD \fi\fi +%OLD \fi\fi +%OLD \fi +%OLD % +%OLD \multiply\dimen12 \MPfactor +%OLD \multiply\dimen14 \MPfactor +%OLD % +%OLD \doMPreducedimen12 +%OLD \doMPreducedimen14 +%OLD % +%OLD \dimen16 \dimen 0 +%OLD \multiply \dimen16 \dimen 6 +%OLD \dimen20 \dimen 2 +%OLD \multiply \dimen20 \dimen 4 +%OLD \advance \dimen16 -\dimen20 +%OLD % +%OLD \dimen18 \dimen12 +%OLD \multiply \dimen18 \dimen 6 +%OLD \dimen20 \dimen14 +%OLD \multiply \dimen20 \dimen 4 +%OLD \advance \dimen18 -\dimen20 +%OLD \dimen20 \dimen 4 +%OLD \multiply \dimen20 \dimen10 +%OLD \advance \dimen18 \dimen20 +%OLD \dimen20 \dimen 6 +%OLD \multiply \dimen20 \dimen 8 +%OLD \advance \dimen18 -\dimen20 +%OLD % +%OLD \multiply \dimen12 -\dimen 2 +%OLD \multiply \dimen14 \dimen 0 +%OLD \advance \dimen12 \dimen14 +%OLD \dimen20 \dimen 2 +%OLD \multiply \dimen20 \dimen 8 +%OLD \advance \dimen12 \dimen20 +%OLD \dimen20 \dimen 0 +%OLD \multiply \dimen20 \dimen10 +%OLD \advance \dimen12 -\dimen20 +%OLD % +%OLD \ifdim\dimen16=\onepoint \else +%OLD \ifdim\dimen16>\MPconcatfactor \onepoint \relax +%OLD \doMPreducedimen16 +%OLD \divide \dimen18 \dimen16 \doMPexpanddimen18 +%OLD \divide \dimen12 \dimen16 \doMPexpanddimen12 +%OLD \else +%OLD \divide \dimen18 \dimen16 \doMPexpanddimen18 \doMPexpanddimen18 +%OLD \divide \dimen12 \dimen16 \doMPexpanddimen12 \doMPexpanddimen12 +%OLD \fi +%OLD \fi +%OLD % +%OLD \divide\dimen18 \MPfactor +%OLD \divide\dimen12 \MPfactor +%OLD % +%OLD \edef#2{\withoutpt\the\dimen18}% % p_x^\prime +%OLD \edef#4{\withoutpt\the\dimen12}} % p_y^\prime + +%D DHL: Ideally, $r_x$, $r_y$, $s_x4, $s_y$ should be in macros, not +%D dimensions (they are scalar quantities after all, not lengths). I +%D suppose the authors decided to do calculations with integer +%D arithmetic instead of using real factors because it's faster. +%D However, the actual macros test slower, possibly because I've +%D omitted three nested loops. In my test files, my approach is more +%D accurate. It is also far simpler and overflow does not seem to be a +%D significant concern. The scale factors written by Metapost are (?) +%D always $<=1$ (it scales coordinates internally) and coordinates are +%D always likely to be less than \type {\maxdimen}. +%D +%D If this should ever cause problems, the scale factors can be reduced. + +\def\doMPconcat#1#2#3#4% + {\dimen12=#1pt % p_x % #1\onepoint + \dimen14=#3pt % p_y % #3\onepoint + \advance\dimen12 -\dimen8 % p_x - t_x + \advance\dimen14 -\dimen10 % p_y - t_y + \dimen18=\withoutpt\the\dimen6 \dimen12 % s_y(p_x - t_x) + \advance\dimen18 -\withoutpt\the\dimen4 \dimen14 % - r_y(p_y-t_y) + \dimen14=\withoutpt\the\dimen0 \dimen14 % s_x(p_y-t_y) + \advance\dimen14 -\withoutpt\the\dimen2 \dimen12 % - r_x(p_x-t_x) + % \MPscratchDim contains precomputed 1/D: + \dimen18=\withoutpt\the\MPscratchDim \dimen18 + \dimen14=\withoutpt\the\MPscratchDim \dimen14 + \edef#2{\withoutpt\the\dimen18}% % p_x^\prime + \edef#4{\withoutpt\the\dimen14}} % p_y^\prime + +%D One reason for Daniel to write this patch was that at small sizes +%D the accuracy was less than optimal. Here is a test that demonstrates +%D that his alternative is pretty good: +%D +%D \startlinecorrection +%D \startMPcode +%D for i = 5cm,1cm,5mm,1mm,.5mm,.1mm,.01mm : +%D draw fullcircle scaled i withpen pencircle xscaled (i/10) yscaled (i/20) rotated 45 ; +%D endfor ; +%D \stopMPcode +%D \stoplinecorrection + +%D The following explanation of the conversion process was +%D posted to the \PDFTEX\ mailing list by Tanmoy. The original +%D macro was part of a set of macro's that included sinus and +%D cosinus calculations as well as scaling and translating. The +%D \METAPOST\ to \PDF\ conversion however only needs +%D transformation. + +%M \start \switchtobodyfont [ss] + +%D Given a point $(U_x, U_y)$ in user coordinates, the business +%D of \POSTSCRIPT\ is to convert it to device space. Let us say +%D that the device space coordinates are $(D_x, D_y)$. Then, in +%D \POSTSCRIPT\ $(D_x, D_y)$ can be written in terms of +%D $(U_x, U_y)$ in matrix notation, either as +%D +%D \placeformula +%D \startformula +%D \pmatrix{D_x&D_y&1\cr} = \pmatrix{U_x&U_y&1\cr} +%D \pmatrix{s_x&r_x&0\cr +%D r_y&s_y&0\cr +%D t_x&t_y&1\cr} +%D \stopformula +%D +%D or +%D +%D \placeformula +%D \startformula +%D \pmatrix{D_x\cr D_y\cr 1} = \pmatrix{s_x&r_y&t_x\cr +%D r_x&s_y&t_y\cr +%D 0 &0 &1 \cr} +%D \pmatrix{U_x\cr +%D U_y\cr +%D 1 \cr} +%D \stopformula +%D +%D both of which is a shorthand for the same set of equations: +%D +%D \placeformula +%D \startformula +%D D_x = s_x U_x + r_y U_y + t_x +%D \stopformula +%D +%D \placeformula +%D \startformula +%D D_y = r_x U_x + s_y U_y + t_y +%D \stopformula +%D +%D which define what is called an `affine transformation'. +%D +%D \POSTSCRIPT\ represents the `transformation matrix' as a +%D six element matrix instead of a $3\times 3$ array because +%D three of the elements are always~0, 0 and~1. Thus the above +%D transformation is written in postscript as $[s_x\, r_x\, +%D r_y\, s_y\, t_x\, t_y]$. However, when doing any +%D calculations, it is useful to go back to the original +%D matrix notation (whichever: I will use the second) and +%D continue from there. +%D +%D As an example, if the current transformation matrix is +%D $[s_x\, r_x\, r_y\, s_y\, t_x\, t_y]$ and you say \typ{[a b +%D c d e f] concat}, this means: +%D +%D \startnarrower +%D Take the user space coordinates and transform them to an +%D intermediate set of coordinates using array $[a\, b\, c\, d\, +%D e\, f]$ as the transformation matrix. +%D +%D Take the intermediate set of coordinates and change them to +%D device coordinates using array $[s_x\, r_x\, r_y\, s_y\, t_x\, t_y]$ +%D as the transformation matrix. +%D \stopnarrower +%D +%D Well, what is the net effect? In matrix notation, it is +%D +%D \placeformula +%D \startformula +%D \pmatrix{I_x\cr I_y\cr 1\cr} = \pmatrix{a&c&e\cr +%D b&d&f\cr +%D 0&0&1\cr} +%D \pmatrix{U_x\cr +%D U_y\cr +%D 1 \cr} +%D \stopformula +%D +%D \placeformula +%D \startformula +%D \pmatrix{D_y\cr D_y\cr 1\cr} = \pmatrix{s_x&r_y&t_x\cr +%D r_x&s_y&t_y\cr +%D 0 &0 &1 \cr} +%D \pmatrix{I_x\cr +%D I_y\cr +%D 1 \cr} +%D \stopformula +%D +%D where $(I_x, I_y)$ is the intermediate coordinate. +%D +%D Now, the beauty of the matrix notation is that when there is +%D a chain of such matrix equations, one can always compose +%D them into one matrix equation using the standard matrix +%D composition law. The composite matrix from two matrices can +%D be derived very easily: the element in the $i$\high{th} +%D horizontal row and $j$\high{th} vertical column is +%D calculated by`multiplying' the $i$\high{th} row of the first +%D matrix and the $j$\high{th} column of the second matrix (and +%D summing over the elements). Thus, in the above: +%D +%D \placeformula +%D \startformula +%D \pmatrix{D_x\cr D_y\cr 1} = \pmatrix{s_x^\prime&r_y^\prime&t_x^\prime\cr +%D r_x^\prime&s_y^\prime&t_y^\prime\cr +%D 0 &0 &0 \cr} +%D \pmatrix{U_x\cr +%D U_y\cr +%D 1 \cr} +%D \stopformula +%D +%D with +%D +%D \placeformula +%D \startformula +%D \eqalign +%D {s_x^\prime & = s_x a + r_y b \cr +%D r_x^\prime & = r_x a + s_y b \cr +%D r_y^\prime & = s_x c + r_y d \cr +%D s_y^\prime & = r_x c + s_y d \cr +%D t_x^\prime & = s_x e + r_y f + t_x \cr +%D t_y^\prime & = r_x e + s_y f + t_y \cr} +%D \stopformula + +%D In fact, the same rule is true not only when one is going +%D from user coordinates to device coordinates, but whenever +%D one is composing two `transformations' together +%D (transformations are `associative'). Note that the formula +%D is not symmetric: you have to keep track of which +%D transformation existed before (i.e.\ the equivalent of +%D $[s_x\, r_x\, r_y\, s_y\, t_x\, t_y]$) and which was +%D specified later (i.e.\ the equivalent of $[a\, b\, c\, d\, +%D e\, f]$). Note also that the language can be rather +%D confusing: the one specified later `acts earlier', +%D converting the user space coordinates to intermediate +%D coordinates, which are then acted upon by the pre||existing +%D transformation. The important point is that order of +%D transformation matrices cannot be flipped (transformations +%D are not `commutative'). +%D +%D Now what does it mean to move a transformation matrix +%D before a drawing? What it means is that given a point +%D $(P_x, P_y)$ we need a different set of coordinates +%D $(P_x^\prime, P_y^\prime)$ such that if the transformation +%D acts on $(P_x^\prime, P_y^\prime)$, they produce $(P_x, +%D P_y)$. That is we need to solve the set of equations: +%D +%D \placeformula +%D \startformula +%D \pmatrix{P_x\cr P_y\cr 1\cr} = \pmatrix{s_x&r_y&t_x\cr +%D r_x&s_y&t_y\cr +%D 0 &0 &1 \cr} +%D \pmatrix{P_x^\prime\cr +%D P_y^\prime\cr +%D 1 \cr} +%D \stopformula +%D +%D Again matrix notation comes in handy (i.e. someone has +%D already solved the problem for us): we need the inverse +%D transformation matrix. The inverse transformation matrix can +%D be calculated very easily: +%D +%D \placeformula +%D \startformula +%D \pmatrix{P_x^\prime\cr P_y^\prime\cr 1\cr} = +%D \pmatrix{s_x^\prime&r_y^\prime&t_x^\prime\cr +%D r_x^\prime&s_y^\prime&t_y^\prime\cr +%D 0 &0 &1 \cr} +%D \pmatrix{P_x\cr +%D P_y\cr +%D 1 \cr} +%D \stopformula +%D +%D where, the inverse transformation matrix is given by +%D +%D \placeformula +%D \startformula +%D \eqalign +%D {D & = s_x s_y - r_x r_y \cr +%D s_x^\prime & = s_y / D \cr +%D s_y^\prime & = s_x / D \cr +%D r_x^\prime & = - r_x / D \cr +%D r_y^\prime & = - r_y / D \cr +%D t_x^\prime & = ( - s_y t_x + r_y t_y ) / D \cr +%D t_y^\prime & = ( r_x t_x - s_x t_y ) / D \cr} +%D \stopformula +%D +%D And you can see that when expanded out, this does +%D give the formulas: +%D +%D \placeformula +%D \startformula +%D P_x^\prime = { { s_y(p_x-t_x) + r_y(t_y-p_y) } \over +%D { s_x s_y-r_x r_y } } +%D \stopformula +%D +%D \placeformula +%D \startformula +%D P_y^\prime = { { s_x(p_y-t_y) + r_x(t_x-p_x) } \over +%D { s_x*s_y-r_x*r_y } } +%D \stopformula +%D +%D The code works by representing a real number by converting +%D it to a dimension to be put into a \DIMENSION\ register: 2.3 would +%D be represented as 2.3pt for example. In this scheme, +%D multiplying two numbers involves multiplying the \DIMENSION\ +%D registers and dividing by 65536. Accuracy demands that the +%D division be done as late as possible, but overflow +%D considerations need early division. +%D +%D Division involves dividing the two \DIMENSION\ registers and +%D multiplying the result by 65536. Again, accuracy would +%D demand that the numerator be multiplied (and|/|or the +%D denominator divided) early: but that can lead to overflow +%D which needs to be avoided. +%D +%D If nothing is known about the numbers to start with (in +%D concat), I have chosen to divide the 65536 as a 256 in each +%D operand. However, in the series calculating the sine and +%D cosine, I know that the terms are small (because I never +%D have an angle greater than 45 degrees), so I chose to +%D apportion the factor in a different way. + +%M \stop + +%D The path is output using the values saved on the stack. If +%D needed, all coordinates are recalculated. + +\def\finishMPpath + {\PDFcode{\ifcase\finiMPpath W n\or S\or f\or B\fi}} + +\def\processMPpath + {\checkMPpath + \ifcase\nofMPsegments\else + \flushMPpath + \closeMPpath + \finishMPpath + \fi + \let\handleMPsequence\dohandleMPsequence + \resetMPstack + \nofMPsegments\zerocount + \handleMPsequence} + +%D The following \METAPOST\ code is quite valid but, when +%D processed and converted to \PDF, will make a file +%D unprintable on a Hewlett Packard printer (from Acrobat +%D $v<=5$). Who is to blame, the driver of the OS layer in +%D between, is hard to determine, so we add an additional +%D check. +%D +%D \starttyping +%D clip currentpicture to origin -- cycle ; +%D setbounds currentpicture to fullsquare scaled 5cm ; +%D \stoptyping + +\def\checkMPpath + {\ifcase\finiMPpath + \ifnum\nofMPsegments<3 % n is one ahead + \message{omitting zero clip path}% + \nofMPsegments\zerocount + \fi + \fi} + +%D In \PDF\ the \type{cm} operator must precede the path +%D specification. We therefore can output the \type{cm} at +%D the moment we encounter it. + +\def\handleMPpathconcat + {\presetMPconcat + \PDFcode{\gMPs1 \gMPs2 \gMPs3 \gMPs4 \gMPs5 \gMPs6 cm}% + \resetMPstack} + +\def\handleMPpathscale + {\presetMPscale + \PDFcode{\gMPs1 0 0 \gMPs2 0 0 cm}% + \resetMPstack} + +%D This macro interprets the path and saves it as compact as +%D possible. + +\def\dohandleMPpath#1% + {\ifcase\lccode`#1\relax + \@EA\dohandleMPpathA + \else + \@EA\dohandleMPpathB + \fi#1} + +%\def\dohandleMPpathA#1 % +% {\setMPargument{#1}% +% \handleMPsequence} + +\let\dohandleMPpathA\setMPsequence + +\def\dohandleMPpathB#1 % + {\def\somestring{#1}% + \ifx\somestring\PSlineto + \setMPkeyword0 + \else\ifx\somestring\PScurveto + \setMPkeyword1 + \else\ifx\somestring\PSrlineto + \setMPkeyword2 + \else\ifx\somestring\PSmoveto + \setMPkeyword3 + \else\ifx\somestring\PSclip + % \chardef\finiMPpath0 % already + \let\handleMPsequence\processMPpath + \else\ifx\somestring\PSgsave + \chardef\finiMPpath3 + \else\ifx\somestring\PSgrestore + \else\ifx\somestring\PSfill + \ifcase\finiMPpath + \chardef\finiMPpath2 + \let\handleMPsequence\processMPpath + \fi + \else\ifx\somestring\PSstroke + \ifcase\finiMPpath + \chardef\finiMPpath1 + \fi + \let\handleMPsequence\processMPpath + \else\ifx\somestring\PSclosepath + \def\closeMPpath{\PDFcode{h}}% + \else\ifx\somestring\PSconcat + \let\flushMPpath\flushconcatMPpath + \handleMPpathconcat + \else\ifx\somestring\PSscale + \let\flushMPpath\flushconcatMPpath + \handleMPpathscale + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \handleMPsequence} + +%D The main conversion command is: +%D +%D \starttyping +%D \convertMPtoPDF {filename} {x scale} {y scale} +%D \stoptyping +%D +%D The dimensions are derived from the bounding box. So we +%D only have to say: +%D +%D \starttyping +%D \convertMPtoPDF{mp-pra-1.eps}{1}{1} +%D \convertMPtoPDF{mp-pra-1.eps}{.5}{.5} +%D \stoptyping + +%D \macros +%D {makeMPintoPDFobject,lastPDFMPobject} +%D +%D For experts there are a few more options. When attributes +%D are to be added, the code must be embedded in an object +%D accompanied with the appropriate directives. One can +%D influence this process with \type {\makeMPintoPDFobject}. +%D +%D This option defaults to~0, because \CONTEXT\ takes care +%D of objects at another level, which saves some bytes. +%D +%D \starttabulate[|l|l|p|] +%D \NC 0 \NC never \NC don't use an object \NC\NR +%D \NC 1 \NC always \NC always use an object \NC\NR +%D \NC 2 \NC optional \NC use object when needed \NC\NR +%D \stoptabulate +%D +%D The last object number used is avaliable in the macro +%D \type {\lastPDFMPobject}. + +\ifx\makeMPintoPDFobject\undefined \chardef\makeMPintoPDFobject=0 \fi + +\def\lastPDFMPobject{0} + +%D The additional code needed can be made available in the +%D (global) macro \type {\currentPDFresources}. + +\let\currentPDFresources\empty + +\newtoks\everyMPtoPDFconversion + +\def\convertMPtoPDF % #1#2#3% + {\bgroup + \ifx\pdfdecimaldigits\undefined\else \pdfdecimaldigits=5 \fi % new + \setbox\scratchbox\vbox\bgroup + \forgetall + \offinterlineskip + \startMPresources + \doprocessMPtoPDFfile} % + +%D The next one is kind of private and probably will become obsolete): + +\def\processMPtoPDFfile % file xscale yscale + {\bgroup + \let\finishMPgraphic\egroup + \doprocessMPtoPDFfile} + +\def\doprocessMPtoPDFfile#1#2#3% file xscale yscale + {% the following line is needed for latex where onepoint is not + % onepoint but a number (maxdimen); some day i'll make a latex + % variant of this file so that i no longer have to deal with such + % issues; then i'll also speed up this module using a few context + % tricks + % + \let\onepoint\onerealpoint + % + \setMPspecials + \the\everyMPtoPDFconversion + \catcode`\^^M=\@@endofline + \startMPscanning + \let\do\empty + \xdef\MPxscale{#2}% + \xdef\MPyscale{#3}% + \xdef\MPxoffset{0}% + \xdef\MPyoffset{0}% + \xdef\MPyshift{\zeropoint}% + \donefalse + \let\handleMPsequence\dohandleMPsequence + \message{[MP to PDF]}% was: [MP to PDF #1] but there is a (#1) anyway + \input#1\relax} + +% strange rounding/clip in pdftex/viewer +% +% \def\finishMPgraphic +% {\stopMPresources +% \egroup +% \ifx\pdftexversion\undefined\else\ifnum\pdftexversion<14 % for the moment +% \chardef\makeMPintoPDFobject=0 +% \fi\fi +% \ifcase\makeMPintoPDFobject\or\or\ifx\currentPDFresources\empty\else +% \chardef\makeMPintoPDFobject=1 +% \fi\fi +% \setbox\scratchbox=\vbox +% {\forgetall +% \hbox +% {\PDFcode{q \MPxscale\space 0 0 \MPyscale\space \MPxoffset\space \MPyoffset\space cm}% +% \lower\MPyshift\box\scratchbox % unscaled shift +% \PDFcode{Q}}}% +% \ht\scratchbox\MPheight +% \wd\scratchbox\MPwidth +% \dp\scratchbox\zeropoint +% \ifcase\makeMPintoPDFobject +% \box\scratchbox +% \or +% \immediate\pdfxform resources{\currentPDFresources}\scratchbox +% \xdef\lastPDFMPobject{\the\pdflastxform}% +% \pdfrefxform\lastPDFMPobject +% \global\let\currentPDFresources\empty +% \else +% \box\scratchbox +% \fi +% \egroup} +% +% funny clip in viewer +% +% \setbox\scratchbox=\vbox +% {\forgetall +% \dimen0=\MPllx bp +% \dimen2=\MPlly bp +% \setbox\scratchbox=\hbox{\hskip-\dimen0\raise-\dimen2\box\scratchbox}% +% \ht\scratchbox=\zeropoint +% \dp\scratchbox=\zeropoint +% \wd\scratchbox=\zeropoint +% \hbox +% {\PDFcode{q \MPxscale\space 0 0 \MPyscale\space 0 0 cm}% +% \lower\MPshift\box\scratchbox +% \PDFcode{Q}}}% + +% \let\PDFMPformoffset\zeropoint + +\def\PDFMPformoffset + {\ifx\objectoffset\undefined\zeropoint\else\objectoffset\fi} + +\def\finishMPgraphic + {\stopMPresources + \egroup + \setbox\scratchbox\vbox + {\forgetall + \hbox + {\PDFcode{q \MPxscale\space 0 0 \MPyscale\space \MPxoffset\space \MPyoffset\space cm}% + \lower\MPyshift\box\scratchbox % unscaled shift + \PDFcode{Q}}}% + \ht\scratchbox\MPheight + \wd\scratchbox\MPwidth + \dp\scratchbox\zeropoint\relax + \dopackageMPgraphic\scratchbox + \egroup + \endinput} + +%D Alternative for \PDFTEX. We cannot come up with something more contexy +%D because this module is also used in \LATEX. + +\def\dopackageMPgraphic#1% #1 = boxregister + {%\ifx\pdfxform\undefined + % \chardef\makeMPintoPDFobject\zerocount % no pdftex at all + %\else\ifx\pdftexversion\undefined + % \chardef\makeMPintoPDFobject\zerocount % no pdftex at all + %\else\ifnum\pdftexversion<14 + % \chardef\makeMPintoPDFobject\zerocount % no resource support + %\else + % % keep the default value + %\fi\fi\fi + \ifcase\makeMPintoPDFobject\or\or\ifx\currentPDFresources\empty\else + % an existing value of 2 signals object support (set elsewhere) + \chardef\makeMPintoPDFobject\plusone + \fi\fi + \ifcase\makeMPintoPDFobject + \box#1% + \or + \scratchdimen\PDFMPformoffset\relax + \ifdim\scratchdimen>\zeropoint % compensate for error + \setbox#1\vbox spread 2\scratchdimen + {\forgetall\vss\hbox spread 2\scratchdimen{\hss\box#1\hss}\vss}% + \fi + \setMPPDFobject{\currentPDFresources}{#1}% + \ifdim\scratchdimen>\zeropoint % compensate for error + \vbox to \MPheight + {\forgetall\vss\hbox to \MPwidth{\hss\getMPPDFobject\hss}\vss}% + \else + \getMPPDFobject + \fi + \global\let\currentPDFresources\empty + \else + \box#1% + \fi} + +\def\setMPPDFobject#1#2% resources boxnumber + {\ifx\pdfxform\undefined + \def\getMPPDFobject{\box#2}% + \else\ifx\pdftexversion\undefined + \def\getMPPDFobject{\box#2}% + \else\ifnum\pdftexversion<14 + \def\getMPPDFobject{\box#2}% + \else + \immediate\pdfxform resources{#1}#2% + \edef\getMPPDFobject{\noexpand\pdfrefxform\the\pdflastxform}% + \fi\fi\fi} + +\let\getMPPDFobject\relax + +%D \macros +%D {deleteMPgraphic, +%D startMPresources, +%D stopMPresources} +%D +%D Here are a few hooks for \CONTEXT\ specific things. + +\ifx\deleteMPgraphic\undefined + \def\deleteMPgraphic#1{} +\fi + +\ifx\startMPresources\undefined + \let\startMPresources\relax + \let\stopMPresources\relax +\fi + +%D \macros +%D {twodigitMPoutput} +%D +%D We can limit the precision to two digits after the comma +%D by saying: +%D +%D \starttyping +%D \twodigitMPoutput +%D \stoptyping +%D +%D This option only works in \CONTEXT\ combined with \ETEX. + +\def\twodigitMPoutput + {\let\!MP \twodigitrounding + \def\!MPgMPs##1{\twodigitrounding{\gMPs##1}}% + \def\!MPgMPa##1{\twodigitrounding{\gMPa##1}}} + +\let\!MP \empty +\let\!MPgMPa\gMPa +\let\!MPgMPs\gMPs + +%D This kind of conversion is possible because \METAPOST\ +%D does all the calculations. Converting other \POSTSCRIPT\ +%D files would drive both me and \TEX\ crazy. + +\ifx\undefined\StopLatexHack \else \StopLatexHack \fi + +\protect \endinput diff --git a/Master/texmf/doc/pdftex/manual/samplepdf/tmp.pdf b/Master/texmf/doc/pdftex/manual/samplepdf/tmp.pdf Binary files differnew file mode 100644 index 00000000000..3ce979ebf0c --- /dev/null +++ b/Master/texmf/doc/pdftex/manual/samplepdf/tmp.pdf |