summaryrefslogtreecommitdiff
path: root/metapost/context/base/mpiv/mp-abck.mpiv
blob: abd7d8848ec3bb7dfd38a08f34cda1db77bc4cec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
%D \module
%D   [       file=mp-abck.mpiv,
%D        version=2012.02.19, % was mp-core: 1999.08.01, anchoring
%D          title=\CONTEXT\ \METAPOST\ graphics,
%D       subtitle=anchored background macros,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

if known context_abck : endinput ; fi ;

boolean context_abck ; context_abck := true ;

path    multiregs[],    % region used for multipar (tracing only)
        multipars[],    % effective area (shape)
        multibox ;      % main boundingbox (of main region)

string  multikind[] ;   % region state: single | first | middle | last (new method)

numeric multilocs[],    % 1=begin 2=between 3=end (old method)
        nofmultipars ;  % number of calculated areas

numeric par_strut_height,
        par_strut_depth,
        par_line_height ;

nofmultipars     := 0 ;
par_strut_height := 0 ;
par_strut_depth  := 0 ;
par_line_height  := 0 ;

def boxgridoptions = withcolor .8red   enddef ;
def boxlineoptions = withcolor .8blue  enddef ;
def boxfilloptions = withcolor .8white enddef ;

numeric boxgridtype      ; boxgridtype      := 0 ;
numeric boxlinetype      ; boxlinetype      := 1 ;
numeric boxfilltype      ; boxfilltype      := 1 ;
numeric boxdashtype      ; boxdashtype      := 0 ;
pair    boxgriddirection ; boxgriddirection := up ;
numeric boxgridwidth     ; boxgridwidth     := 1pt ;
numeric boxlinewidth     ; boxlinewidth     := 1pt ;
numeric boxlineradius    ; boxlineradius    := 0 ;
numeric boxlineoffset    ; boxlineoffset    := 0 ;
numeric boxfilloffset    ; boxfilloffset    := 0 ;
numeric boxgriddistance  ; boxgriddistance  := .5cm ;
numeric boxgridshift     ; boxgridshift     := 0 ;

def abck_show_path(expr p, r, c) =
    draw p withpen pencircle scaled .5pt withcolor c ;
    if length(p) > 2 :
        begingroup ; save _c_ ; path _c_ ; _c_ := fullcircle scaled r ;
        for i=0 upto length(p) if cycle p : -1 fi :
            fill _c_ shifted point i of p withcolor white ;
            draw _c_ shifted point i of p withpen pencircle scaled .5pt withcolor c ;
        endfor ;
    fi ;
enddef ;

vardef abck_draw_path(expr p) =
    if (length p > 2) and (bbwidth(p) > 1) and (bbheight(p) > 1) :
        save pp ; path pp ;
        pp := p if (boxlineradius>0) and (boxlinetype=2) : cornered boxlineradius fi ;
        if boxfilltype > 0 :
            if boxfilloffset > 0 :
                interim linejoin := mitered ;
                filldraw pp boxfilloptions withpen pencircle scaled (2*boxfilloffset) ;
            else :
                fill pp boxfilloptions ;
            fi ;
        fi ;
        if boxlinetype > 0 :
            draw pp boxlineoptions withpen pencircle scaled boxlinewidth ;
        fi ;
    fi ;
enddef ;

def abck_grid_line(expr start, width) =
    % 1 = normal, 2 = with background (i.e. no shine-through)
    if boxdashtype = 2 :
        draw start -- start shifted (width,0)
            withpen pencircle scaled boxgridwidth
            boxfilloptions ;
    fi ;
    draw start -- start shifted (width,0)
        if boxdashtype > 0 :
            dashed evenly
        fi
        withpen pencircle scaled boxgridwidth
        boxgridoptions ;
enddef ;

vardef abck_baseline_grid(expr pxy, pdir, at_baseline) =
    save width ; width := bbwidth(pxy) ;
    save height ; height := bbheight(pxy) ;
    if (par_line_height > 0) and (height > 1) and (width > 1) and (boxgridwidth > 0) :
        save i, grid, bb ; picture grid ; pair start ; path bb ;
        grid := image ( % fails with inlinespace
            if pdir = up :
                for i = if at_baseline : par_strut_depth else : 0 fi step par_line_height until max(height,par_line_height) :
                    abck_grid_line(llcorner pxy shifted (0,+i),width) ;
                endfor ;
            else :
                for i = if at_baseline : par_strut_height else : 0 fi step par_line_height until height :
                    abck_grid_line(ulcorner pxy shifted (0,-i),width) ;
                endfor ;
            fi ;
        ) ;
        clip grid to pxy ;
        bb := boundingbox grid ;
        grid := grid shifted (0,boxgridshift) ;
        setbounds grid to bb ;
        grid
    else :
        nullpicture
    fi
enddef ;

vardef abck_graphic_grid(expr pxy, dx, dy, x, y) =
    if (bbheight(pxy) > dy) and (bbwidth(pxy) > dx) and (boxgridwidth > 0) :
        save grid ; picture grid ;
        grid := image (
            for i = xpart llcorner pxy step dx until xpart lrcorner pxy :
                draw (i,ypart llcorner pxy) -- (i,ypart ulcorner pxy) withpen pencircle scaled boxgridwidth ;
            endfor ;
            for i = ypart llcorner pxy step dy until ypart ulcorner pxy :
                draw (xpart llcorner pxy,i) -- (xpart lrcorner pxy,i) withpen pencircle scaled boxgridwidth ;
            endfor
        ) shifted (x,y) ;
        clip grid to pxy ;
        grid
    else :
        nullpicture
    fi
enddef ;

def draw_multi_pars =
    for i=1 upto nofmultipars :
        abck_draw_path(multipars[i]) ;
        if boxgridtype = 1 :
            draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) ;
        elseif boxgridtype = 2 :
            draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,false) ;
        elseif boxgridtype = 3 :
            draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) ;
            draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight) ;
        elseif boxgridtype = 4 :
            draw abck_baseline_grid(multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight/2) ;
        elseif boxgridtype = 11 :
            draw abck_graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ;
        elseif boxgridtype = 12 :
            draw abck_graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ;
        fi ;
    endfor ;
