mp-core.mpiv /size: 56 Kb    last modification: 2020-07-01 14:35
1
%D \module
2
%D [ file=mp-core.mpiv,
3
%D version=1999.08.01, % anchoring
4
%D title=\CONTEXT\ \METAPOST\ graphics,
5
%D subtitle=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 14
if
known
context_core
:
endinput
;
fi
;
15 16
boolean
context_core
;
context_core
:
=
true
;
17 18
%D Copied to here .. not used any more.
19 20
if
unknown
NOfTextColumns
:
numeric
NOfTextColumns
;
NOfTextColumns
:
=
1
;
fi
;
21
if
unknown
NOfTextAreas
:
numeric
NOfTextAreas
;
NOfTextAreas
:
=
1
;
fi
;
22 23
def
SaveTextAreas
=
24
path
SavedTextAreas
[
]
;
25
path
SavedTextColumns
[
]
;
26
numeric
NOfSavedTextAreas
;
27
numeric
NOfSavedTextColumns
;
28
for
i
=
1
upto
NOfTextAreas
:
29
SavedTextAreas
[
i
]
:
=
TextAreas
[
i
]
;
30
endfor
;
31
for
i
=
1
upto
NOfTextColumns
:
32
SavedTextColumns
[
i
]
:
=
TextColumns
[
i
]
;
33
endfor
;
34
NOfSavedTextAreas
:
=
NOfTextAreas
;
35
NOfSavedTextColumns
:
=
NOfTextColumns
;
36
enddef
;
37 38
def
ResetTextAreas
=
39
path
TextAreas
[
]
,
TextColumns
[
]
,
PlainTextArea
,
RegionTextArea
;
40
numeric
NOfTextAreas
;
NOfTextAreas
:
=
0
;
41
numeric
NOfTextColumns
;
NOfTextColumns
:
=
0
;
42
numeric
nofmultipars
;
nofmultipars
:
=
0
;
43
TextAreas
[
0
]
:
=
TextColumns
[
0
]
:
=
origin
--
cycle
;
44
enddef
;
45 46
ResetTextAreas
;
SaveTextAreas
;
;
47 48
def
RegisterTextArea
(
expr
x
,
y
,
w
,
h
,
d
)
=
49
begingroup
;
50
save
p
;
path
p
;
51
p
:
=
unitsquare
xyscaled
(
w
,
h
+
d
)
shifted
(
x
,
y
-
d
)
;
52
if
NOfTextAreas
>
0
:
53
% if needed, concatenate areas
54
if
(
round
(
llcorner
TextAreas
[
NOfTextAreas
]
)
=
round
(
ulcorner
p
)
)
and
55
(
round
(
lrcorner
TextAreas
[
NOfTextAreas
]
)
=
round
(
urcorner
p
)
)
:
56
p
:
=
57
ulcorner
TextAreas
[
NOfTextAreas
]
--
58
urcorner
TextAreas
[
NOfTextAreas
]
--
59
lrcorner
p
--
60
llcorner
p
--
cycle
;
61
else
:
62
NOfTextAreas
:
=
NOfTextAreas
+
1
;
63
fi
;
64
else
:
65
NOfTextAreas
:
=
NOfTextAreas
+
1
;
66
fi
;
67
TextAreas
[
NOfTextAreas
]
:
=
p
;
68
if
NOfTextColumns
>
0
:
69
if
(
round
(
xpart
llcorner
TextColumns
[
NOfTextColumns
]
)
=
round
(
xpart
ulcorner
p
)
)
and
70
(
round
(
xpart
lrcorner
TextColumns
[
NOfTextColumns
]
)
=
round
(
xpart
urcorner
p
)
)
:
71
p
:
=
72
ulcorner
TextColumns
[
NOfTextColumns
]
--
73
urcorner
TextColumns
[
NOfTextColumns
]
--
74
lrcorner
p
--
75
llcorner
p
--
cycle
;
76
else
:
77
NOfTextColumns
:
=
NOfTextColumns
+
1
;
78
fi
;
79
else
:
80
NOfTextColumns
:
=
NOfTextColumns
+
1
;
81
fi
;
82
TextColumns
[
NOfTextColumns
]
:
=
p
;
83
endgroup
;
84
enddef
;
85 86
%D We store a local area in slot zero.
87 88
def
RegisterPlainTextArea
(
expr
x
,
y
,
w
,
h
,
d
)
=
89
PlainTextArea
:
=
unitsquare
xyscaled
(
w
,
h
+
d
)
shifted
(
x
,
y
-
d
)
;
90
enddef
;
91 92
def
RegisterRegionTextArea
(
expr
x
,
y
,
w
,
h
,
d
)
=
93
RegionTextArea
:
=
unitsquare
xyscaled
(
w
,
h
+
d
)
shifted
(
x
,
y
-
d
)
;
94
% RegionTextArea := RegionTextArea enlarged 2mm ;
95
enddef
;
96 97
def
RegisterLocalTextArea
(
expr
x
,
y
,
w
,
h
,
d
)
=
98
TextAreas
[
0
]
:
=
TextColumns
[
0
]
:
=
unitsquare
xyscaled
(
w
,
h
+
d
)
shifted
(
x
,
y
-
d
)
;
99
enddef
;
100 101
def
ResetLocalTextArea
=
102
TextAreas
[
0
]
:
=
TextColumns
[
0
]
:
=
origin
--
cycle
;
103
enddef
;
104 105
ResetLocalTextArea
;
106 107
vardef
InsideTextArea
(
expr
_i_
,
_xy_
)
=
108
(
round
(
xpart
_xy_
)
>
=
round
(
xpart
llcorner
TextAreas
[
_i_
]
)
)
and
109
(
round
(
xpart
_xy_
)
<
=
round
(
xpart
lrcorner
TextAreas
[
_i_
]
)
)
and
110
(
round
(
ypart
_xy_
)
>
=
round
(
ypart
llcorner
TextAreas
[
_i_
]
)
)
and
111
(
round
(
ypart
_xy_
)
<
=
round
(
ypart
urcorner
TextAreas
[
_i_
]
)
)
112
enddef
;
113 114
vardef
InsideSavedTextArea
(
expr
_i_
,
_xy_
)
=
115
(
round
(
xpart
_xy_
)
>
=
round
(
xpart
llcorner
SavedTextAreas
[
_i_
]
)
)
and
116
(
round
(
xpart
_xy_
)
<
=
round
(
xpart
lrcorner
SavedTextAreas
[
_i_
]
)
)
and
117
(
round
(
ypart
_xy_
)
>
=
round
(
ypart
llcorner
SavedTextAreas
[
_i_
]
)
)
and
118
(
round
(
ypart
_xy_
)
<
=
round
(
ypart
urcorner
SavedTextAreas
[
_i_
]
)
)
119
enddef
;
120 121
vardef
InsideSomeTextArea
(
expr
_xy_
)
=
122
save
ok
;
boolean
ok
;
ok
:
=
false
;
123
for
i
:
=
1
upto
NOfTextAreas
:
124
if
InsideTextArea
(
i
,
_xy_
)
:
125
ok
:
=
true
;
% we can move the exit here
126
fi
;
127
exitif
ok
;
128
endfor
;
129
ok
130
enddef
;
131 132
vardef
InsideSomeSavedTextArea
(
expr
_xy_
)
=
133
save
ok
;
boolean
ok
;
ok
:
=
false
;
134
for
i
:
=
1
upto
NOfSavedTextAreas
:
135
if
InsideSavedTextArea
(
i
,
_xy_
)
:
136
ok
:
=
true
;
137
fi
;
138
exitif
ok
;
139
endfor
;
140
ok
141
enddef
;
142 143
vardef
TextAreaX
(
expr
x
)
=
144
numeric
_TextAreaX_
;
_TextAreaX_
:
=
0
;
145
for
i
:
=
1
upto
NOfTextAreas
:
146
if
(
round
(
x
)
>
=
round
(
xpart
llcorner
TextAreas
[
i
]
)
)
and
147
(
round
(
x
)
<
=
round
(
xpart
lrcorner
TextAreas
[
i
]
)
)
:
148
_TextAreaX_
:
=
xpart
llcorner
TextAreas
[
i
]
;
149
fi
;
150
endfor
;
151
_TextAreaX_
152
enddef
;
153 154
vardef
TextAreaY
(
expr
y
)
=
155
numeric
_TextAreaY_
;
_TextAreaY_
:
=
0
;
156
for
i
:
=
1
upto
NOfTextAreas
:
157
if
(
round
(
y
)
>
=
round
(
ypart
llcorner
TextAreas
[
NOfTextAreas
]
)
)
and
158
(
round
(
y
)
<
=
round
(
ypart
ulcorner
TextAreas
[
NOfTextAreas
]
)
)
:
159
_TextAreaY_
:
=
ypart
llcorner
TextAreas
[
NOfTextAreas
]
;
160
fi
;
161
endfor
;
162
_TextAreaY_
163
enddef
;
164 165
vardef
TextAreaXY
(
expr
x
,
y
)
=
166
pair
_TextAreaXY_
;
_TextAreaXY_
:
=
origin
;
167
for
i
:
=
1
upto
NOfTextAreas
:
168
if
(
round
(
x
)
>
=
round
(
xpart
llcorner
TextAreas
[
i
]
)
)
and
169
(
round
(
x
)
<
=
round
(
xpart
lrcorner
TextAreas
[
i
]
)
)
and
170
(
round
(
y
)
>
=
round
(
ypart
llcorner
TextAreas
[
i
]
)
)
and
171
(
round
(
y
)
<
=
round
(
ypart
ulcorner
TextAreas
[
i
]
)
)
:
172
_TextAreaXY_
:
=
llconer
TextAreas
[
i
]
;
173
fi
;
174
endfor
;
175
_TextAreaXY_
176
enddef
;
177 178
vardef
TextAreaW
(
expr
x
)
=
179
numeric
_TextAreaW_
;
_TextAreaW_
:
=
0
;
180
for
i
:
=
1
upto
NOfTextAreas
:
181
if
(
round
(
x
)
>
=
round
(
xpart
llcorner
TextAreas
[
i
]
)
)
and
182
(
round
(
x
)
<
=
round
(
xpart
lrcorner
TextAreas
[
i
]
)
)
:
183
_TextAreaW_
:
=
bbwidth
(
TextAreas
[
i
]
)
;
184
fi
;
185
endfor
;
186
_TextAreaW_
187
enddef
;
188 189
vardef
TextAreaH
(
expr
y
)
=
190
numeric
_TextAreaH_
;
_TextAreaH_
:
=
0
;
191
for
i
:
=
1
upto
NOfTextAreas
:
192
if
(
round
(
y
)
>
=
round
(
ypart
llcorner
TextAreas
[
i
]
)
)
and
193
(
round
(
y
)
<
=
round
(
ypart
ulcorner
TextAreas
[
i
]
)
)
:
194
_TextAreaH_
:
=
bbheight
(
TextAreas
[
i
]
)
;
195
fi
;
196
endfor
;
197
_TextAreaH_
198
enddef
;
199 200
vardef
TextAreaWH
(
expr
x
,
y
)
=
201
pair
_TextAreaWH_
;
_TextAreaWH_
:
=
origin
;
202
for
i
:
=
1
upto
NOfTextAreas
:
203
if
(
round
(
x
)
>
=
round
(
xpart
llcorner
TextAreas
[
i
]
)
)
and
204
(
round
(
x
)
<
=
round
(
xpart
lrcorner
TextAreas
[
i
]
)
)
and
205
(
round
(
y
)
>
=
round
(
ypart
llcorner
TextAreas
[
i
]
)
)
and
206
(
round
(
y
)
<
=
round
(
ypart
ulcorner
TextAreas
[
i
]
)
)
:
207
_TextAreaWH_
:
=
(
bbwidth
(
TextAreas
[
i
]
)
,
bbheight
(
TextAreas
[
i
]
)
)
;
208
fi
;
209
endfor
;
210
_TextAreaWH_
211
enddef
;
212 213
%D Till here.
214 215
pair
lxy
[
]
,
rxy
[
]
,
cxy
[
]
,
llxy
[
]
,
lrxy
[
]
,
ulxy
[
]
,
urxy
[
]
;
216
path
pxy
[
]
;
217
numeric
hxy
[
]
,
wxy
[
]
,
dxy
[
]
,
nxy
[
]
;
218 219
def
box_found
(
expr
n
,
x
,
y
,
w
,
h
,
d
)
=
220
not
(
(
x
=
0
)
and
(
y
=
0
)
and
(
w
=
0
)
and
(
h
=
0
)
and
(
d
=
0
)
)
221
enddef
;
222 223
def
initialize_box_pos
(
expr
pos
,
n
,
x
,
y
,
w
,
h
,
d
)
=
224
pair
lxy
,
rxy
,
cxy
,
llxy
,
lrxy
,
ulxy
,
urxy
;
225
path
pxy
;
numeric
hxy
,
wxy
,
dxy
,
nxy
;
226
lxy
:
=
(
x
,
y
)
;
227
llxy
:
=
(
x
,
y
-
d
)
;
228
lrxy
:
=
(
x
+
w
,
y
-
d
)
;
229
urxy
:
=
(
x
+
w
,
y
+
h
)
;
230
ulxy
:
=
(
x
,
y
+
h
)
;
231
wxy
:
=
w
;
232
hxy
:
=
h
;
233
dxy
:
=
d
;
234
rxy
:
=
lxy
shifted
(
wxy
,
0
)
;
235
pxy
:
=
llxy
-
-
lrxy
-
-
urxy
-
-
ulxy
-
-
cycle
;
236
cxy
:
=
center
pxy
;
237
nxy
:
=
n
;
238
freeze_box
(
pos
)
;
239
enddef
;
240 241
def
freeze_box
(
expr
pos
)
=
242
lxy
[
pos
]
:
=
lxy
;
243
llxy
[
pos
]
:
=
llxy
;
244
lrxy
[
pos
]
:
=
lrxy
;
245
urxy
[
pos
]
:
=
urxy
;
246
ulxy
[
pos
]
:
=
ulxy
;
247
wxy
[
pos
]
:
=
wxy
;
248
hxy
[
pos
]
:
=
hxy
;
249
dxy
[
pos
]
:
=
dxy
;
250
rxy
[
pos
]
:
=
rxy
;
251
pxy
[
pos
]
:
=
pxy
;
252
cxy
[
pos
]
:
=
cxy
;
253
nxy
[
pos
]
:
=
nxy
;
254
enddef
;
255 256
def
initialize_box
(
expr
n
,
x
,
y
,
w
,
h
,
d
)
=
257
numeric
bpos
;
bpos
:
=
0
;
initialize_box_pos
(
bpos
,
n
,
x
,
y
,
w
,
h
,
d
)
;
258
enddef
;
259 260
def
initialize_area
(
expr
fn
,
fx
,
fy
,
fw
,
fh
,
fd
,
261
tn
,
tx
,
ty
,
tw
,
th
,
td
)
=
262
numeric
fpos
;
fpos
:
=
1
;
initialize_box_pos
(
fpos
,
fn
,
fx
,
fy
,
fw
,
fh
,
fd
)
;
263
numeric
tpos
;
tpos
:
=
2
;
initialize_box_pos
(
tpos
,
tn
,
tx
,
ty
,
tw
,
th
,
td
)
;
264
do_initialize_area
(
fpos
,
tpos
)
;
265
enddef
;
266 267
def
do_initialize_area
(
expr
fpos
,
tpos
)
=
268
lxy
:
=
lxy
[
fpos
]
;
269
llxy
:
=
(
xpart
llxy
[
fpos
]
,
ypart
llxy
[
tpos
]
)
;
270
lrxy
:
=
lrxy
[
tpos
]
;
271
urxy
:
=
(
xpart
urxy
[
tpos
]
,
ypart
urxy
[
fpos
]
)
;
272
ulxy
:
=
ulxy
[
fpos
]
;
273
wxy
:
=
xpart
lrxy
-
xpart
llxy
;
274
hxy
:
=
hxy
[
fpos
]
;
275
dxy
:
=
dxy
[
tpos
]
;
276
rxy
:
=
lxy
shifted
(
wxy
,
0
)
;
277
pxy
:
=
llxy
-
-
lrxy
-
-
urxy
-
-
ulxy
-
-
cycle
;
278
cxy
:
=
center
pxy
;
279
enddef
;
280 281
def
set_par_line_height
(
expr
ph
,
pd
)
=
282
par_strut_height
:
=
if
ph
>
0
:
ph
elseif
StrutHeight
>
0
:
StrutHeight
else
:
8
pt
fi
;
283
par_strut_depth
:
=
if
pd
>
0
:
pd
elseif
StrutDepth
>
0
:
StrutDepth
else
:
3
pt
fi
;
284
par_line_height
:
=
par_strut_height
+
par_strut_depth
;
285
enddef
;
286 287
def
initialize_par
(
expr
fn
,
fx
,
fy
,
fw
,
fh
,
fd
,
288
tn
,
tx
,
ty
,
tw
,
th
,
td
,
289
mn
,
mx
,
my
,
mw
,
mh
,
md
,
290
pn
,
px
,
py
,
pw
,
ph
,
pd
,
291
rw
,
rl
,
rr
,
rh
,
ra
,
ri
)
=
292 293
numeric
fpos
;
fpos
:
=
1
;
initialize_box_pos
(
fpos
,
fn
,
fx
,
fy
,
fw
,
fh
,
fd
)
;
294
numeric
tpos
;
tpos
:
=
2
;
initialize_box_pos
(
tpos
,
tn
,
tx
,
ty
,
tw
,
th
,
td
)
;
295
numeric
mpos
;
mpos
:
=
3
;
initialize_box_pos
(
mpos
,
mn
,
mx
,
my
,
mw
,
mh
,
md
)
;
296
numeric
ppos
;
ppos
:
=
4
;
initialize_box_pos
(
ppos
,
pn
,
px
,
py
,
pw
,
ph
,
pd
)
;
297 298
numeric
par_strut_height
,
par_strut_depth
,
par_line_height
;
299 300
set_par_line_height
(
ph
,
pd
)
;
301 302
do_initialize_area
(
fpos
,
tpos
)
;
303
do_initialize_par
(
fpos
,
tpos
,
mpos
,
ppos
,
rw
,
rl
,
rr
,
rh
,
ra
,
ri
)
;
304 305
enddef
;
306 307
def
initialize_area_par
(
expr
fn
,
fx
,
fy
,
fw
,
fh
,
fd
,
308
tn
,
tx
,
ty
,
tw
,
th
,
td
,
309
wn
,
wx
,
wy
,
ww
,
wh
,
wd
)
=
310 311
numeric
fpos
;
fpos
:
=
1
;
initialize_box_pos
(
fpos
,
fn
,
fx
,
fy
,
fw
,
fh
,
fd
)
;
312
numeric
tpos
;
tpos
:
=
2
;
initialize_box_pos
(
tpos
,
tn
,
tx
,
ty
,
tw
,
th
,
td
)
;
313
numeric
wpos
;
wpos
:
=
3
;
initialize_box_pos
(
wpos
,
wn
,
wx
,
wy
,
ww
,
wh
,
wd
)
;
314 315
numeric
par_strut_height
,
par_strut_depth
,
par_line_height
;
316 317
set_par_line_height
(
wh
,
wd
)
;
318 319
numeric
ffpos
;
ffpos
:
=
4
;
initialize_box_pos
(
ffpos
,
wn
,
wx
,
fy
,
0
,
wh
,
wd
)
;
320
numeric
ttpos
;
ttpos
:
=
5
;
initialize_box_pos
(
ttpos
,
wn
,
wx
+
ww
,
ty
,
0
,
wh
,
wd
)
;
321 322
do_initialize_area
(
ffpos
,
ttpos
)
;
323 324
numeric
mpos
;
mpos
:
=
6
;
freeze_box
(
mpos
)
;
325 326
do_initialize_par
(
fpos
,
tpos
,
mpos
,
ffpos
,
0
,
0
,
0
,
0
,
0
,
0
)
;
327 328
enddef
;
329 330
def
do_initialize_par
(
expr
fpos
,
tpos
,
mpos
,
ppos
,
rw
,
rl
,
rr
,
rh
,
ra
,
ri
)
=
331 332
pair
lref
,
rref
,
pref
,
lhref
,
rhref
;
333 334
% clip the page area to the left and right skips
335 336
llxy
[
mpos
]
:
=
llxy
[
mpos
]
shifted
(
+
rl
,
0
)
;
337
lrxy
[
mpos
]
:
=
lrxy
[
mpos
]
shifted
(
-
rr
,
0
)
;
338
urxy
[
mpos
]
:
=
urxy
[
mpos
]
shifted
(
-
rr
,
0
)
;
339
ulxy
[
mpos
]
:
=
ulxy
[
mpos
]
shifted
(
+
rl
,
0
)
;
340 341
% fixate the leftskip, rightskip and hanging indentation
342 343
lref
:
=
(
xpart
llxy
[
mpos
]
,
ypart
ulxy
[
ppos
]
)
;
lhref
:
=
lref
shifted
(
rh
,
0
)
;
344
rref
:
=
(
xpart
lrxy
[
mpos
]
,
ypart
urxy
[
ppos
]
)
;
rhref
:
=
rref
shifted
(
rh
,
0
)
;
345 346
pref
:
=
lxy
[
ppos
]
;
347 348
if
nxy
[
tpos
]
>
nxy
[
fpos
]
:
349
if
nxy
[
fpos
]
=
nxy
[
mpos
]
:
350
% first of multiple pages
351
llxy
[
tpos
]
:
=
llxy
[
mpos
]
;
352
lrxy
[
tpos
]
:
=
lrxy
[
mpos
]
;
353
urxy
[
tpos
]
:
=
lrxy
[
mpos
]
shifted
(
0
,
par_line_height
)
;
354
ulxy
[
tpos
]
:
=
llxy
[
mpos
]
shifted
(
0
,
par_line_height
)
;
355
boxgriddirection
:
=
down
;
356
elseif
nxy
[
tpos
]
=
nxy
[
mpos
]
:
357
% last of multiple pages
358
llxy
[
fpos
]
:
=
ulxy
[
mpos
]
shifted
(
0
,
-
par_line_height
)
;
359
lrxy
[
fpos
]
:
=
urxy
[
mpos
]
shifted
(
0
,
-
par_line_height
)
;
360
urxy
[
fpos
]
:
=
urxy
[
mpos
]
;
361
ulxy
[
fpos
]
:
=
ulxy
[
mpos
]
;
362
boxgriddirection
:
=
up
;
363
else
:
364
% middle of multiple pages
365
llxy
[
fpos
]
:
=
ulxy
[
mpos
]
shifted
(
0
,
-
par_line_height
)
;
366
lrxy
[
fpos
]
:
=
urxy
[
mpos
]
shifted
(
0
,
-
par_line_height
)
;
367
urxy
[
fpos
]
:
=
urxy
[
mpos
]
;
368
ulxy
[
fpos
]
:
=
ulxy
[
mpos
]
;
369
llxy
[
tpos
]
:
=
llxy
[
mpos
]
;
370
lrxy
[
tpos
]
:
=
lrxy
[
mpos
]
;
371
urxy
[
tpos
]
:
=
lrxy
[
mpos
]
shifted
(
0
,
par_line_height
)
;
372
ulxy
[
tpos
]
:
=
llxy
[
mpos
]
shifted
(
0
,
par_line_height
)
;
373
boxgriddirection
:
=
up
;
374
fi
;
375
else
:
376
% just one page
377
boxgriddirection
:
=
up
;
378
fi
;
379 380
path
txy
,
bxy
,
pxy
,
mxy
;
381 382
txy
:
=
originpath
;
% top
383
bxy
:
=
originpath
;
% bottom
384
pxy
:
=
originpath
;
% composed
385 386
boolean
lefthang
,
righthang
,
somehang
;
387 388
% we only hang on the first of a multiple page background
389 390
if
nxy
[
mpos
]
>
nxy
[
fpos
]
:
391
lefthang
:
=
righthang
:
=
somehang
:
=
false
;
392
else
:
393
lefthang
:
=
(
rh
>
0
)
;
righthang
:
=
(
rh
<
0
)
;
somehang
:
=
false
;
394
fi
;
395 396
if
lefthang
:
397
mxy
:
=
boundingbox
(
lref
--
lref
shifted
(
rh
,
ra
*
par_line_height
)
)
;
398
elseif
righthang
:
399
mxy
:
=
boundingbox
(
rref
--
rref
shifted
(
rh
,
ra
*
par_line_height
)
)
;
400
else
:
401
mxy
:
=
originpath
;
402
fi
;
403 404
if
round
(
ypart
llxy
[
fpos
]
)
=
round
(
ypart
llxy
[
tpos
]
)
:
405 406
% We have a one-liner. Watch how er use the bottom pos for
407
% determining the height.
408 409
llxy
[
fpos
]
:
=
(
xpart
llxy
[
fpos
]
,
ypart
llxy
[
tpos
]
)
;
410
ulxy
[
fpos
]
:
=
(
xpart
ulxy
[
fpos
]
,
ypart
ulxy
[
tpos
]
)
;
411 412
else
:
413 414
% We have a multi-liner. For convenience we now correct the
415
% begin and end points for indentation.
416 417
if
lefthang
and
(
round
(
ypart
llxy
[
tpos
]
)
>
=
round
(
ypart
lrcorner
mxy
)
)
:
418
llxy
[
tpos
]
:
=
(
xpart
lhref
,
ypart
llxy
[
tpos
]
)
;
419
ulxy
[
tpos
]
:
=
(
xpart
lhref
,
ypart
ulxy
[
tpos
]
)
;
420
else
:
421
llxy
[
tpos
]
:
=
(
xpart
lref
,
ypart
llxy
[
tpos
]
)
;
422
ulxy
[
tpos
]
:
=
(
xpart
lref
,
ypart
ulxy
[
tpos
]
)
;
423
fi
;
424 425
if
righthang
and
(
round
(
ypart
lrxy
[
fpos
]
)
>
=
round
(
ypart
llcorner
mxy
)
)
:
426
lrxy
[
fpos
]
:
=
(
xpart
rhref
,
ypart
lrxy
[
fpos
]
)
;
427
urxy
[
fpos
]
:
=
(
xpart
rhref
,
ypart
urxy
[
fpos
]
)
;
428
else
:
429
lrxy
[
fpos
]
:
=
(
xpart
rref
,
ypart
lrxy
[
fpos
]
)
;
430
urxy
[
fpos
]
:
=
(
xpart
rref
,
ypart
urxy
[
fpos
]
)
;
431
fi
;
432 433
fi
;
434 435
somehang
:
=
(
ypart
ulxy
[
fpos
]
>
ypart
llcorner
mxy
)
and
436
(
ypart
llxy
[
tpos
]
<
ypart
llcorner
mxy
)
;
437 438
if
round
(
ypart
llxy
[
fpos
]
)
=
round
(
ypart
llxy
[
tpos
]
)
:
439 440
% A (short) one-liner goes into the top box.
441 442
txy
:
=
llxy
[
fpos
]
--
lrxy
[
tpos
]
--
urxy
[
tpos
]
--
ulxy
[
fpos
]
--
cycle
;
443 444
elseif
(
round
(
ypart
llxy
[
fpos
]
)
=
round
(
ypart
ulxy
[
tpos
]
)
)
and
445
(
round
(
xpart
lrxy
[
tpos
]
)
<
round
(
xpart
llxy
[
fpos
]
)
)
:
446 447
% We have a sentence that spans two lines but with only end
448
% of line and begin of line segments. We need to take care of
449
% indentation.
450 451
txy
:
=
llxy
[
fpos
]
--
lrxy
[
fpos
]
--
urxy
[
fpos
]
--
ulxy
[
fpos
]
--
cycle
;
452
bxy
:
=
llxy
[
tpos
]
--
lrxy
[
tpos
]
--
urxy
[
tpos
]
--
ulxy
[
tpos
]
--
cycle
;
453 454
elseif
(
round
(
ypart
llxy
[
fpos
]
)
=
round
(
ypart
ulxy
[
tpos
]
)
)
:
455 456
% We have a sentence that spans two lines but with overlap.
457 458
pxy
:
=
459
llxy
[
tpos
]
--
lrxy
[
tpos
]
--
urxy
[
tpos
]
--
lrxy
[
fpos
]
--
460
urxy
[
fpos
]
--
ulxy
[
fpos
]
--
llxy
[
fpos
]
--
ulxy
[
tpos
]
--
cycle
;
461 462
elseif
lefthang
and
somehang
:
463 464
% We have a sentence that spans more than two lines with
465
% left hanging indentation.
466 467
pxy
:
=
468
llxy
[
tpos
]
--
lrxy
[
tpos
]
--
urxy
[
tpos
]
--
469
(
xpart
urxy
[
fpos
]
,
ypart
urxy
[
tpos
]
)
--
470
urxy
[
fpos
]
--
ulxy
[
fpos
]
--
llxy
[
fpos
]
--
471
if
round
(
ypart
urxy
[
tpos
]
)
<
round
(
ypart
llcorner
mxy
)
:
472
(
xpart
lrcorner
mxy
,
ypart
llxy
[
fpos
]
)
--
473
lrcorner
mxy
--
474
(
xpart
llxy
[
tpos
]
,
ypart
llcorner
mxy
)
--
475
else
:
476
(
xpart
llxy
[
tpos
]
,
ypart
llxy
[
fpos
]
)
--
477
fi
478
cycle
;
479 480
elseif
righthang
and
somehang
:
481 482
% We have a sentence that spans more than two lines with
483
% right hanging indentation.
484 485
pxy
:
=
486
llxy
[
tpos
]
--
lrxy
[
tpos
]
--
urxy
[
tpos
]
--
487
if
round
(
ypart
urxy
[
tpos
]
)
<
round
(
ypart
llcorner
mxy
)
:
488
(
xpart
lrcorner
mxy
,
ypart
urxy
[
tpos
]
)
--
489
lrcorner
mxy
--
llcorner
mxy
--
490
else
:
491
(
xpart
urxy
[
fpos
]
,
ypart
urxy
[
tpos
]
)
--
492
fi
493
urxy
[
fpos
]
--
ulxy
[
fpos
]
--
llxy
[
fpos
]
--
494
(
xpart
llxy
[
tpos
]
,
ypart
llxy
[
fpos
]
)
--
495
cycle
;
496 497
else
:
498 499
% We have a sentence that spans more than two lines with
500
% no hanging indentation.
501 502
pxy
:
=
503
llxy
[
tpos
]
--
lrxy
[
tpos
]
--
urxy
[
tpos
]
--
504
(
xpart
urxy
[
fpos
]
,
ypart
urxy
[
tpos
]
)
--
505
urxy
[
fpos
]
--
ulxy
[
fpos
]
--
llxy
[
fpos
]
--
506
(
xpart
llxy
[
tpos
]
,
ypart
llxy
[
fpos
]
)
--
507
cycle
;
508 509
fi
;
510 511
pxy
:
=
simplified
pxy
;
512
pxy
:
=
unspiked
pxy
;
513 514
enddef
;
515 516
pair
last_multi_par_shift
;
last_multi_par_shift
:
=
origin
;
517 518
def
relocate_multipars
(
expr
xy
)
=
519
last_multi_par_shift
:
=
xy
;
520
for
i
=
1
upto
nofmultipars
:
521
multipars
[
i
]
:
=
multipars
[
i
]
shifted
last_multi_par_shift
;
522
endfor
;
523
enddef
;
524 525
boolean
compensate_multi_par_topskip
;
526
boolean
span_multi_column_pars
;
527
boolean
auto_multi_par_hsize
;
528
boolean
enable_multi_par_fallback
;
529 530
compensate_multi_par_topskip
:
=
true
;
531
span_multi_column_pars
:
=
false
;
532
auto_multi_par_hsize
:
=
false
;
% true ;
533
enable_multi_par_fallback
:
=
true
;
534 535
vardef
multi_par_at_top
(
expr
i
)
=
536
(
round
(
ypart
ulcorner
multipars
[
i
]
)
=
round
(
ypart
ulcorner
(
TextAreas
[
multirefs
[
i
]
]
shifted
last_multi_par_shift
)
)
)
537
enddef
;
538 539
numeric
nofmultipars
;
nofmultipars
:
=
0
;
540 541
boolean
obey_multi_par_hang
;
obey_multi_par_hang
:
=
true
;
542
boolean
obey_multi_par_more
;
obey_multi_par_more
:
=
true
;
543
boolean
snap_multi_par_tops
;
snap_multi_par_tops
:
=
true
;
544
boolean
local_multi_par_area
;
local_multi_par_area
:
=
false
;
545
boolean
use_multi_par_region
;
use_multi_par_region
:
=
false
;
546
boolean
ignore_multi_par_page
;
ignore_multi_par_page
:
=
false
;
547
boolean
force_multi_par_chain
;
force_multi_par_chain
:
=
true
;
548
boolean
one_piece_multi_par
;
one_piece_multi_par
:
=
false
;
549
boolean
check_multi_par_chain
;
check_multi_par_chain
:
=
true
;
% extra page check
550 551
boolean
multi_column_first_page_hack
;
multi_column_first_page_hack
:
=
true
;
% seems to work ok
552 553
def
simplify_multi_pars
=
% boundingbox ipv shape als optie
554
for
i
:
=
1
upto
nofmultipars
:
555
multipars
[
i
]
:
=
boundingbox
multipars
[
i
]
;
556
endfor
;
557
enddef
;
558 559
def
save_multipar
(
expr
i
,
l
,
p
)
=
560
nofmultipars
:
=
nofmultipars
+
1
;
561
multirefs
[
nofmultipars
]
:
=
i
;
562
multilocs
[
nofmultipars
]
:
=
l
;
563
multipars
[
nofmultipars
]
:
=
unspiked
(
simplified
p
)
;
564
enddef
;
565 566
def
prepare_multi_pars
(
expr
fn
,
fx
,
fy
,
fw
,
fh
,
fd
,
567
tn
,
tx
,
ty
,
tw
,
th
,
td
,
568
wn
,
wx
,
wy
,
ww
,
wh
,
wd
,
569
pn
,
px
,
py
,
pw
,
ph
,
pd
,
570
rw
,
rl
,
rr
,
rh
,
ra
,
ri
)
=
571 572
% fill PlainTextArea withcolor red ;
573
% fill RegionTextArea withcolor green;
574 575
if
span_multi_column_pars
:
576
begingroup
;
577
save
TextAreas
;
path
TextAreas
[
]
;
578
save
NOfTextAreas
;
numeric
NOfTextAreas
;
579
for
i
=
1
upto
NOfTextColumns
:
580
TextAreas
[
i
]
:
=
TextColumns
[
i
]
;
581
endfor
;
582
NOfTextAreas
:
=
NOfTextColumns
;
583
fi
;
584 585
last_multi_par_shift
:
=
origin
;
586 587
% save _tx_, _ty_, _fx_, _fy_ ;
588
% if use_multi_par_region :
589
% _fx_ := fx ; %min(xpart ulcorner RegionTextArea,fx) ;
590
% _fy_ := fy ; %min(xpart ulcorner RegionTextArea,fy) ;
591
% _tx_ := min(xpart lrcorner RegionTextArea,tx) ;
592
% _ty_ := min(xpart lrcorner RegionTextArea,ty) ;
593
% else :
594
% _fx_ := fx ;
595
% _fy_ := fy ;
596
% _tx_ := tx ;
597
% _ty_ := ty ;
598
% fi ;
599 600
% numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,_fx_,_fy_,fw,fh,fd) ;
601
% numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,_tx_,_ty_,tw,th,td) ;
602
numeric
fpos
;
fpos
:
=
1
;
initialize_box_pos
(
fpos
,
fn
,
fx
,
fy
,
fw
,
fh
,
fd
)
;
603
numeric
tpos
;
tpos
:
=
2
;
initialize_box_pos
(
tpos
,
tn
,
tx
,
ty
,
tw
,
th
,
td
)
;
604
numeric
wpos
;
wpos
:
=
3
;
initialize_box_pos
(
wpos
,
wn
,
wx
,
wy
,
ww
,
wh
,
wd
)
;
605
numeric
ppos
;
ppos
:
=
4
;
initialize_box_pos
(
ppos
,
pn
,
px
,
py
,
pw
,
ph
,
pd
)
;
606 607
if
local_multi_par_area
:
608
RealPageNumber
:
=
fn
;
609
NOfTextAreas
:
=
1
;
610
NOfSavedTextAreas
:
=
0
;
611
TextAreas
[
1
]
:
=
TextAreas
[
0
]
;
612
TextColumns
[
1
]
:
=
TextColumns
[
0
]
;
613
nxy
[
fpos
]
:
=
nxy
[
tpos
]
:
=
nxy
[
wpos
]
:
=
nxy
[
ppos
]
:
=
RealPageNumber
;
614
elseif
use_multi_par_region
:
615
RealPageNumber
:
=
fn
;
616
NOfTextAreas
:
=
1
;
617
NOfSavedTextAreas
:
=
0
;
618
TextAreas
[
1
]
:
=
RegionTextArea
;
619
TextColumns
[
1
]
:
=
RegionTextArea
;
620
nxy
[
fpos
]
:
=
nxy
[
tpos
]
:
=
nxy
[
wpos
]
:
=
nxy
[
ppos
]
:
=
RealPageNumber
;
621
elseif
ignore_multi_par_page
:
622
RealPageNumber
:
=
fn
;
623
nxy
[
fpos
]
:
=
nxy
[
tpos
]
:
=
nxy
[
wpos
]
:
=
nxy
[
ppos
]
:
=
RealPageNumber
;
624
fi
;
625 626
numeric
par_strut_height
,
par_strut_depth
,
par_line_height
;
627 628
set_par_line_height
(
ph
,
pd
)
;
629 630
numeric
par_hang_indent
,
par_hang_after
,
par_indent
,
par_left_skip
,
par_right_skip
;
631 632
par_hang_indent
:
=
rh
;
633
par_hang_after
:
=
ra
;
634
par_indent
:
=
ri
;
635
par_left_skip
:
=
rl
;
636
par_right_skip
:
=
rr
;
637 638
pair
par_start_pos
;
639
pair
par_stop_pos
;
640 641
par_start_pos
:
=
llxy
[
fpos
]
642
if
par_indent
<
0
:
shifted
(
-
par_indent
,
0
)
fi
643
if
par_left_skip
<
0
:
shifted
(
-
par_left_skip
,
0
)
fi
;
644 645
par_stop_pos
:
=
lrxy
[
tpos
]
646
if
par_right_skip
<
0
:
shifted
(
par_right_skip
,
0
)
fi
;
% nasty as the endpos can be shifted by rightskip
647 648
if
wxy
[
wpos
]
>
0
:
649
left_skip
:
=
rl
+
xpart
llxy
[
wpos
]
-
xpart
llxy
[
ppos
]
;
650
right_skip
:
=
rw
-
left_skip
-
ww
;
651
else
:
652
left_skip
:
=
rl
;
653
right_skip
:
=
rr
;
654
fi
;
655 656
path
multipar
,
multipars
[
]
;
657
numeric
multiref
,
multirefs
[
]
;
658
numeric
multiloc
,
multilocs
[
]
;
% 1=begin 2=between 3=end
659 660
numeric
multi_par_pages
;
multi_par_pages
:
=
nxy
[
tpos
]
-
nxy
[
fpos
]
+1
;
661 662
% locals .. why can't i move these outside?
663 664
vardef
_pmp_set_multipar_
(
expr
i
)
=
665
(
(
TextAreas
[
i
]
leftenlarged
-
left_skip
)
rightenlarged
(
-
right_skip
666
if
auto_multi_par_hsize
:
+
rw
-
bbwidth
(
TextAreas
[
i
]
)
fi
)
)
667
enddef
;
668 669
vardef
_pmp_snapped_multi_pos_
(
expr
p
)
=
670
if
snap_multi_par_tops
:
671
if
abs
(
ypart
p
-
ypart
ulcorner
multipar
)
<
par_line_height
:
672
(
xpart
p
,
ypart
ulcorner
multipar
)
673
else
:
674
p
675
fi
676
else
:
677
p
678
fi
679
enddef
;
680 681
vardef
_pmp_estimated_par_lines_
(
expr
h
)
=
682
round
(
h
/
par_line_height
)
683
enddef
;
684 685
vardef
_pmp_top_multi_par_
(
expr
p
)
=
686
(
round
(
_pmp_estimated_par_lines_
(
bbheight
(
p
)
*
par_line_height
)
)
=
round
(
bbheight
(
p
)
)
)
687
enddef
;
688 689
vardef
_pmp_multi_par_tsc_
(
expr
p
)
=
690
if
_pmp_top_multi_par_
(
p
)
:
TopSkipCorrection
else
:
0
fi
691
enddef
;
692 693
vardef
_pmp_estimated_multi_par_height_
(
expr
n
,
t
)
=
694
if
round
(
par_line_height
)
=
0
:
695
0
696
else
:
697
save
ok
,
h
;
boolean
ok
;
698
numeric
h
;
h
:
=
0
;
699
ok
:
=
false
;
700
if
(
nxy
[
fpos
]
=
RealPageNumber
-1
)
:
701
for
i
:
=
1
upto
NOfSavedTextAreas
:
702
if
(
InsideSavedTextArea
(
i
,
par_start_pos
)
)
:
703
ok
:
=
true
;
704
h
:
=
h
+
_pmp_estimated_par_lines_
(
ypart
ulxy
[
fpos
]
-
ypart
llcorner
SavedTextAreas
[
i
]
)
;
705
elseif
ok
:
706
h
:
=
h
+
_pmp_estimated_par_lines_
(
bbheight
(
SavedTextAreas
[
i
]
)
)
;
707
fi
;
708
endfor
;
709
fi
;
710
if
ok
:
711
for
i
:
=
1
upto
n
-1
:
712
h
:
=
h
+
_pmp_estimated_par_lines_
(
bbheight
(
TextAreas
[
i
]
)
)
;
713
endfor
;
714
else
:
715
% already: ok := false ;
716
for
i
:
=
1
upto
n
-1
:
717
if
(
InsideTextArea
(
i
,
par_start_pos
)
)
:
718
ok
:
=
true
;
719
h
:
=
h
+
_pmp_estimated_par_lines_
(
ypart
ulxy
[
fpos
]
-
ypart
llcorner
TextAreas
[
i
]
)
;
720
elseif
ok
:
721
h
:
=
h
+
_pmp_estimated_par_lines_
(
bbheight
(
TextAreas
[
i
]
)
)
;
722
fi
;
723
endfor
;
724
fi
;
725
h
726
fi
727
enddef
;
728 729
vardef
_pmp_left_top_hang_
(
expr
same_area
)
=
730 731
par_hang_after
:
=
ra
+
_pmp_estimated_par_lines_
(
py
-
fy
)
;
732 733
if
(
par_hang_indent
>
0
)
and
(
par_hang_after
<
0
)
and
obey_multi_par_hang
:
734
pair
_ul_
;
_ul_
:
=
(
xpart
ulcorner
multipar
,
ypart
_pmp_snapped_multi_pos_
(
ulxy
[
fpos
]
)
)
;
735
pair
_pa_
;
_pa_
:
=
_ul_
shifted
(
0
,
par_hang_after
*
par_line_height
)
;
736
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
-
TopSkipCorrection
,
ypart
llcorner
multipar
)
)
;
737
if
same_area
:
738
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
-
TopSkipCorrection
,
ypart
llxy
[
tpos
]
)
)
;
739
fi
;
740
if
obey_multi_par_more
and
(
round
(
par_line_height
)
>
0
)
:
741
par_hang_after
:
=
min
(
0
,
round
(
par_hang_after
+
(
ypart
urxy
[
fpos
]
-
ypart
_pa_
)
/
par_line_height
)
)
;
742
fi
;
743
(
xpart
_ul_
+
par_hang_indent
,
ypart
lrxy
[
fpos
]
)
--
744
(
xpart
_ul_
+
par_hang_indent
,
ypart
_pa_
)
--
745
(
xpart
ulcorner
multipar
,
ypart
_pa_
)
746
else
:
747
(
xpart
ulcorner
multipar
,
ypart
lrxy
[
fpos
]
)
748
fi
749
enddef
;
750 751
vardef
_pmp_right_top_hang_
(
expr
same_area
)
=
752 753
par_hang_after
:
=
ra
+
_pmp_estimated_par_lines_
(
py
-
fy
)
;
754 755
if
(
par_hang_indent
<
0
)
and
(
par_hang_after
<
0
)
and
obey_multi_par_hang
:
756
pair
_ur_
;
_ur_
:
=
(
xpart
urcorner
multipar
,
ypart
_pmp_snapped_multi_pos_
(
urxy
[
fpos
]
)
)
;
757
pair
_pa_
;
_pa_
:
=
_ur_
shifted
(
0
,
par_hang_after
*
par_line_height
)
;
758
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
-
TopSkipCorrection
,
ypart
llcorner
multipar
)
)
;
759
if
same_area
:
760
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
-
TopSkipCorrection
,
ypart
_pmp_snapped_multi_pos_
(
ulxy
[
tpos
]
)
)
)
;
761
fi
;
762
if
obey_multi_par_more
and
(
round
(
par_line_height
)
>
0
)
:
763
par_hang_after
:
=
min
(
0
,
round
(
par_hang_after
+
(
ypart
urxy
[
fpos
]
-
ypart
_pa_
)
/
par_line_height
)
)
;
764
fi
;
765
(
xpart
urcorner
multipar
,
ypart
_pa_
)
--
766
(
xpart
_ur_
+
par_hang_indent
,
ypart
_pa_
)
--
767
(
xpart
_ur_
+
par_hang_indent
,
ypart
_pmp_snapped_multi_pos_
(
urxy
[
fpos
]
)
)
768
else
:
769
(
xpart
urcorner
multipar
,
ypart
_pmp_snapped_multi_pos_
(
urxy
[
fpos
]
)
)
770
fi
771
enddef
;
772 773
vardef
_pmp_x_left_top_hang_
(
expr
i
,
t
)
=
774
par_hang_after
:
=
min
(
0
,
ra
+
_pmp_estimated_multi_par_height_
(
i
,
t
)
)
;
775
if
(
par_hang_indent
>
0
)
and
(
par_hang_after
<
0
)
:
776
pair
_ul_
;
_ul_
:
=
ulcorner
multipar
;
777
pair
_pa_
;
_pa_
:
=
_ul_
shifted
(
0
,
par_hang_after
*
par_line_height
)
;
778
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
,
ypart
llcorner
multipar
)
)
;
779
if
t
:
780
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
,
ypart
llxy
[
tpos
]
)
)
;
781
fi
;
782
if
abs
(
ypart
_pa_
-
ypart
llxy
[
tpos
]
)
<
par_line_height
:
783
_pa_
:
=
(
xpart
_pa_
,
ypart
llxy
[
tpos
]
)
;
784
fi
;
785
if
abs
(
ypart
_pa_
-
ypart
llcorner
multipar
)
<
par_line_height
:
786
_pa_
:
=
(
xpart
_pa_
,
ypart
llcorner
multipar
)
;
787
fi
;
788
(
xpart
_ul_
,
ypart
_pa_
)
--
789
(
xpart
_ul_
+
par_hang_indent
,
ypart
_pa_
)
--
790
(
xpart
_ul_
+
par_hang_indent
,
ypart
_ul_
)
791
else
:
792
ulcorner
multipar
793
fi
794
enddef
;
795 796
vardef
_pmp_x_right_top_hang_
(
expr
i
,
t
)
=
797
par_hang_after
:
=
min
(
0
,
ra
+
_pmp_estimated_multi_par_height_
(
i
,
t
)
)
;
798
if
(
par_hang_indent
<
0
)
and
(
par_hang_after
<
0
)
:
799
pair
_ur_
;
_ur_
:
=
urcorner
multipar
;
800
pair
_pa_
;
_pa_
:
=
_ur_
shifted
(
0
,
par_hang_after
*
par_line_height
)
;
801
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
,
ypart
lrcorner
multipar
)
)
;
802
if
t
:
803
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
,
ypart
_pmp_snapped_multi_pos_
(
urxy
[
tpos
]
)
)
)
;
804
fi
;
805
(
xpart
_ur_
+
par_hang_indent
,
ypart
_ur_
)
--
806
(
xpart
_ur_
+
par_hang_indent
,
ypart
_pa_
)
--
807
(
xpart
_ur_
,
ypart
_pa_
)
808
else
:
809
urcorner
multipar
810
fi
811
enddef
;
812 813
vardef
_pmp_left_bottom_hang_
(
expr
same_area
)
=
814
pair
_ll_
,
_sa_
,
_pa_
;
815
_sa_
:
=
if
same_area
:
llxy
[
tpos
]
else
:
lrcorner
multipar
fi
;
816
if
(
par_hang_indent
>
0
)
and
(
par_hang_after
>
0
)
and
obey_multi_par_hang
:
817
_ll_
:
=
(
xpart
ulcorner
multipar
,
ypart
_pmp_snapped_multi_pos_
(
ulxy
[
fpos
]
)
)
;
818
_pa_
:
=
_ll_
shifted
(
0
,
-
par_hang_after
*
par_line_height
)
;
819
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
,
ypart
llcorner
multipar
)
)
;
820
if
same_area
:
821
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
,
ypart
_sa_
)
)
;
822
fi
;
823
if
obey_multi_par_more
and
(
round
(
par_line_height
)
>
0
)
:
824
par_hang_after
:
=
max
(
0
,
round
(
par_hang_after
-
(
ypart
urxy
[
fpos
]
-
ypart
_pa_
)
/
par_line_height
)
)
;
825
fi
;
826
_pa_
--
827
(
xpart
_pa_
+
par_hang_indent
,
ypart
_pa_
)
--
828
(
xpart
_pa_
+
par_hang_indent
,
ypart
_sa_
)
829
else
:
830
(
xpart
llcorner
multipar
,
ypart
_sa_
)
831
fi
832
enddef
;
833 834
vardef
_pmp_right_bottom_hang_
(
expr
same_area
)
=
835
pair
_lr_
,
_sa_
,
_pa_
;
836
_sa_
:
=
if
same_area
:
_pmp_snapped_multi_pos_
(
ulxy
[
tpos
]
)
else
:
lrcorner
multipar
fi
;
837
if
(
par_hang_indent
<
0
)
and
(
par_hang_after
>
0
)
and
obey_multi_par_hang
:
838
_lr_
:
=
(
xpart
urcorner
multipar
,
ypart
_pmp_snapped_multi_pos_
(
urxy
[
fpos
]
)
)
;
839
_pa_
:
=
_lr_
shifted
(
0
,
-
par_hang_after
*
par_line_height
)
;
840
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
,
ypart
lrcorner
multipar
)
)
;
841
if
same_area
:
842
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
,
ypart
_pmp_snapped_multi_pos_
(
ulxy
[
tpos
]
)
)
)
;
843
fi
;
844
if
obey_multi_par_more
and
(
round
(
par_line_height
)
>
0
)
:
845
par_hang_after
:
=
max
(
0
,
round
(
par_hang_after
-
(
ypart
urxy
[
fpos
]
-
ypart
_pa_
)
/
par_line_height
)
)
;
846
fi
;
847
(
xpart
_pa_
+
par_hang_indent
,
ypart
_sa_
)
--
848
(
xpart
_pa_
+
par_hang_indent
,
ypart
_pa_
)
--
849
_pa_
850
else
:
851
(
xpart
lrcorner
multipar
,
ypart
_sa_
)
852
fi
853
enddef
;
854 855
vardef
_pmp_x_left_bottom_hang_
(
expr
i
,
t
)
=
856
pair
_ll_
,
_sa_
,
_pa_
;
857
_sa_
:
=
if
t
:
llxy
[
tpos
]
else
:
llcorner
multipar
fi
;
858
if
(
par_hang_indent
>
0
)
and
(
ra
>
0
)
:
859
par_hang_after
:
=
max
(
0
,
ra
-
_pmp_estimated_multi_par_height_
(
i
,
t
)
)
;
860
_ll_
:
=
ulcorner
multipar
;
861
_pa_
:
=
_ll_
shifted
(
0
,
-
par_hang_after
*
par_line_height
)
;
862
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
,
ypart
llcorner
multipar
)
)
;
863
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
,
ypart
_sa_
)
)
;
864
% we need to compensate for topskip enlarged areas
865
if
abs
(
ypart
_pa_
-
ypart
_sa_
)
>
par_line_height
:
866
(
xpart
_pa_
+
par_hang_indent
,
ypart
_sa_
)
--
867
(
xpart
_pa_
+
par_hang_indent
,
ypart
_pa_
)
--
868
fi
869
_pa_
870
else
:
871
(
xpart
llcorner
multipar
,
ypart
_sa_
)
872
fi
873
enddef
;
874 875
vardef
_pmp_x_right_bottom_hang_
(
expr
i
,
t
)
=
876
pair
_lr_
,
_sa_
,
_pa_
;
877
_sa_
:
=
if
t
:
_pmp_snapped_multi_pos_
(
ulxy
[
tpos
]
)
else
:
llcorner
multipar
fi
;
878
if
(
par_hang_indent
<
0
)
and
(
ra
>
0
)
:
879
par_hang_after
:
=
max
(
0
,
ra
-
_pmp_estimated_multi_par_height_
(
i
,
t
)
)
;
880
_lr_
:
=
urcorner
multipar
;
881
_pa_
:
=
_lr_
shifted
(
0
,
-
par_hang_after
*
par_line_height
)
;
882
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
,
ypart
lrcorner
multipar
)
)
;
883
_pa_
:
=
(
xpart
_pa_
,
max
(
ypart
_pa_
,
ypart
_sa_
)
)
;
884
% we need to compensate for topskip enlarged areas
885
_pa_
886
if
abs
(
ypart
_pa_
-
ypart
_sa_
)
>
par_line_height
:
887
--
(
xpart
_pa_
+
par_hang_indent
,
ypart
_pa_
)
888
--
(
xpart
_pa_
+
par_hang_indent
,
ypart
_sa_
)
889
fi
890
else
:
891
(
xpart
lrcorner
multipar
,
ypart
_sa_
)
892
fi
893
enddef
;
894 895
% def _pmp_test_multipar_ =
896
% multipar := boundingbox multipar ;
897
% enddef ;
898 899
% first loop
900 901
ii
:
=
0
;
nn
:
=
NOfTextAreas
+1
;
nofmultipars
:
=
0
;
902 903
if
enable_multi_par_fallback
and
(
nxy
[
fpos
]
=
RealPageNumber
)
904
and
(
nxy
[
tpos
]
=
RealPageNumber
)
and
not
(
InsideSomeTextArea
(
lxy
[
fpos
]
)
and
InsideSomeTextArea
(
rxy
[
tpos
]
)
)
:
905 906
% fallback
907 908
% multipar :=
909
% llxy[fpos] --
910
% lrxy[tpos] --
911
% urxy[tpos] --
912
% ulxy[fpos] -- cycle ;
913
%
914
% save_multipar (1,1,multipar) ;
915 916
% we need to take the boundingbox because there can be
917
% more lines and we want a proper rectange
918 919
multipar
:
=
920
ulxy
[
fpos
]
--
921
urxy
[
tpos
]
--
922
lrxy
[
fpos
]
--
923
llxy
[
tpos
]
--
cycle
;
924 925
save_multipar
(
1
,
1
,
boundingbox
(
multipar
)
)
;
926 927
else
:
928 929
% normal
930 931
for
i
=
1
upto
NOfTextAreas
:
932 933
TopSkipCorrection
:
=
0
;
934 935
multipar
:
=
_pmp_set_multipar_
(
i
)
;
936 937
% watch how we compensate for negative indentation
938 939
if
(
nxy
[
fpos
]
=
RealPageNumber
)
and
(
InsideTextArea
(
i
,
par_start_pos
)
)
:
940 941
% first one in chain
942 943
ii
:
=
i
;
944 945
if
(
nxy
[
tpos
]
=
RealPageNumber
)
and
(
InsideTextArea
(
i
,
par_stop_pos
)
)
:
946 947
% in same area
948 949
nn
:
=
i
;
950 951
if
compensate_multi_par_topskip
and
(
round
(
LineHeight
-
ph
-
pd
)
=
0
)
:
952 953
TopSkipCorrection
:
=
TopSkip
-
StrutHeight
;
954 955
if
round
(
ypart
ulxy
[
fpos
]
+
TopSkipCorrection
)
=
round
(
ypart
ulcorner
TextAreas
[
i
]
)
:
956
ulxy
[
fpos
]
:
=
ulxy
[
fpos
]
shifted
(
0
,
TopSkipCorrection
)
;
957
urxy
[
fpos
]
:
=
urxy
[
fpos
]
shifted
(
0
,
TopSkipCorrection
)
;
958
else
:
959
TopSkipCorrection
:
=
0
;
960
fi
;
961 962
fi
;
963 964
if
ypart
llxy
[
fpos
]
=
ypart
llxy
[
tpos
]
:
965 966
multipar
:
=
967
llxy
[
fpos
]
--
968
lrxy
[
tpos
]
--
969
_pmp_snapped_multi_pos_
(
urxy
[
tpos
]
)
--
970
_pmp_snapped_multi_pos_
(
ulxy
[
fpos
]
)
--
971
cycle
;
972 973
save_multipar
(
i
,
1
,
multipar
)
;
974 975
elseif
(
ypart
llxy
[
fpos
]
=
ypart
ulxy
[
tpos
]
)
and
(
xpart
llxy
[
tpos
]
<
xpart
llxy
[
fpos
]
)
:
976 977
% two loners
978 979
multipar
:
=
if
obey_multi_par_hang
:
980 981
_pmp_right_bottom_hang_
(
true
)
--
982
_pmp_right_top_hang_
(
true
)
--
983
_pmp_snapped_multi_pos_
(
urxy
[
fpos
]
)
--
984
lrxy
[
fpos
]
--
985 986
else
:
987 988
llxy
[
fpos
]
--
989
(
xpart
urcorner
multipar
,
ypart
llxy
[
fpos
]
)
--
990
(
xpart
urcorner
multipar
,
ypart
ulxy
[
fpos
]
)
--
991
_pmp_snapped_multi_pos_
(
ulxy
[
fpos
]
)
--
992 993
fi
cycle
;
994 995
save_multipar
(
i
,
1
,
multipar
)
;
996 997
multipar
:
=
_pmp_set_multipar_
(
i
)
;
998 999
multipar
:
=
if
obey_multi_par_hang
:
1000 1001
_pmp_left_bottom_hang_
(
true
)
--
1002
llxy
[
tpos
]
--
1003
_pmp_snapped_multi_pos_
(
ulxy
[
tpos
]
)
--
1004
_pmp_left_top_hang_
(
true
)
--
1005 1006
else
:
1007 1008
(
xpart
llcorner
multipar
,
ypart
llxy
[
tpos
]
)
--
1009
llxy
[
tpos
]
--
1010
_pmp_snapped_multi_pos_
(
ulxy
[
tpos
]
)
--
1011
(
xpart
llcorner
multipar
,
ypart
ulxy
[
tpos
]
)
--
1012 1013
fi
cycle
;
1014 1015
save_multipar
(
i
,
1
,
multipar
)
;
1016 1017
else
:
1018 1019
multipar
:
=
if
obey_multi_par_hang
:
1020 1021
_pmp_left_bottom_hang_
(
true
)
--
1022
llxy
[
tpos
]
--
1023
_pmp_snapped_multi_pos_
(
ulxy
[
tpos
]
)
--
1024
_pmp_right_bottom_hang_
(
true
)
--
1025
_pmp_right_top_hang_
(
true
)
--
1026
_pmp_snapped_multi_pos_
(
urxy
[
fpos
]
)
--
1027
lrxy
[
fpos
]
--
1028
_pmp_left_top_hang_
(
true
)
--
1029 1030
else
:
1031 1032
(
xpart
llcorner
multipar
,
ypart
llxy
[
tpos
]
)
--
1033
llxy
[
tpos
]
--
1034
_pmp_snapped_multi_pos_
(
ulxy
[
tpos
]
)
--
1035
(
xpart
lrcorner
multipar
,
ypart
ulxy
[
tpos
]
)
--
1036
(
xpart
urcorner
multipar
,
ypart
urxy
[
fpos
]
)
--
1037
_pmp_snapped_multi_pos_
(
urxy
[
fpos
]
)
--
1038
lrxy
[
fpos
]
--
1039
(
xpart
ulcorner
multipar
,
ypart
lrxy
[
fpos
]
)
--
1040 1041
fi
cycle
;
1042 1043
save_multipar
(
i
,
1
,
multipar
)
;
1044 1045
fi
;
1046 1047
else
:
1048 1049
multipar
:
=
if
obey_multi_par_hang
:
1050 1051
_pmp_left_bottom_hang_
(
false
)
--
1052
_pmp_right_bottom_hang_
(
false
)
--
1053
_pmp_right_top_hang_
(
false
)
--
1054
_pmp_snapped_multi_pos_
(
urxy
[
fpos
]
)
--
1055
lrxy
[
fpos
]
--
1056
_pmp_left_top_hang_
(
false
)
--
1057 1058
else
:
1059 1060
llcorner
multipar
--
1061
lrcorner
multipar
--
1062
(
xpart
urcorner
multipar
,
ypart
urxy
[
fpos
]
)
--
1063
_pmp_snapped_multi_pos_
(
urxy
[
fpos
]
)
--
1064
lrxy
[
fpos
]
--
1065
(
xpart
ulcorner
multipar
,
ypart
lrxy
[
fpos
]
)
--
1066 1067
fi
cycle
;
1068 1069
save_multipar
(
i
,
1
,
multipar
)
;
1070 1071
fi
;
1072 1073
elseif
(
nxy
[
tpos
]
=
RealPageNumber
)
and
(
InsideTextArea
(
i
,
par_stop_pos
)
)
:
1074 1075
% last one in chain
1076 1077
nn
:
=
i
;
1078 1079
if
obey_multi_par_hang
and
obey_multi_par_more
:
1080 1081
multipar
:
=
1082
_pmp_x_left_top_hang_
(
i
,
true
)
--
1083
_pmp_x_right_top_hang_
(
i
,
true
)
--
1084
_pmp_x_right_bottom_hang_
(
i
,
true
)
--
1085
_pmp_snapped_multi_pos_
(
ulxy
[
tpos
]
)
--
1086
llxy
[
tpos
]
--
1087
_pmp_x_left_bottom_hang_
(
i
,
true
)
--
1088
cycle
;
1089 1090
else
:
1091 1092
multipar
:
=
1093
ulcorner
multipar
--
1094
urcorner
multipar
--
1095
(
xpart
lrcorner
multipar
,
ypart
urxy
[
tpos
]
)
--
1096
_pmp_snapped_multi_pos_
(
ulxy
[
tpos
]
)
--
1097
llxy
[
tpos
]
--
1098
(
xpart
llcorner
multipar
,
ypart
llxy
[
tpos
]
)
--
1099
cycle
;
1100 1101
fi
;
1102 1103
save_multipar
(
i
,
3
,
multipar
)
;
1104 1105
elseif
multi_column_first_page_hack
and
(
(
nxy
[
fpos
]
=
RealPageNumber
)
and
(
nxy
[
tpos
]
>
=
RealPageNumber
)
and
(
NOfTextColumns
>
1
)
)
:
1106 1107
save_multipar
(
i
,
2
,
multipar
)
;
1108 1109
else
:
1110
% handled later
1111
fi
;
1112 1113
endfor
;
1114 1115 1116
% second loop
1117 1118
if
force_multi_par_chain
or
(
ii
>
1
)
:
1119 1120
for
i
=
ii
+1
upto
nn
-1
:
1121 1122
% rest of chain / todo : hang
1123 1124
% hm, the second+ column in column sets now gets lost in a NOfTextColumns
1125 1126
if
(
not
check_multi_par_chain
)
or
(
(
nxy
[
fpos
]
<
RealPageNumber
)
and
(
nxy
[
tpos
]
>
RealPageNumber
)
)
:
1127 1128
multipar
:
=
_pmp_set_multipar_
(
i
)
;
1129 1130
if
obey_multi_par_hang
and
obey_multi_par_more
:
1131 1132
multipar
:
=
1133
_pmp_x_left_top_hang_
(
i
,
false
)
--
1134
_pmp_x_right_top_hang_
(
i
,
false
)
--
1135
_pmp_x_right_bottom_hang_
(
i
,
false
)
--
1136
_pmp_x_left_bottom_hang_
(
i
,
false
)
--
1137
cycle
;
1138 1139
fi
;
1140 1141
save_multipar
(
i
,
2
,
multipar
)
;
1142 1143
fi
;
1144 1145
endfor
;
1146 1147
fi
;
1148 1149
% end of normal/fallback
1150 1151
fi
;
1152 1153
if
span_multi_column_pars
:
1154
endgroup
;
1155
fi
;
1156 1157
% potential safeguard:
1158 1159
% for i=1 upto nofmultipars :
1160
% if length p <= 4 :
1161
% multipars[i] := boundingbox(multipars[i]) ;
1162
% fi ;
1163
% end ;
1164 1165
% quick hack for gb:
1166 1167
one_piece_multi_par
:
=
(
nofmultipars
=
1
)
and
(
pn
=
tn
)
;
1168 1169
enddef
;
1170 1171
def
boxgridoptions
=
withcolor
.8
red
enddef
;
1172
def
boxlineoptions
=
withcolor
.8
blue
enddef
;
1173
def
boxfilloptions
=
withcolor
.8
white
enddef
;
1174 1175
numeric
boxgridtype
;
boxgridtype
:
=
0
;
1176
numeric
boxlinetype
;
boxlinetype
:
=
1
;
1177
numeric
boxfilltype
;
boxfilltype
:
=
1
;
1178
numeric
boxdashtype
;
boxdashtype
:
=
0
;
1179
pair
boxgriddirection
;
boxgriddirection
:
=
up
;
1180
numeric
boxgridwidth
;
boxgridwidth
:
=
1
pt
;
1181
numeric
boxlinewidth
;
boxlinewidth
:
=
1
pt
;
1182
numeric
boxlineradius
;
boxlineradius
:
=
0
pt
;
1183
numeric
boxfilloffset
;
boxfilloffset
:
=
0
pt
;
1184
numeric
boxgriddistance
;
boxgriddistance
:
=
.5
cm
;
1185
numeric
boxgridshift
;
boxgridshift
:
=
0
pt
;
1186 1187
% def draw_box =
1188
% draw pxy boxlineoptions withpen pencircle scaled boxlinewidth ;
1189
% draw lxy -- rxy boxlineoptions withpen pencircle scaled boxgridwidth ;
1190
% enddef ;
1191 1192
def
draw_par
=
% 1 2 3 11 12
1193
do_draw_par
(
pxy
)
;
do_draw_par
(
txy
)
;
do_draw_par
(
bxy
)
;
1194
for
i
=
pxy
,
txy
,
bxy
:
1195
if
boxgridtype
=
1
:
1196
boxgriddirection
:
=
origin
;
1197
draw
baseline_grid
(
i
,
boxgriddirection
,
true
)
boxgridoptions
;
1198
elseif
boxgridtype
=
2
:
1199
boxgriddirection
:
=
origin
;
1200
draw
baseline_grid
(
i
,
boxgriddirection
,
false
)
boxgridoptions
;
1201
elseif
boxgridtype
=
3
:
1202
boxgriddirection
:
=
origin
;
1203
draw
baseline_grid
(
i
,
boxgriddirection
,
true
)
boxgridoptions
;
1204
draw
baseline_grid
(
i
,
boxgriddirection
,
true
)
shifted
(
0
,
ExHeight
)
boxgridoptions
;
1205
elseif
boxgridtype
=
4
:
1206
boxgriddirection
:
=
origin
;
1207
draw
baseline_grid
(
i
,
boxgriddirection
,
true
)
shifted
(
0
,
ExHeight
/
2
)
boxgridoptions
;
1208
elseif
boxgridtype
=
11
:
1209
draw
graphic_grid
(
i
,
boxgriddistance
,
boxgriddistance
,
boxgriddistance
/
2
,
boxgriddistance
/
2
)
;
1210
elseif
boxgridtype
=
12
:
1211
draw
graphic_grid
(
i
,
boxgriddistance
,
boxgriddistance
,
0
,
0
)
;
1212
fi
;
1213
endfor
;
1214
enddef
;
1215 1216
def
do_show_par
(
expr
p
,
r
,
c
)
=
1217
if
length
(
p
)
>
2
:
1218
for
i
=
0
upto
length
(
p
)
:
1219
draw
fullcircle
scaled
r
shifted
point
i
of
p
withpen
pencircle
scaled
.5
pt
withcolor
c
;
1220
endfor
;
1221
fi
;
1222
draw
p
withpen
pencircle
scaled
.5
pt
withcolor
c
;
1223
enddef
;
1224 1225
def
show_par
=
1226
if
length
(
mxy
)
>
2
:
1227
draw
mxy
dashed
evenly
withpen
pencircle
scaled
.5
pt
withcolor
.5
white
;
1228
fi
;
1229
do_show_par
(
txy
,
4
pt
,
.5
green
)
;
1230
do_show_par
(
bxy
,
6
pt
,
.5
blue
)
;
1231
do_show_par
(
pxy
,
8
pt
,
.5
red
)
;
1232
draw
pref
withpen
pencircle
scaled
2
pt
;
1233
enddef
;
1234 1235
def
sort_multi_pars
=
1236
if
nofmultipars
>
1
:
1237
begingroup
;
1238
save
_p_
,
_n_
;
path
_p_
;
numeric
_n_
;
1239
for
i
:
=
1
upto
nofmultipars
:
1240
if
multilocs
[
i
]
=
3
:
1241
_p_
:
=
multipars
[
nofmultipars
]
;
1242
multipars
[
nofmultipars
]
:
=
multipars
[
i
]
;
1243
multipars
[
i
]
:
=
_p_
;
1244
_n_
:
=
multirefs
[
nofmultipars
]
;
1245
multirefs
[
nofmultipars
]
:
=
multirefs
[
i
]
;
1246
multirefs
[
i
]
:
=
_n_
;
1247
_n_
:
=
multilocs
[
nofmultipars
]
;
1248
multilocs
[
nofmultipars
]
:
=
multilocs
[
i
]
;
1249
multilocs
[
i
]
:
=
_n_
;
1250
fi
;
1251
endfor
;
1252
endgroup
;
1253
fi
;
1254
enddef
;
1255 1256
def
collapse_multi_pars
=
1257
if
nofmultipars
>
1
:
1258
begingroup
;
1259
save
_nofmultipars_
;
numeric
_nofmultipars_
;
1260
_nofmultipars_
:
=
1
;
1261
sort_multi_pars
;
% block not in order: 1, 3, 2....
1262
for
i
:
=
1
upto
nofmultipars
-1
:
1263
if
(
round
(
xpart
(
llcorner
multipars
[
i
]
-
llcorner
multipars
[
i
+1
]
)
)
=
0
)
and
1264
(
round
(
xpart
(
lrcorner
multipars
[
i
]
-
lrcorner
multipars
[
i
+1
]
)
)
=
0
)
:
1265
multilocs
[
_nofmultipars_
]
:
=
multilocs
[
i
+1
]
;
1266
multirefs
[
_nofmultipars_
]
:
=
multirefs
[
i
+1
]
;
1267
multipars
[
_nofmultipars_
]
:
=
1268
ulcorner
multipars
[
_nofmultipars_
]
--
1269
urcorner
multipars
[
_nofmultipars_
]
--
1270
lrcorner
multipars
[
i
+1
]
--
1271
llcorner
multipars
[
i
+1
]
--
cycle
;
1272
else
:
1273
_nofmultipars_
:
=
_nofmultipars_
+
1
;
1274
multipars
[
_nofmultipars_
]
:
=
multipars
[
i
+1
]
;
1275
multilocs
[
_nofmultipars_
]
:
=
multilocs
[
i
+1
]
;
1276
multirefs
[
_nofmultipars_
]
:
=
multirefs
[
i
+1
]
;
1277
fi
;
1278
endfor
;
1279
nofmultipars
:
=
_nofmultipars_
;
1280
endgroup
;
1281
fi
;
1282
enddef
;
1283 1284
def
draw_multi_pars
=
1285
for
i
=
1
upto
nofmultipars
:
1286
do_draw_par
(
multipars
[
i
]
)
;
1287
if
boxgridtype
=
1
:
1288
draw
baseline_grid
(
multipars
[
i
]
,
if
multilocs
[
i
]
=
1
:
down
else
:
up
fi
,
true
)
;
1289
elseif
boxgridtype
=
2
:
1290
draw
baseline_grid
(
multipars
[
i
]
,
if
multilocs
[
i
]
=
1
:
down
else
:
up
fi
,
false
)
;
1291
elseif
boxgridtype
=
3
:
1292
draw
baseline_grid
(
multipars
[
i
]
,
if
multilocs
[
i
]
=
1
:
down
else
:
up
fi
,
true
)
;
1293
draw
baseline_grid
(
multipars
[
i
]
,
if
multilocs
[
i
]
=
1
:
down
else
:
up
fi
,
true
)
shifted
(
0
,
ExHeight
)
;
1294
elseif
boxgridtype
=
4
:
1295
draw
baseline_grid
(
multipars
[
i
]
,
if
multilocs
[
i
]
=
1
:
down
else
:
up
fi
,
true
)
shifted
(
0
,
ExHeight
/
2
)
;
1296
elseif
boxgridtype
=
11
:
1297
draw
graphic_grid
(
multipars
[
i
]
,
boxgriddistance
,
boxgriddistance
,
boxgriddistance
/
2
,
boxgriddistance
/
2
)
;
1298
elseif
boxgridtype
=
12
:
1299
draw
graphic_grid
(
multipars
[
i
]
,
boxgriddistance
,
boxgriddistance
,
0
,
0
)
;
1300
fi
;
1301
endfor
;
1302
enddef
;
1303 1304
def
show_multi_pars
=
1305
for
i
=
1
upto
nofmultipars
:
1306
do_show_par
(
multipars
[
i
]
,
6
pt
,
.5
blue
)
;
1307
endfor
;
1308
enddef
;
1309 1310
vardef
do_draw_par
(
expr
p
)
=
1311
if
(
length
p
>
2
)
and
(
bbwidth
(
p
)
>
1
)
and
(
bbheight
(
p
)
>
1
)
:
1312
save
pp
;
path
pp
;
1313
if
(
boxlineradius
>
0
)
and
(
boxlinetype
=
2
)
:
1314
pp
:
=
p
cornered
boxlineradius
;
1315
else
:
1316
pp
:
=
p
;
1317
fi
;
1318
if
boxfilltype
>
0
:
1319
if
boxfilloffset
>
0
:
1320
% temporary hack
1321
begingroup
;
1322
interim
linejoin
:
=
mitered
;
1323
filldraw
pp
boxfilloptions
withpen
pencircle
scaled
(
2
*
boxfilloffset
)
;
1324
endgroup
;
1325
else
:
1326
fill
pp
boxfilloptions
;
1327
fi
;
1328
fi
;
1329
if
boxlinetype
>
0
:
1330
draw
pp
boxlineoptions
withpen
pencircle
scaled
boxlinewidth
;
1331
fi
;
1332
fi
;
1333
enddef
;
1334 1335
vardef
baseline_grid
(
expr
pxy
,
pdir
,
at_baseline
)
=
1336
save
width
;
width
:
=
bbwidth
(
pxy
)
;
1337
save
height
;
height
:
=
bbheight
(
pxy
)
;
1338
if
(
par_line_height
>
0
)
and
(
height
>
1
)
and
(
width
>
1
)
and
(
boxgridwidth
>
0
)
:
1339
save
i
,
grid
,
bb
;
picture
grid
;
pair
start
;
path
bb
;
1340
def
_do_
(
expr
start
)
=
1341
% 1 = normal, 2 = with background (i.e. no shine-through)
1342
if
boxdashtype
=
2
:
1343
draw
start
--
start
shifted
(
width
,
0
)
1344
withpen
pencircle
scaled
boxgridwidth
1345
boxfilloptions
;
1346
fi
;
1347
draw
start
--
start
shifted
(
width
,
0
)
1348
if
boxdashtype
>
0
:
1349
dashed
evenly
1350
fi
1351
withpen
pencircle
scaled
boxgridwidth
1352
boxgridoptions
;
1353
enddef
;
1354
grid
:
=
image
(
% fails with inlinespace
1355
if
pdir
=
up
:
1356
for
i
=
if
at_baseline
:
par_strut_depth
else
:
0
fi
step
par_line_height
until
max
(
height
,
par_line_height
)
:
1357
_do_
(
llcorner
pxy
shifted
(
0
,
+
i
)
)
;
1358
endfor
;
1359
else
:
1360
for
i
=
if
at_baseline
:
par_strut_height
else
:
0
fi
step
par_line_height
until
height
:
1361
_do_
(
ulcorner
pxy
shifted
(
0
,
-
i
)
)
;
1362
endfor
;
1363
fi
;
1364
)
;
1365
clip
grid
to
pxy
;
1366
bb
:
=
boundingbox
grid
;
1367
grid
:
=
grid
shifted
(
0
,
boxgridshift
)
;
1368
setbounds
grid
to
bb
;
1369
grid
1370
else
:
1371
nullpicture
1372
fi
1373
enddef
;
1374 1375
vardef
graphic_grid
(
expr
pxy
,
dx
,
dy
,
x
,
y
)
=
1376
if
(
bbheight
(
pxy
)
>
dy
)
and
(
bbwidth
(
pxy
)
>
dx
)
and
(
boxgridwidth
>
0
)
:
1377
save
grid
;
picture
grid
;
1378
grid
:
=
image
(
1379
for
i
=
xpart
llcorner
pxy
step
dx
until
xpart
lrcorner
pxy
:
1380
draw
(
i
,
ypart
llcorner
pxy
)
--
(
i
,
ypart
ulcorner
pxy
)
withpen
pencircle
scaled
boxgridwidth
;
1381
endfor
;
1382
for
i
=
ypart
llcorner
pxy
step
dy
until
ypart
ulcorner
pxy
:
1383
draw
(
xpart
llcorner
pxy
,
i
)
--
(
xpart
lrcorner
pxy
,
i
)
withpen
pencircle
scaled
boxgridwidth
;
1384
endfor
1385
)
shifted
(
x
,
y
)
;
1386
clip
grid
to
pxy
;
1387
grid
1388
else
:
1389
nullpicture
1390
fi
1391
enddef
;
1392 1393
def
anchor_box
(
expr
n
,
x
,
y
,
w
,
h
,
d
)
=
1394
currentpicture
:
=
currentpicture
shifted
(
-
x
,
-
y
)
;
1395
enddef
;
1396 1397
let
draw_area
=
draw_box
;
1398
let
anchor_area
=
anchor_box
;
1399
let
anchor_par
=
anchor_box
;
1400 1401
numeric
sync_n
[
]
,
sync_p
[
]
[
]
,
sync_w
[
]
[
]
,
sync_h
[
]
[
]
,
sync_d
[
]
[
]
,
sync_t
[
]
[
]
;
1402
pair
sync_xy
[
]
[
]
;
color
sync_c
[
]
[
]
;
1403 1404
def
ResetSyncTasks
=
1405
path
SyncPaths
[
]
;
numeric
SyncTasks
[
]
,
NOfSyncPaths
,
CurrentSyncClass
;
1406
NOfSyncPaths
:
=
CurrentSyncClass
:
=
0
;
1407
if
unknown
SyncLeftOffset
:
numeric
SyncLeftOffset
;
SyncLeftOffset
:
=
0
;
fi
;
1408
if
unknown
SyncWidth
:
numeric
SyncWidth
;
SyncWidth
:
=
0
;
fi
;
1409
if
unknown
SyncThreshold
:
numeric
SyncThreshold
;
SyncThreshold
:
=
LineHeight
;
fi
;
1410
if
unknown
SyncColor
:
color
SyncColor
;
SyncColor
:
=
.5
white
;
fi
;
1411
if
(
SyncLeftOffset
=
0
)
and
(
SyncWidth
=
0
)
:
1412
SyncWidth
:
=
if
known
TextWidth
:
TextWidth
else
:
-1
cm
fi
;
1413
fi
;
1414
enddef
;
1415 1416
ResetSyncTasks
;
1417 1418
vardef
SyncBox
(
expr
n
,
i
,
leftoffset
,
width
,
topoffset
,
bottomoffset
)
=
1419
save
o
;
pair
o
;
o
:
=
(
xpart
llcorner
PlainTextArea
,
ypart
sync_xy
[
n
]
[
i
]
)
;
1420
o
shifted
(
leftoffset
,
sync_h
[
n
]
[
i
]
+
topoffset
)
--
1421
o
shifted
(
width
+
leftoffset
,
sync_h
[
n
]
[
i
]
+
topoffset
)
--
1422
o
shifted
(
width
+
leftoffset
,
bottomoffset
)
--
1423
o
shifted
(
leftoffset
,
bottomoffset
)
--
cycle
1424
enddef
;
1425 1426
def
SetSyncColor
(
expr
n
,
i
,
c
)
=
1427
sync_c
[
n
]
[
i
]
:
=
c
;
1428
enddef
;
1429 1430
def
SetSyncThreshold
(
expr
n
,
i
,
th
)
=
1431
sync_th
[
n
]
[
i
]
:
=
th
;
1432
enddef
;
1433 1434
vardef
TheSyncColor
(
expr
n
,
i
)
=
1435
if
known
sync_c
[
n
]
[
i
]
:
sync_c
[
n
]
[
i
]
else
:
SyncColor
fi
1436
enddef
;
1437 1438
vardef
TheSyncThreshold
(
expr
n
,
i
)
=
1439
if
known
sync_th
[
n
]
[
i
]
:
sync_th
[
n
]
[
i
]
else
:
SyncThreshold
fi
1440
enddef
;
1441 1442
vardef
PrepareSyncTasks
(
expr
n
,
collapse
,
extendtop
,
prestartnext
)
=
1443
ResetSyncTasks
;
1444
if
known
sync_n
[
n
]
:
1445
CurrentSyncClass
:
=
n
;
1446
save
ok
,
l
,
d
;
boolean
ok
;
ok
:
=
false
;
NOfSyncPaths
:
=
l
:
=
0
;
1447
for
i
=
1
upto
sync_n
[
n
]
:
1448
if
RealPageNumber
>
sync_p
[
n
]
[
i
]
:
1449
l
:
=
i
;
1450
elseif
RealPageNumber
=
sync_p
[
n
]
[
i
]
:
1451
NOfSyncPaths
:
=
NOfSyncPaths
+
1
;
1452
if
not
ok
:
1453
if
i
>
1
:
1454
if
sync_t
[
n
]
[
i
-1
]
=
sync_t
[
n
]
[
i
]
:
1455
SyncPaths
[
NOfSyncPaths
]
:
=
SyncBox
(
n
,
i
,
SyncLeftOffset
,
SyncWidth
,
PaperHeight
,
-
PaperHeight
)
;
1456
SyncTasks
[
NOfSyncPaths
]
:
=
i
;
1457
else
:
1458
SyncPaths
[
NOfSyncPaths
]
:
=
SyncBox
(
n
,
i
-1
,
SyncLeftOffset
,
SyncWidth
,
PaperHeight
,
-
PaperHeight
)
;
1459
SyncTasks
[
NOfSyncPaths
]
:
=
i
-1
;
1460
NOfSyncPaths
:
=
NOfSyncPaths
+
1
;
1461
SyncPaths
[
NOfSyncPaths
]
:
=
SyncBox
(
n
,
i
,
SyncLeftOffset
,
SyncWidth
,
0
,
-
PaperHeight
)
;
1462
SyncTasks
[
NOfSyncPaths
]
:
=
i
;
1463
fi
;
1464
else
:
1465
SyncPaths
[
NOfSyncPaths
]
:
=
SyncBox
(
n
,
i
,
SyncLeftOffset
,
SyncWidth
,
0
,
-
PaperHeight
)
;
1466
SyncTasks
[
NOfSyncPaths
]
:
=
i
;
1467
fi
;
1468
else
:
1469
SyncPaths
[
NOfSyncPaths
]
:
=
SyncBox
(
n
,
i
,
SyncLeftOffset
,
SyncWidth
,
0
,
-
PaperHeight
)
;
1470
SyncTasks
[
NOfSyncPaths
]
:
=
i
;
1471
fi
;
1472
ok
:
=
true
;
1473
fi
;
1474
endfor
;
1475
if
(
NOfSyncPaths
=
0
)
and
(
l
>
0
)
:
1476
NOfSyncPaths
:
=
1
;
1477
SyncPaths
[
NOfSyncPaths
]
:
=
SyncBox
(
n
,
l
,
SyncLeftOffset
,
SyncWidth
,
PaperHeight
,
-
PaperHeight
)
;
1478
SyncTasks
[
NOfSyncPaths
]
:
=
l
;
1479
fi
;
1480
if
NOfSyncPaths
>
0
:
1481
for
i
=
1
upto
NOfSyncPaths
-1
:
1482
SyncPaths
[
i
]
:
=
topboundary
SyncPaths
[
i
]
--
reverse
topboundary
SyncPaths
[
i
+1
]
--
cycle
;
1483
endfor
;
1484
if
unknown
SyncThresholdMethod
:
1485
numeric
SyncThresholdMethod
;
SyncThresholdMethod
:
=
2
;
1486
fi
;
1487
if
extendtop
:
1488
if
SyncThresholdMethod
=
1
:
1489
if
NOfSyncPaths
>
1
:
1490
d
:
=
ypart
(
ulcorner
PlainTextArea
-
sync_xy
[
n
]
[
SyncTasks
[
2
]
]
)
;
1491
if
(
SyncTasks
[
2
]
>
1
)
and
(
d
>
0
pt
)
and
(
d
<
=
TheSyncThreshold
(
n
,
sync_t
[
n
]
[
SyncTasks
[
2
]
]
)
)
and
(
sync_p
[
n
]
[
SyncTasks
[
2
]
]
=
RealPageNumber
)
:
1492
SyncPaths
[
2
]
:
=
SyncPaths
[
2
]
topenlarged
PaperHeight
;
1493
fi
;
1494
fi
;
1495
else
:
1496
for
i
=
1
upto
NOfSyncPaths
:
1497
d
:
=
ypart
(
ulcorner
PlainTextArea
-
sync_xy
[
n
]
[
SyncTasks
[
i
]
]
)
;
1498
if
(
d
>
0
)
and
(
d
<
=
TheSyncThreshold
(
n
,
sync_t
[
n
]
[
SyncTasks
[
i
]
]
)
)
and
(
sync_p
[
n
]
[
SyncTasks
[
i
]
]
=
RealPageNumber
)
:
1499
SyncPaths
[
i
]
:
=
SyncPaths
[
i
]
topenlarged
PaperHeight
;
1500
fi
;
1501
endfor
;
1502
fi
;
1503
fi
;
1504
if
prestartnext
:
1505
if
NOfSyncPaths
>
1
:
1506
if
SyncTasks
[
NOfSyncPaths
]
<
sync_n
[
n
]
:
% there is a next one
1507
d
:
=
ypart
(
ulcorner
PlainTextArea
-
sync_xy
[
n
]
[
SyncTasks
[
NOfSyncPaths
]
+1
]
)
;
1508
if
(
d
>
0
)
and
(
d
<
=
TheSyncThreshold
(
n
,
sync_t
[
n
]
[
SyncTasks
[
i
]
]
)
)
and
(
sync_p
[
n
]
[
SyncTasks
[
NOfSyncPaths
]
+1
]
=
RealPageNumber
+1
)
:
1509
SyncPaths
[
NOfSyncPaths
+1
]
:
=
1510
(
xpart
ulcorner
SyncPaths
[
NOfSyncPaths
]
,
ypart
llcorner
PlainTextArea
)
--
1511
(
xpart
urcorner
SyncPaths
[
NOfSyncPaths
]
,
ypart
llcorner
PlainTextArea
)
--
1512
lrcorner
SyncPaths
[
NOfSyncPaths
]
--
1513
llcorner
SyncPaths
[
NOfSyncPaths
]
--
cycle
;
1514
SyncTasks
[
NOfSyncPaths
+1
]
:
=
SyncTasks
[
NOfSyncPaths
]
+1
;
1515
NOfSyncPaths
:
=
NOfSyncPaths
+
1
;
1516
fi
;
1517
fi
;
1518
fi
;
1519
else
:
1520
if
NOfSyncPaths
>
1
:
1521
d
:
=
ypart
(
sync_xy
[
n
]
[
SyncTasks
[
NOfSyncPaths
]
]
-
llcorner
PlainTextArea
)
;
1522
if
(
d
<
TheSyncThreshold
(
n
,
SyncTasks
[
NOfSyncPaths
]
)
)
:
1523
NOfSyncPaths
:
=
NOfSyncPaths
-
1
;
1524
SyncPaths
[
NOfSyncPaths
]
:
=
SyncPaths
[
NOfSyncPaths
]
bottomenlarged
PaperHeight
;
1525
fi
;
1526
fi
;
1527
fi
;
1528
if
(
NOfSyncPaths
>
1
)
and
collapse
:
1529
save
j
;
numeric
j
;
j
:
=
1
;
1530
for
i
=
2
upto
NOfSyncPaths
:
1531
if
sync_t
[
n
]
[
SyncTasks
[
i
]
]
=
sync_t
[
n
]
[
SyncTasks
[
j
]
]
:
1532
SyncPaths
[
j
]
:
=
boundingbox
image
(
draw
SyncPaths
[
i
]
;
draw
SyncPaths
[
j
]
;
)
;
1533
SyncTasks
[
j
]
:
=
SyncTasks
[
i
]
;
1534
else
:
1535
j
:
=
j
+
1
;
1536
SyncPaths
[
j
]
:
=
SyncPaths
[
i
]
;
1537
SyncTasks
[
j
]
:
=
SyncTasks
[
i
]
;
1538
fi
;
1539
endfor
;
1540
NOfSyncPaths
:
=
j
;
1541
fi
;
1542
fi
;
1543
fi
;
1544
enddef
;
1545 1546
def
SyncTask
(
expr
n
)
=
1547
if
known
SyncTasks
[
n
]
:
SyncTasks
[
n
]
else
:
0
fi
1548
enddef
;
1549 1550
def
FlushSyncTasks
=
1551
for
i
=
1
upto
NOfSyncPaths
:
1552
ProcessSyncTask
(
SyncPaths
[
i
]
,
TheSyncColor
(
CurrentSyncClass
,
sync_t
[
CurrentSyncClass
]
[
SyncTasks
[
i
]
]
)
)
;
1553
endfor
;
1554
enddef
;
1555 1556
def
ProcessSyncTask
(
expr
p
,
c
)
=
1557
fill
p
withcolor
c
;
1558
enddef
;
1559