summaryrefslogtreecommitdiff
path: root/macros/luatex/optex/graphics.opm
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/optex/graphics.opm')
-rw-r--r--macros/luatex/optex/graphics.opm249
1 files changed, 242 insertions, 7 deletions
diff --git a/macros/luatex/optex/graphics.opm b/macros/luatex/optex/graphics.opm
index d4a868a3d1..92a1a7a804 100644
--- a/macros/luatex/optex/graphics.opm
+++ b/macros/luatex/optex/graphics.opm
@@ -1,13 +1,13 @@
%% This is part of OpTeX project, see http://petr.olsak.net/optex
-\_codedecl \inspic {Graphics <2020-03-18>} % preloaded in format
+\_codedecl \inspic {Graphics <2020-03-29>} % preloaded in format
\_doc -----------------------------
`\inspic` accepts old syntax `\inspic <filename><space>`
or new syntax `\inspic{<filename>}`. So, we need to define
two auxiliary macros `\_inspicA` and `\_inspicB`.
- You can include more `\pdfximage` parameters (like `page=`)
+ You can include more `\pdfximage` parameters (like `page<number>`)
in the `\_picparams` macro.
All `\inspic` macros are surrounded in `\hbox` in order user can
@@ -146,11 +146,11 @@
The `\_scantwodimens` scans two objects with the syntactic rule <dimen>
and returns `{<number>}{<number>}` in sp unit.
- The `\puttext <down> <right>{<text>}` puts the <text> to desired place:
+ The `\puttext <right> <up>{<text>}` puts the <text> to desired place:
From current point moves <down> and <right>, puts the <text> and returns
back. The cuuren tpoint is unchanged after this macro ends.
- The `\putpic <down> <right> <width> <height> {<image-file>}`
+ The `\putpic <right> <up> <width> <height> {<image-file>}`
does `\puttext` with the image scaled to desired <width> and <height>.
If <with> or <height> is zero, natural dimension is used.
The `\nospec` is a shortcut to such natural dimension.
@@ -158,18 +158,18 @@
\_def\_scantwodimens{%
\_directlua{tex.print(string.format('{\_pcent d}{\_pcent d}',
- token.scan_dimen(),token.scan_dimen{}))}%
+ token.scan_dimen(),token.scan_dimen()))}%
}
\_def\_puttext{\_ea\_ea\_ea\_puttextA\_scantwodimens}
\_def\_puttextA#1#2#3{\_setbox0=\_hbox{{#3}}\_dimen1=#1sp \_dimen2=#2sp \_puttextB}
\_def\_puttextB{%
- \_ifvmode
+ \_ifvmode
\_ifdim\_prevdepth>0pt \_vskip-\_prevdepth \_relax \_fi
\_nointerlineskip
\_fi
\_wd0=0pt \_ht0=0pt \_dp0=0pt
- \_vbox to0pt{\_kern\_dimen1 \_hbox to0pt{\_kern\_dimen2 \_box0\_hss}\_vss}}
+ \_vbox to0pt{\_kern-\_dimen2 \_hbox to0pt{\_kern\_dimen1 \_box0\_hss}\_vss}}
\_def\_putpic{\_ea\_ea\_ea\_putpicA\_scantwodimens}
\_def\_putpicA#1#2{\_dimen1=#1sp \_dimen2=#2sp \_ea\_ea\_ea\_putpicB\_scantwodimens}
@@ -183,5 +183,240 @@
\_def\nospec{0pt}
\_public \puttext \putpic \backgroundpic ;
+ \_doc -----------------------------
+ You can use expandable `\_bp{<dimen>}` convertor from
+ \TeX/ `<dimen>` (or from an expression accepted by
+ `\dimexpr` primitive) to a decimal value in big points
+ (used as natural unit in the PDF format). So, you can write, for example:
+ \begtt
+ \pdfliteral{q \_bp{.3\hsize-2mm} \_bp{2mm} m 0 \_bp{-4mm} l S Q}
+ \endtt
+ You can use expandable `\_expr{<expression>}` for analogical purposes.
+ The `<expression>` can include `+-*/()` and decimal numbers in common syntax.
+ \_cod -----------------------------
+
+\_def\_decdigits{3} % digits after decimal point in \_bp and \_expr outputs.
+\_def\_pttopb{%
+ \_directlua{tex.print(string.format('\_pcent.\_decdigits f',
+ token.scan_dimen()/65781.76))}% pt to bp conversion
+}
+\def\_bp#1{\_ea\_pttopb\_dimexpr#1\_relax}
+\def\_expr#1{\_directlua{tex.print(string.format('\_pcent.\_decdigits f',#1))}}
+
+ \_doc -----------------------------
+ `\)circle<x><y>` creates an ellipse with `<x>` axis and `<y>` axix.
+ The origin is in the center.
+ `\_oval<x><y><roudness>` creates an oval with `<x>`, `<y>` size and with
+ given `<roundness>`. The real size is bigger by 2`<roundness>`. The
+ orgigin is at the left bottom corner.
+ `\_mv<x><y>{<curve>}` moves current point to `<x>`, `<y>`, crates the
+ `<curve>` and retuns back the current point.
+ All these macros are fully expandable and they can be used in the
+ `\pdfliteral` argument.
+ \_cod -----------------------------
+
+\def\_circle#1#2{\_expr{.5*(#1)} 0 m
+ \_expr{.5*(#1)} \_expr{.276*(#2)} \_expr{.276*(#1)} \_expr{.5*(#2)} 0 \_expr{.5*(#2)} c
+ \_expr{-.276*(#1)} \_expr{.5*(#2)} \_expr{-.5*(#1)} \_expr{.276*(#2)} \_expr{-.5*(#1)} 0 c
+ \_expr{-.5*(#1)} \_expr{-.276*(#2)} \_expr{-.276*(#1)} \_expr{-.5*(#2)} 0 \_expr{-.5*(#2)} c
+ \_expr{.276*(#1)} \_expr{-.5*(#2)} \_expr{.5*(#1)} \_expr{-.276*(#2)} \_expr{.5*(#1)} 0 c h}
+
+\def\_oval#1#2#3{0 \_expr{-(#3)} m \_expr{#1} \_expr{-(#3)} l
+ \_expr{(#1)+.552*(#3)} \_expr{-(#3)} \_expr{(#1)+(#3)} \_expr{-.552*(#3)}
+ \_expr{(#1)+(#3)} 0 c
+ \_expr{(#1)+(#3)} \_expr{#2} l
+ \_expr{(#1)+(#3)} \_expr{(#2)+.552*(#3)} \_expr{(#1)+.552*(#3)} \_expr{(#2)+(#3)}
+ \_expr{#1} \_expr{(#2)+(#3)} c
+ 0 \_expr{(#2)+(#3)} l
+ \_expr{-.552*(#3)} \_expr{(#2)+(#3)} \_expr{-(#3)} \_expr{(#2)+.552*(#3)}
+ \_expr{-(#3)} \_expr{#2} c
+ \_expr{-(#3)} 0 l
+ \_expr{-(#3)} \_expr{-.552*(#3)} \_expr{-.552*(#3)} \_expr{-(#3)} 0 \_expr{-(#3)} c h}
+
+\def\_mv#1#2#3{1 0 0 1 \_expr{#1} \_expr{#2} cm #3 1 0 0 1 \_expr{-(#1)} \_expr{-(#2)} cm}
+
+ \_doc -----------------------------
+ The `\inoval` is an example of `\_oval` usage.
+ The `\incircle` is an example of `\_circle` usage.
+ \_cod -----------------------------
+
+\_newdimen \_lwidth
+\_def\_fcolor{\_let\_fcolorvalue}
+\_def\_lcolor{\_let\_lcolorvalue}
+\_def\_shadow{\_let\_shadowvalue}
+\_def\_overlapmargins{\_let\_overlapmarginsvalue}
+\_def\_ratio{\isnextchar ={\_ratioA}{\_ratioA=}}
+\_def\_ratioA =#1 {\_def\_ratiovalue{#1}}
+\_def\_touppervalue#1{\_ifx#1n\_let#1=N\_fi}
+
+\_def\_setflcolors#1{% use only in a group
+ \_def\_setcolor##1{##1}%
+ \_def\_fillstroke##1##2{##1}%
+ \_edef#1{\_fcolorvalue}%
+ \_def\_fillstroke##1##2{##2}%
+ \_edef#1{#1\_space\_lcolorvalue\_space}%
+}
+
+\_optdef\_inoval[]{\_vbox\_bgroup
+ \_roundness=2pt \_fcolor=\Yellow \_lcolor=\Red \_lwidth=.5bp
+ \_shadow=N \_overlapmargins=N \_hhkern=0pt \_vvkern=0pt
+ \_the\_ovalparams \_relax \_the\_opt \_relax
+ \_touppervalue\_overlapmarginsvalue \_touppervalue\_shadowvalue
+ \_ifx\_overlapmarginsvalue N%
+ \_advance\_hsize by-2\_hhkern \_advance\_hsize by-2\_roundness \_fi
+ \_setbox0=\_hbox\_bgroup\_bgroup \_aftergroup\_inovalA \_kern\_hhkern \_let\_next=%
+}
+\_def\_inovalA{\_isnextchar\_colorstackpop\_inovalB\_inovalC}
+\_def\_inovalB#1{#1\_isnextchar\_colorstackpop\_inovalB\_inovalC}
+\_def\_inovalC{\_egroup % of \setbox0=\hbox\bgroup
+ \_ifdim\_vvkern=0pt \_else \_ht0=\_dimexpr\_ht0+\_vvkern \_relax
+ \_dp0=\_dimexpr\_dp0+\_vvkern \_relax \_fi
+ \_ifdim\_hhkern=0pt \_else \_wd0=\_dimexpr\_wd0+\_hhkern \_relax \_fi
+ \_ifx\_overlapmarginsvalue N\_dimen0=\_roundness \_dimen1=\_roundness
+ \_else \_dimen0=-\_hhkern \_dimen1=-\_vvkern \_fi
+ \_setflcolors\_tmp
+ \_hbox{\_kern\_dimen0
+ \_vbox to0pt{\_kern\_dp0
+ \_ifx\_shadowvalue N\_else
+ \_edef\_tmpb{{\_bp{\_wd0+\_lwidth}}{\_bp{\_ht0+\_dp0+\_lwidth}}{\_bp{\_roundness}}}%
+ \_doshadow\_oval
+ \_fi
+ \_pdfliteral{q \_bp{\_lwidth} w \_tmp
+ \_oval{\_bp{\wd0}}{\_bp{\_ht0+\_dp0}}{\_bp{\_roundness}} B Q}\_vss}%
+ \_ht0=\_dimexpr\_ht0+\_dimen1 \_relax \_dp0=\_dimexpr\_dp0+\_dimen1 \_relax
+ \_box0
+ \_kern\_dimen0}%
+ \_egroup % of \vbox\bgroup
+}
+\_optdef\_incircle[]{\_vbox\_bgroup
+ \_ratio=1 \_fcolor=\Yellow \_lcolor=\Red \_lwidth=.5bp
+ \_shadow=N \_overlapmargins=N \_hhkern=3pt \_vvkern=3pt
+ \_ea\_the \_ea\_circleparams \_space \_relax
+ \_ea\_the \_ea\_opt \_space \_relax
+ \_touppervalue\_overlapmarginsvalue \_touppervalue\_shadowvalue
+ \_setbox0=\_hbox\_bgroup\_bgroup \_aftergroup\_incircleA \_kern\_hhkern \_let\_next=%
+}
+\_def\_incircleA {\_isnextchar\_colorstackpop\_incircleB\_incircleC}
+\_def\_incircleB #1{#1\_isnextchar\_colorstackpop\_incircleB\_incircleC}
+\_def\_incircleC {\_egroup % of \setbox0=\hbox\bgroup
+ \_wd0=\dimexpr \_wd0+\_hhkern \_relax
+ \_ht0=\dimexpr \_ht0+\_vvkern \_relax \_dp0=\dimexpr \_dp0+\_vvkern \_relax
+ \_ifdim \_ratiovalue\_dimexpr \_ht0+\_dp0 > \_wd0
+ \_dimen3=\_dimexpr \_ht0+\_dp0 \_relax \_dimen2=\_ratiovalue\_dimen3
+ \_else \_dimen2=\_wd0 \_dimen3=\_expr{1/\_ratiovalue}\_dimen2 \fi
+ \_setflcolors\_tmp
+ \_ifx\_overlapmarginsvalue N\_dimen0=0pt \_dimen1=0pt
+ \_else \_dimen0=-\hhkern \_dimen1=-\vvkern \_fi
+ \_hbox{\_kern\dimen0
+ \_ifx\_shadowvalue N\_else
+ \_edef\_tmpb{{\_bp{\_dimen2+\_lwidth}}{\_bp{\_dimen3+\_lwidth}}{}}%
+ \_doshadow\_circlet
+ \_fi
+ \_pdfliteral{q \_bp{\_lwidth} w \_tmp \_mv{\_bp{.5\_wd0}}{\_bp{(\ht0-\dp0)/2}}
+ {\_circle{\_bp{\_dimen2}}{\_bp{\_dimen3}} B} Q}%
+ \_ifdim\_dimen1=0pt \_else
+ \_ht0=\dimexpr \_ht0+\_dimen1 \_relax \_dp0=\dimexpr \_dp0+\_dimen1 \_relax \_fi
+ \_box0
+ \_kern\_dimen0}
+ \_egroup % of \vbox\bgroup
+}
+\_def\_circlet#1#2#3{\_circle{#1}{#2}}
+
+\_public
+ \inoval \incircle \ratio \lwidth \fcolor \lcolor \shadow \overlapmargins ;
+
+ \_doc -----------------------------
+ A shadow effect is implemented here. The shadow is equal to the
+ silhouette of the given path in gray-transparent color shifted by
+ `\shadowmoveto` vector and with blurred boundary.
+ A waistline with the width 2*`\shadowb` around the boundary is blurred.
+ The `\shadowlevels` levels of transparent shapes is used for creating
+ this effect. The `\shadowlevels+1/2` level is equal to the shifted given path.
+ \_cod -----------------------------
+
+\_def\_shadowlevels{9} % number of layers for blurr effect
+\_def\_shadowdarknessA{0.025} % transparency of first shadowlevels/2 layers
+\_def\_shadowdarknessB{0.07} % transparency of second half of layers
+\_def\_shadowmoveto{1.8 -2.5} % vector defines shifting layer (in bp)
+\_def\_shadowb{1} % 2*shadowb = blurring area thickness
+
+ \_doc -----------------------------
+ The `\_pdfpageresources` primitive is used to define transparency.
+ It does not work when used in a box. So, we use it at begining of
+ output routine. The modification of output routine is done only once
+ when the shadow effect is used first.
+ \_cod -----------------------------
+
+\_def\_insertshadowresources{%
+ \_global\_addto\_begoutput{\_setshadowresources}%
+ \_xdef\_setshadowresources{%
+ \_pdfpageresources{/ExtGState
+ <<
+ /op1 << /Type /ExtGState /ca \_shadowdarknessA >>
+ /op2 << /Type /ExtGState /ca \_shadowdarknessB >>
+ >>
+ }%
+ }%
+ \_global\_let\_insertshadowresources=\_relax
+}
+\_def\_doshadow#1{\_vbox{%
+ \_insertshadowresources
+ \_tmpnum=\_numexpr (\_shadowlevels-1)/2 \_relax
+ \_edef\_tmpfin{\_the\_tmpnum}%
+ \_ifnum\_tmpfin=0 \_def\_shadowb{0}\_def\_shadowstep{0}%
+ \_else \_edef\_shadowstep{\_expr{\_shadowb/\_tmpfin}}\_fi
+ \_def\_tmpa##1##2##3{\_def\_tmpb
+ {#1{##1+2*\_the\_tmpnum*\_shadowstep}{##2+2*\_the\_tmpnum*\_shadowstep}{##3}}}%
+ \_ea \_tmpa \_tmpb
+ \_def\_shadowlayer{%
+ \_ifnum\_tmpnum=0 /op2 gs \_fi
+ \_tmpb\_space f
+ \_immediateassignment\_advance\_tmpnum by-1
+ \_ifnum-\_tmpfin<\_tmpnum
+ \_ifx#1\_oval 1 0 0 1 \_shadowstep\_space \_shadowstep\_space cm \_fi
+ \_ea \_shadowlayer \_fi
+ }%
+ \_pdfliteral{q /op1 gs 0 g 1 0 0 1 \_shadowmoveto\_space cm
+ \_ifx#1\_circlet 1 0 0 1 \_expr{\_bp{.5\_wd0}} \_expr{\_bp{(\_ht0-\_dp0)/2}} cm
+ \_else 1 0 0 1 -\_shadowb\_space -\_shadowb\_space cm \_fi
+ \_shadowlayer Q}
+}}
+
+ \_doc -----------------------------
+ A generic macro `\clipinpath{<x>}{<y>}{<curve>}{<text>}` declares
+ a clipping path by <curve> shifted by <x>, <y>. The <text> is typesset
+ when such clipping path is active. Dimensions are given by bp without the unit here.
+ Macros `\clipinoval <x> <y> <width> <height> {<text>}` and
+ `\clipincircle <x> <y> <width> <height> {<text>}` are defined here.
+ These marcos read normal \TeX/ dimensions in their parameters.
+ \_cod -----------------------------
+
+\_def\_clipinpath#1#2#3#4{% #1=x-pos[bp], #2=y-pos[bp], #3=curve, #4=text
+ \_hbox{\setbox0=\hbox{{#4}}%
+ \_tmpdim=\wd0 \wd0=0pt
+ \_pdfliteral{q \_mv{#1}{#2}{#3 W n}}%
+ \_box0\_pdfliteral{Q}\_kern\_tmpdim
+ }%
+}
+
+\_def\_clipinoval {\_ea\_ea\_ea\_clipinovalA\_scantwodimens}
+\_def\_clipinovalA #1#2{%
+ \_def\_tmp{{#1/65781.76}{#2/65781.76}}%
+ \_ea\_ea\_ea\_clipinovalB\_scantwodimens
+}
+\_def\_clipinovalB{\_ea\_clipinovalC\_tmp}
+\_def\_clipinovalC#1#2#3#4{%
+ \_ea\_clipinpath{#1-(#3/131563.52)+(\_bp{\_roundness})}{#2-(#4/131563.52)+(\_bp{\_roundness})}%
+ {\_oval{#3/65781.76-(\_bp{2\_roundness})}{#4/65781.76-(\_bp{2\_roundness})}{\_bp{\_roundness}}}%
+}
+\_def\_clipincircle {\_ea\_ea\_ea\_clipincircleA\_scantwodimens}
+\_def\_clipincircleA #1#2{%
+ \_def\_tmp{{#1/65781.76}{#2/65781.76}}%
+ \_ea\_ea\_ea\_clipincircleB\_scantwodimens
+}
+\_def\_clipincircleB#1#2{%
+ \_ea\_clipinpath\_tmp{\_circle{#1/65781.76}{#2/65781.76}}%
+}
+
\_endcode % -------------------------------------