enddef ;

def show_multi_pars =
    for i=1 upto nofmultipars :
        abck_show_path(multipars[i], 6pt, .5blue) ;
    endfor ;
enddef ;

def show_multi_kind =
    for i=1 upto nofmultipars :
        fill multipars[i]
            withcolor
                if      multikind[i] = "single" : yellow
                elseif  multikind[i] = "first"  : red
                elseif  multikind[i] = "middle" : green
                elseif  multikind[i] = "last"   : blue
                fi
            withtransparency (1,.5)
        ;
    endfor ;
enddef ;

def multi_side_draw_options = enddef ;

def draw_multi_side =
    begingroup ; save p ; picture p ;
    for i=1 upto nofmultipars :
        p := image ( fill leftboundary multipars[i]
            shifted (-boxlineoffset,0)
            rightenlarged boxlinewidth boxlineoptions ;
        ) ;
        setbounds p to multipars[i] ;
        draw p ;
    endfor ;
    endgroup ;
enddef ;

def draw_multi_side_path text t =
    begingroup ; save p ; picture p ;
    for i=1 upto nofmultipars :
        p := image ( draw leftboundary multipars[i]
            shifted (-boxlineoffset,0)
            withpen pensquare scaled boxlinewidth boxlineoptions t ;
        ) ;
        setbounds p to multipars[i] ;
        draw p ;
    endfor ;
    endgroup ;
enddef ;

% some extras

path    posboxes[],
        posregions[] ;

numeric multipages[],
        nofposboxes ;

nofposboxes := 0 ;

% For the moment we keep these as they can be in use but they will
% disappear.

pair    lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ;
path    pxy[] ;
numeric hxy[], wxy[], dxy[], nxy[] ;

def box_found (expr n,x,y,w,h,d) =
    not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0))
enddef ;

def initialize_box_pos (expr pos,n,x,y,w,h,d) =
    pair lxy, rxy, cxy, llxy, lrxy, ulxy, urxy ;
    path pxy ; numeric hxy, wxy, dxy, nxy;
    lxy  := (x,y) ;
    llxy := (x,y-d) ;
    lrxy := (x+w,y-d) ;
    urxy := (x+w,y+h) ;
    ulxy := (x,y+h) ;
    wxy  := w ;
    hxy  := h ;
    dxy  := d ;
    rxy  := lxy shifted (wxy,0) ;
    pxy  := llxy--lrxy--urxy--ulxy--cycle ;
    cxy  := center pxy ;
    nxy  := n ;
    freeze_box(pos) ;
enddef ;

def freeze_box (expr pos) =
    lxy[pos]  := lxy  ;
    llxy[pos] := llxy ;
    lrxy[pos] := lrxy ;
    urxy[pos] := urxy ;
    ulxy[pos] := ulxy ;
    wxy[pos]  := wxy  ;
    hxy[pos]  := hxy  ;
    dxy[pos]  := dxy  ;
    rxy[pos]  := rxy  ;
    pxy[pos]  := pxy  ;
    cxy[pos]  := cxy  ;
    nxy[pos]  := nxy  ;
enddef ;

def initialize_box (expr n,x,y,w,h,d) =
    numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ;
enddef ;

def anchor_box (expr n,x,y,w,h,d) =
    currentpicture := currentpicture shifted (-x,-y) ;
enddef ;