mp-abck.mpxl /size: 10 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=mp-abck.mpiv,
3%D        version=2012.02.19, % was mp-core: 1999.08.01, anchoring
4%D          title=\CONTEXT\ \METAPOST\ graphics,
5%D       subtitle=anchored background macros,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14if known metafun_loaded_abck : endinput ; fi ;
15
16newinternal boolean metafun_loaded_abck ; metafun_loaded_abck := true ; immutable metafun_loaded_abck ;
17
18path    multiregs[],    % region used for multipar (tracing only)
19        multipars[],    % effective area (shape)
20        multibox ;      % main boundingbox (of main region)
21
22string  multikind[] ;   % region state: single | first | middle | last (new method)
23
24numeric multilocs[],    % 1=begin 2=between 3=end (old method)
25        nofmultipars ;  % number of calculated areas
26
27numeric par_strut_height,
28        par_strut_depth,
29        par_line_height ;
30
31nofmultipars     := 0 ;
32par_strut_height := 0 ;
33par_strut_depth  := 0 ;
34% par_line_height  := 0 ;
35
36pair    boxgriddirection ; boxgriddirection := up ;   % to be interfaced
37numeric boxgriddistance  ; boxgriddistance  := .5cm ; % to be interfaced
38
39def boxgridtype     = (runscript mfid_mpvarn "gridtype") enddef ;
40def boxgridwidth    = (runscript mfid_mpvard "gridwidth") enddef ;
41def boxgridshift    = (runscript mfid_mpvard "gridshift") enddef ;
42def boxgridcolor    = (runscript mfid_mpvars "gridcolor") enddef ;
43
44def boxlinetype     = (runscript mfid_mpvarn "linetype") enddef ;
45def boxlinewidth    = (runscript mfid_mpvard "linewidth") enddef ;
46def boxlineradius   = (runscript mfid_mpvard "lineradius") enddef ;
47def boxlineoffset   = (runscript mfid_mpvard "lineoffset") enddef ;
48def boxlinecolor    = (runscript mfid_mpvars "linecolor") enddef ;
49
50def boxfilltype     = (runscript mfid_mpvarn "filltype") enddef ;
51def boxfilloffset   = (runscript mfid_mpvard "filloffset") enddef ;
52def boxfillcolor    = (runscript mfid_mpvars "fillcolor") enddef ;
53
54def boxdashtype     = (runscript mfid_mpvarn "dashtype") enddef ;
55
56def boxalternative  = (runscript mfid_mpvarn "alternative") enddef;
57def boxdistance     = (runscript mfid_mpvard "distance") enddef;
58def boxlocation     = (runscript mfid_mpvarn "location") enddef ;
59def boxtopoffset    = (runscript mfid_mpvard "topoffset") enddef;
60def boxbottomoffset = (runscript mfid_mpvard "bottomoffset") enddef;
61
62vardef boxatright  =
63    save b ; b := boxlocation ;
64    if b = 1 :
65        false
66    elseif b = 2 :
67        true
68    elseif OnRightPage :
69        if b = 4 : % outer
70            true
71        else : % inner
72            false
73        fi
74    else :
75        if b = 4 : % inner
76            false
77        else : % inner
78            true
79        fi
80    fi
81enddef ;
82
83def boxgridoptions  = withcolor boxgridcolor enddef ;
84def boxlineoptions  = withcolor boxlinecolor enddef ;
85def boxfilloptions  = withcolor boxfillcolor enddef ;
86
87mutable
88    multipars, multiregs, multibox, multikind, multilocs, nofmultipars,
89    boxgridtype, boxgridwidth, boxgridshift, boxgridcolor,
90    boxlinetype, boxlinewidth, boxlineradius, boxlineoffset, boxlinecolor,
91    boxfilltype, boxfilloffset, boxfillcolor, boxdashtype,
92    boxalternative, boxdistance, boxtopoffset, boxbottomoffset,
93    boxgridoptions, boxlineoptions, boxfilloptions ;
94
95vardef abck_draw_path(expr p) =
96    if (length p > 2) and (bbwidth(p) > 1) and (bbheight(p) > 1) :
97        save pp ; path pp ;
98        pp := p if (boxlineradius>0) and (boxlinetype=2) : cornered boxlineradius fi ;
99        if boxfilltype > 0 :
100            if boxfilloffset > 0 :
101                interim linejoin := mitered ;
102                filldraw pp boxfilloptions withpen pencircle scaled (2*boxfilloffset) ;
103            else :
104                fill pp boxfilloptions ;
105            fi ;
106        fi ;
107        if boxlinetype > 0 :
108            draw pp boxlineoptions withpen pencircle scaled boxlinewidth ;
109        fi ;
110    fi ;
111enddef ;
112
113def abck_grid_line(expr start, width) =
114    % 1 = normal, 2 = with background (i.e. no shine-through)
115    if boxdashtype = 2 :
116        draw start -- start shifted (width,0)
117            withpen pencircle scaled boxgridwidth
118            boxfilloptions ;
119    fi ;
120    draw start -- start shifted (width,0)
121        if boxdashtype > 0 :
122            dashed evenly
123        fi
124        withpen pencircle scaled boxgridwidth
125        boxgridoptions ;
126enddef ;
127
128vardef abck_baseline_grid(expr pxy, pdir, at_baseline) =
129    save width ; width := bbwidth(pxy) ;
130    save height ; height := bbheight(pxy) ;
131    if (par_line_height > 0) and (height > 1) and (width > 1) and (boxgridwidth > 0) :
132        save i, grid, bb ; picture grid ; pair start ; path bb ;
133        grid := image ( % fails with inlinespace
134            if pdir = up :
135                for i = if at_baseline : par_strut_depth else : 0 fi step par_line_height until max(height,par_line_height) :
136                    abck_grid_line(llcorner pxy shifted (0,+i),width) ;
137                endfor ;
138            else :
139                for i = if at_baseline : par_strut_height else : 0 fi step par_line_height until height :
140                    abck_grid_line(ulcorner pxy shifted (0,-i),width) ;
141                endfor ;
142            fi ;
143        ) ;
144        clip grid to pxy ;
145        bb := boundingbox grid ;
146        grid := grid shifted (0,boxgridshift) ;
147        setbounds grid to bb ;
148        grid
149    else :
150        nullpicture
151    fi
152enddef ;
153
154vardef abck_graphic_grid(expr pxy, dx, dy, x, y) =
155    if (bbheight(pxy) > dy) and (bbwidth(pxy) > dx) and (boxgridwidth > 0) :
156        save grid ; picture grid ;
157        grid := image (
158            for i = xpart llcorner pxy step dx until xpart lrcorner pxy :
159                draw (i,ypart llcorner pxy) -- (i,ypart ulcorner pxy) withpen pencircle scaled boxgridwidth ;
160            endfor ;
161            for i = ypart llcorner pxy step dy until ypart ulcorner pxy :
162                draw (xpart llcorner pxy,i) -- (xpart lrcorner pxy,i) withpen pencircle scaled boxgridwidth ;
163            endfor
164        ) shifted (x,y) ;
165        clip grid to pxy ;
166        grid
167    else :
168        nullpicture
169    fi
170enddef ;
171
172def draw_multi_pars =
173    for i=1 upto nofmultipars :
174        abck_draw_path(multipars[i]) ;
175        if boxgridtype = 1 :
176            draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) ;
177        elseif boxgridtype = 2 :
178            draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,false) ;
179        elseif boxgridtype = 3 :
180            draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) ;
181            draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight) ;
182        elseif boxgridtype = 4 :
183            draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight/2) ;
184        elseif boxgridtype = 11 :
185            draw abck_graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ;
186        elseif boxgridtype = 12 :
187            draw abck_graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ;
188        fi ;
189    endfor ;
190enddef ;
191
192def show_multi_pars =
193    for i=1 upto nofmultipars :
194        drawpathwithpoints multipars[i] withcolor .5blue ;
195    endfor ;
196enddef ;
197
198def show_multi_kind =
199    for i=1 upto nofmultipars :
200        fill multipars[i]
201            withcolor
202                if      multikind[i] = "single" : yellow
203                elseif  multikind[i] = "first"  : red
204                elseif  multikind[i] = "middle" : green
205                elseif  multikind[i] = "last"   : blue
206                fi
207            withtransparency (1,.5)
208        ;
209    endfor ;
210enddef ;
211
212def multi_side_draw_options = enddef ;
213
214def draw_multi_side =
215    begingroup ; save p ; picture p ;
216    for i=1 upto nofmultipars :
217        p := image ( fill leftboundary multipars[i]
218            shifted (-boxlineoffset,0)
219            rightenlarged boxlinewidth boxlineoptions ;
220        ) ;
221        setbounds p to multipars[i] ;
222        draw p ;
223    endfor ;
224    endgroup ;
225enddef ;
226
227def draw_multi_side_path text t =
228    begingroup ; save p ; picture p ;
229    for i=1 upto nofmultipars :
230        p := image ( draw leftboundary multipars[i]
231            shifted (-boxlineoffset,0)
232            withpen pensquare scaled boxlinewidth boxlineoptions t ;
233        ) ;
234        setbounds p to multipars[i] ;
235        draw p ;
236    endfor ;
237    endgroup ;
238enddef ;
239
240% some extras
241
242% For the moment we keep these as they can be in use but they will disappear.
243
244pair    lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ;
245path    pxy[] ;
246numeric hxy[], wxy[], dxy[], nxy[] ;
247
248mutable lxy, rxy, cxy, llxy, lrxy, ulxy, urxy, pxy, hxy, wxy, dxy, nxy ;
249
250def box_found (expr n,x,y,w,h,d) =
251    not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0))
252enddef ;
253
254def initialize_box_pos (expr pos,n,x,y,w,h,d) =
255    pair lxy, rxy, cxy, llxy, lrxy, ulxy, urxy ;
256    path pxy ; numeric hxy, wxy, dxy, nxy;
257    lxy  := (x,y) ;
258    llxy := (x,y-d) ;
259    lrxy := (x+w,y-d) ;
260    urxy := (x+w,y+h) ;
261    ulxy := (x,y+h) ;
262    wxy  := w ;
263    hxy  := h ;
264    dxy  := d ;
265    rxy  := lxy shifted (wxy,0) ;
266    pxy  := llxy--lrxy--urxy--ulxy--cycle ;
267    cxy  := center pxy ;
268    nxy  := n ;
269    freeze_box(pos) ;
270enddef ;
271
272def freeze_box (expr pos) =
273    lxy[pos]  := lxy  ;
274    llxy[pos] := llxy ;
275    lrxy[pos] := lrxy ;
276    urxy[pos] := urxy ;
277    ulxy[pos] := ulxy ;
278    wxy[pos]  := wxy  ;
279    hxy[pos]  := hxy  ;
280    dxy[pos]  := dxy  ;
281    rxy[pos]  := rxy  ;
282    pxy[pos]  := pxy  ;
283    cxy[pos]  := cxy  ;
284    nxy[pos]  := nxy  ;
285enddef ;
286
287def initialize_box (expr n,x,y,w,h,d) =
288    numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ;
289enddef ;
290
291def anchor_box (expr n,x,y,w,h,d) =
292    currentpicture := currentpicture shifted (-x,-y) ;
293enddef ;
294
295def draw_box = % for old times sake
296    draw pxy        boxlineoptions withpen pencircle scaled boxlinewidth ;
297    draw lxy -- rxy boxlineoptions withpen pencircle scaled boxgridwidth ;
298enddef ;
299
300def draw_free_region(expr width, height, depth, loffset, roffset, toffset, boffset) =
301
302    begingroup ; save b, o, l ; path b, o, l[] ; save d ;
303
304    b := fullsquare
305        xysized(width,height+depth) ;
306    o := b
307        topenlarged    toffset
308        bottomenlarged boffset
309        leftenlarged   loffset
310        rightenlarged  roffset ;
311    d := max(PaperWidth,PaperHeight) ;
312
313    fill o withcolor .5white ;
314    fill b withcolor .7white ;
315
316    interim linecap := butt ;
317
318    l[1] := topboundary    (topboundary    o leftenlarged d rightenlarged  d) ;
319    l[2] := bottomboundary (bottomboundary o leftenlarged d rightenlarged  d) ;
320    l[3] := leftboundary   (leftboundary   o topenlarged  d bottomenlarged d) ;
321    l[4] := rightboundary  (rightboundary  o topenlarged  d bottomenlarged d) ;
322
323    for i=1 upto 4 :
324        draw l[i] withpen pencircle scaled 1bp withcolor white ;
325        draw l[i] withpen pencircle scaled 1bp dashed (evenly scaled 1bp) withcolor black ;
326    endfor ;
327
328    setbounds currentpicture to b ;
329
330    endgroup ;
331
332enddef ;
333
334