mp-abck.mpiv /size: 9721 b    last modification: 2020-07-01 14:35
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 context_abck : endinput ; fi ;
15
16boolean context_abck ; context_abck := true ;
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 ;
34par_line_height  := 0 ;
35
36def boxgridoptions = withcolor .8red   enddef ;
37def boxlineoptions = withcolor .8blue  enddef ;
38def boxfilloptions = withcolor .8white enddef ;
39
40numeric boxgridtype      ; boxgridtype      := 0 ;
41numeric boxlinetype      ; boxlinetype      := 1 ;
42numeric boxfilltype      ; boxfilltype      := 1 ;
43numeric boxdashtype      ; boxdashtype      := 0 ;
44pair    boxgriddirection ; boxgriddirection := up ;
45numeric boxgridwidth     ; boxgridwidth     := 1pt ;
46numeric boxlinewidth     ; boxlinewidth     := 1pt ;
47numeric boxlineradius    ; boxlineradius    := 0 ;
48numeric boxlineoffset    ; boxlineoffset    := 0 ;
49numeric boxfilloffset    ; boxfilloffset    := 0 ;
50numeric boxgriddistance  ; boxgriddistance  := .5cm ;
51numeric boxgridshift     ; boxgridshift     := 0 ;
52
53vardef abck_draw_path(expr p) =
54    if (length p > 2) and (bbwidth(p) > 1) and (bbheight(p) > 1) :
55        save pp ; path pp ;
56        pp := p if (boxlineradius>0) and (boxlinetype=2) : cornered boxlineradius fi ;
57        if boxfilltype > 0 :
58            if boxfilloffset > 0 :
59                interim linejoin := mitered ;
60                filldraw pp boxfilloptions withpen pencircle scaled (2*boxfilloffset) ;
61            else :
62                fill pp boxfilloptions ;
63            fi ;
64        fi ;
65        if boxlinetype > 0 :
66            draw pp boxlineoptions withpen pencircle scaled boxlinewidth ;
67        fi ;
68    fi ;
69enddef ;
70
71def abck_grid_line(expr start, width) =
72    % 1 = normal, 2 = with background (i.e. no shine-through)
73    if boxdashtype = 2 :
74        draw start -- start shifted (width,0)
75            withpen pencircle scaled boxgridwidth
76            boxfilloptions ;
77    fi ;
78    draw start -- start shifted (width,0)
79        if boxdashtype > 0 :
80            dashed evenly
81        fi
82        withpen pencircle scaled boxgridwidth
83        boxgridoptions ;
84enddef ;
85
86vardef abck_baseline_grid(expr pxy, pdir, at_baseline) =
87    save width ; width := bbwidth(pxy) ;
88    save height ; height := bbheight(pxy) ;
89    if (par_line_height > 0) and (height > 1) and (width > 1) and (boxgridwidth > 0) :
90        save i, grid, bb ; picture grid ; pair start ; path bb ;
91        grid := image ( % fails with inlinespace
92            if pdir = up :
93                for i = if at_baseline : par_strut_depth else : 0 fi step par_line_height until max(height,par_line_height) :
94                    abck_grid_line(llcorner pxy shifted (0,+i),width) ;
95                endfor ;
96            else :
97                for i = if at_baseline : par_strut_height else : 0 fi step par_line_height until height :
98                    abck_grid_line(ulcorner pxy shifted (0,-i),width) ;
99                endfor ;
100            fi ;
101        ) ;
102        clip grid to pxy ;
103        bb := boundingbox grid ;
104        grid := grid shifted (0,boxgridshift) ;
105        setbounds grid to bb ;
106        grid
107    else :
108        nullpicture
109    fi
110enddef ;
111
112vardef abck_graphic_grid(expr pxy, dx, dy, x, y) =
113    if (bbheight(pxy) > dy) and (bbwidth(pxy) > dx) and (boxgridwidth > 0) :
114        save grid ; picture grid ;
115        grid := image (
116            for i = xpart llcorner pxy step dx until xpart lrcorner pxy :
117                draw (i,ypart llcorner pxy) -- (i,ypart ulcorner pxy) withpen pencircle scaled boxgridwidth ;
118            endfor ;
119            for i = ypart llcorner pxy step dy until ypart ulcorner pxy :
120                draw (xpart llcorner pxy,i) -- (xpart lrcorner pxy,i) withpen pencircle scaled boxgridwidth ;
121            endfor
122        ) shifted (x,y) ;
123        clip grid to pxy ;
124        grid
125    else :
126        nullpicture
127    fi
128enddef ;
129
130def draw_multi_pars =
131    for i=1 upto nofmultipars :
132        abck_draw_path(multipars[i]) ;
133        if boxgridtype = 1 :
134            draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) ;
135        elseif boxgridtype = 2 :
136            draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,false) ;
137        elseif boxgridtype = 3 :
138            draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) ;
139            draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight) ;
140        elseif boxgridtype = 4 :
141            draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight/2) ;
142        elseif boxgridtype = 11 :
143            draw abck_graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ;
144        elseif boxgridtype = 12 :
145            draw abck_graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ;
146        fi ;
147    endfor ;
148enddef ;
149
150def show_multi_pars =
151    for i=1 upto nofmultipars :
152        drawpathwithpoints multipars[i] withcolor .5blue ;
153    endfor ;
154enddef ;
155
156def show_multi_kind =
157    for i=1 upto nofmultipars :
158        fill multipars[i]
159            withcolor
160                if      multikind[i] = "single" : yellow
161                elseif  multikind[i] = "first"  : red
162                elseif  multikind[i] = "middle" : green
163                elseif  multikind[i] = "last"   : blue
164                fi
165            withtransparency (1,.5)
166        ;
167    endfor ;
168enddef ;
169
170def multi_side_draw_options = enddef ;
171
172def draw_multi_side =
173    begingroup ; save p ; picture p ;
174    for i=1 upto nofmultipars :
175        p := image ( fill leftboundary multipars[i]
176            shifted (-boxlineoffset,0)
177            rightenlarged boxlinewidth boxlineoptions ;
178        ) ;
179        setbounds p to multipars[i] ;
180        draw p ;
181    endfor ;
182    endgroup ;
183enddef ;
184
185def draw_multi_side_path text t =
186    begingroup ; save p ; picture p ;
187    for i=1 upto nofmultipars :
188        p := image ( draw leftboundary multipars[i]
189            shifted (-boxlineoffset,0)
190            withpen pensquare scaled boxlinewidth boxlineoptions t ;
191        ) ;
192        setbounds p to multipars[i] ;
193        draw p ;
194    endfor ;
195    endgroup ;
196enddef ;
197
198% some extras
199
200path    posboxes[],
201        posregions[] ;
202
203numeric multipages[],
204        nofposboxes ;
205
206nofposboxes := 0 ;
207
208% For the moment we keep these as they can be in use but they will
209% disappear.
210
211pair    lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ;
212path    pxy[] ;
213numeric hxy[], wxy[], dxy[], nxy[] ;
214
215def box_found (expr n,x,y,w,h,d) =
216    not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0))
217enddef ;
218
219def initialize_box_pos (expr pos,n,x,y,w,h,d) =
220    pair lxy, rxy, cxy, llxy, lrxy, ulxy, urxy ;
221    path pxy ; numeric hxy, wxy, dxy, nxy;
222    lxy  := (x,y) ;
223    llxy := (x,y-d) ;
224    lrxy := (x+w,y-d) ;
225    urxy := (x+w,y+h) ;
226    ulxy := (x,y+h) ;
227    wxy  := w ;
228    hxy  := h ;
229    dxy  := d ;
230    rxy  := lxy shifted (wxy,0) ;
231    pxy  := llxy--lrxy--urxy--ulxy--cycle ;
232    cxy  := center pxy ;
233    nxy  := n ;
234    freeze_box(pos) ;
235enddef ;
236
237def freeze_box (expr pos) =
238    lxy[pos]  := lxy  ;
239    llxy[pos] := llxy ;
240    lrxy[pos] := lrxy ;
241    urxy[pos] := urxy ;
242    ulxy[pos] := ulxy ;
243    wxy[pos]  := wxy  ;
244    hxy[pos]  := hxy  ;
245    dxy[pos]  := dxy  ;
246    rxy[pos]  := rxy  ;
247    pxy[pos]  := pxy  ;
248    cxy[pos]  := cxy  ;
249    nxy[pos]  := nxy  ;
250enddef ;
251
252def initialize_box (expr n,x,y,w,h,d) =
253    numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ;
254enddef ;
255
256def anchor_box (expr n,x,y,w,h,d) =
257    currentpicture := currentpicture shifted (-x,-y) ;
258enddef ;
259
260def draw_box = % for old times sake
261    draw pxy        boxlineoptions withpen pencircle scaled boxlinewidth ;
262    draw lxy -- rxy boxlineoptions withpen pencircle scaled boxgridwidth ;
263enddef ;
264
265def draw_free_region(expr width, height, depth, loffset, roffset, toffset, boffset) =
266
267    begingroup ; save b, o, l ; path b, o, l[] ; save d ;
268
269    b := fullsquare
270        xysized(width,height+depth) ;
271    o := b
272        topenlarged    toffset
273        bottomenlarged boffset
274        leftenlarged   loffset
275        rightenlarged  roffset ;
276    d := max(PaperWidth,PaperHeight) ;
277
278    fill o withcolor .5white ;
279    fill b withcolor .7white ;
280
281    interim linecap := butt ;
282
283    l[1] := topboundary    (topboundary    o leftenlarged d rightenlarged  d) ;
284    l[2] := bottomboundary (bottomboundary o leftenlarged d rightenlarged  d) ;
285    l[3] := leftboundary   (leftboundary   o topenlarged  d bottomenlarged d) ;
286    l[4] := rightboundary  (rightboundary  o topenlarged  d bottomenlarged d) ;
287
288    for i=1 upto 4 :
289        draw l[i] withpen pencircle scaled 1bp withcolor white ;
290        draw l[i] withpen pencircle scaled 1bp dashed (evenly scaled 1bp) withcolor black ;
291    endfor ;
292
293    setbounds currentpicture to b ;
294
295    endgroup ;
296
297enddef ;
298
299