1
2
3
4
5
6
7
8
9
10
11
12
13
14if known context_core : endinput ; fi ;
15
16boolean context_core ; context_core := true ;
17
18
19
20if unknown NOfTextColumns : numeric NOfTextColumns ; NOfTextColumns := 1 ; fi ;
21if unknown NOfTextAreas : numeric NOfTextAreas ; NOfTextAreas := 1 ; fi ;
22
23def 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 ;
36enddef ;
37
38def 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 ;
44enddef ;
45
46ResetTextAreas ; SaveTextAreas ; ;
47
48def RegisterTextArea (expr x, y, w, h, d) =
49 begingroup ;
50 save p ; path p ;
51 p := unitsquare xyscaled(w,hd) shifted (x,yd) ;
52 if NOfTextAreas>0 :
53
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 ;
84enddef ;
85
86
87
88def RegisterPlainTextArea(expr x,y,w,h,d) =
89 PlainTextArea := unitsquare xyscaled(w,hd) shifted (x,yd) ;
90enddef ;
91
92def RegisterRegionTextArea(expr x,y,w,h,d) =
93 RegionTextArea := unitsquare xyscaled(w,hd) shifted (x,yd) ;
94
95enddef ;
96
97def RegisterLocalTextArea (expr x, y, w, h, d) =
98 TextAreas[0] := TextColumns[0] := unitsquare xyscaled(w,hd) shifted (x,yd) ;
99enddef ;
100
101def ResetLocalTextArea =
102 TextAreas[0] := TextColumns[0] := origin -- cycle ;
103enddef ;
104
105ResetLocalTextArea ;
106
107vardef 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_]))
112enddef ;
113
114vardef 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_]))
119enddef ;
120
121vardef InsideSomeTextArea (expr _xy_) =
122 save ok ; boolean ok ; ok := false ;
123 for i := 1 upto NOfTextAreas :
124 if InsideTextArea(i,_xy_) :
125 ok := true ;
126 fi ;
127 exitif ok ;
128 endfor ;
129 ok
130enddef ;
131
132vardef 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
141enddef ;
142
143vardef 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_
152enddef ;
153
154vardef 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_
163enddef ;
164
165vardef 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_
176enddef ;
177
178vardef 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_
187enddef ;
188
189vardef 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_
198enddef ;
199
200vardef 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_
211enddef ;
212
213
214
215pair lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ;
216path pxy[] ;
217numeric hxy[], wxy[], dxy[], nxy[] ;
218
219def 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))
221enddef ;
222
223def 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,yd) ;
228 lrxy := (xw,yd) ;
229 urxy := (xw,yh) ;
230 ulxy := (x,yh) ;
231 wxy := w ;
232 hxy := h ;
233 dxy := d ;
234 rxy := lxy shifted (wxy,0) ;
235 pxy := llxylrxyurxyulxycycle ;
236 cxy := center pxy ;
237 nxy := n ;
238 freeze_box(pos) ;
239enddef ;
240
241def 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 ;
254enddef ;
255
256def initialize_box (expr n,x,y,w,h,d) =
257 numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ;
258enddef ;
259
260def 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) ;
265enddef ;
266
267def 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 := llxylrxyurxyulxycycle ;
278 cxy := center pxy ;
279enddef ;
280
281def set_par_line_height (expr ph, pd) =
282 par_strut_height := if ph>0 : ph elseif StrutHeight>0 : StrutHeight else : 8pt fi ;
283 par_strut_depth := if pd>0 : pd elseif StrutDepth >0 : StrutDepth else : 3pt fi ;
284 par_line_height := par_strut_height par_strut_depth ;
285enddef ;
286
287def 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
305enddef ;
306
307def 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,wxww,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
328enddef ;
329
330def do_initialize_par (expr fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) =
331
332 pair lref, rref, pref, lhref, rhref ;
333
334
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
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
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
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
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
377 boxgriddirection := up ;
378 fi ;
379
380 path txy, bxy, pxy, mxy ;
381
382 txy := originpath ;
383 bxy := originpath ;
384 pxy := originpath ;
385
386 boolean lefthang, righthang, somehang ;
387
388
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,rapar_line_height)) ;
398 elseif righthang :
399 mxy := boundingbox (rref -- rref shifted (rh,rapar_line_height)) ;
400 else :
401 mxy := originpath ;
402 fi ;
403
404 if round(ypart llxy[fpos]) = round(ypart llxy[tpos]) :
405
406
407
408
409 llxy[fpos] := (xpart llxy[fpos], ypart llxy[tpos]) ;
410 ulxy[fpos] := (xpart ulxy[fpos], ypart ulxy[tpos]) ;
411
412 else :
413
414
415
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
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
448
449
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
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
465
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
483
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
500
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
514enddef ;
515
516pair last_multi_par_shift ; last_multi_par_shift := origin ;
517
518def 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 ;
523enddef ;
524
525boolean compensate_multi_par_topskip ;
526boolean span_multi_column_pars ;
527boolean auto_multi_par_hsize ;
528boolean enable_multi_par_fallback ;
529
530compensate_multi_par_topskip := true ;
531span_multi_column_pars := false ;
532auto_multi_par_hsize := false ;
533enable_multi_par_fallback := true ;
534
535vardef multi_par_at_top (expr i) =
536 (round (ypart ulcorner multipars[i]) = round (ypart ulcorner (TextAreas[multirefs[i]] shifted last_multi_par_shift)))
537enddef ;
538
539numeric nofmultipars ; nofmultipars := 0 ;
540
541boolean obey_multi_par_hang ; obey_multi_par_hang := true ;
542boolean obey_multi_par_more ; obey_multi_par_more := true ;
543boolean snap_multi_par_tops ; snap_multi_par_tops := true ;
544boolean local_multi_par_area ; local_multi_par_area := false ;
545boolean use_multi_par_region ; use_multi_par_region := false ;
546boolean ignore_multi_par_page ; ignore_multi_par_page := false ;
547boolean force_multi_par_chain ; force_multi_par_chain := true ;
548boolean one_piece_multi_par ; one_piece_multi_par := false ;
549boolean check_multi_par_chain ; check_multi_par_chain := true ;
550
551boolean multi_column_first_page_hack; multi_column_first_page_hack := true ;
552
553def simplify_multi_pars =
554 for i := 1 upto nofmultipars :
555 multipars[i] := boundingbox multipars[i] ;
556 endfor ;
557enddef ;
558
559def save_multipar (expr i, l, p) =
560 nofmultipars := nofmultipars 1 ;
561 multirefs[nofmultipars] := i ;
562 multilocs[nofmultipars] := l ;
563 multipars[nofmultipars] := unspiked (simplified p) ;
564enddef ;
565
566def 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
573
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
588
589
590
591
592
593
594
595
596
597
598
599
600
601
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 ;
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[] ;
659
660 numeric multi_par_pages ; multi_par_pages := nxy[tpos]nxy[fpos]+1 ;
661
662
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(hpar_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
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_(pyfy) ;
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_afterpar_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_(pyfy) ;
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_afterpar_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_afterpar_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_afterpar_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_afterpar_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_afterpar_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_afterpar_line_height) ;
862 _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ;
863 _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ;
864
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_afterpar_line_height) ;
882 _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ;
883 _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ;
884
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
896
897
898
899
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
907
908
909
910
911
912
913
914
915
916
917
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
930
931 for i=1 upto NOfTextAreas :
932
933 TopSkipCorrection := 0 ;
934
935 multipar := _pmp_set_multipar_(i) ;
936
937
938
939 if (nxy[fpos]=RealPageNumber) and (InsideTextArea(i,par_start_pos)) :
940
941
942
943 ii := i ;
944
945 if (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) :
946
947
948
949 nn := i ;
950
951 if compensate_multi_par_topskip and (round(LineHeightphpd)=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
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
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
1111 fi ;
1112
1113 endfor ;
1114
1115
1116
1117
1118 if force_multi_par_chain or (ii > 1) :
1119
1120 for i=ii+1 upto nn-1 :
1121
1122
1123
1124
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
1150
1151 fi ;
1152
1153 if span_multi_column_pars :
1154 endgroup ;
1155 fi ;
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167 one_piece_multi_par := (nofmultipars=1) and (pn=tn) ;
1168
1169enddef ;
1170
1171def boxgridoptions = withcolor .8red enddef ;
1172def boxlineoptions = withcolor .8blue enddef ;
1173def boxfilloptions = withcolor .8white enddef ;
1174
1175numeric boxgridtype ; boxgridtype := 0 ;
1176numeric boxlinetype ; boxlinetype := 1 ;
1177numeric boxfilltype ; boxfilltype := 1 ;
1178numeric boxdashtype ; boxdashtype := 0 ;
1179pair boxgriddirection ; boxgriddirection := up ;
1180numeric boxgridwidth ; boxgridwidth := 1pt ;
1181numeric boxlinewidth ; boxlinewidth := 1pt ;
1182numeric boxlineradius ; boxlineradius := 0pt ;
1183numeric boxfilloffset ; boxfilloffset := 0pt ;
1184numeric boxgriddistance ; boxgriddistance := .5cm ;
1185numeric boxgridshift ; boxgridshift := 0pt ;
1186
1187
1188
1189
1190
1191
1192def draw_par =
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,ExHeight2) boxgridoptions ;
1208 elseif boxgridtype = 11 :
1209 draw graphic_grid(i,boxgriddistance,boxgriddistance,boxgriddistance2,boxgriddistance2) ;
1210 elseif boxgridtype = 12 :
1211 draw graphic_grid(i,boxgriddistance,boxgriddistance,0,0) ;
1212 fi ;
1213 endfor ;
1214enddef ;
1215
1216def 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 .5pt withcolor c ;
1220 endfor ;
1221 fi ;
1222 draw p withpen pencircle scaled .5pt withcolor c ;
1223enddef ;
1224
1225def show_par =
1226 if length(mxy) > 2 :
1227 draw mxy dashed evenly withpen pencircle scaled .5pt withcolor .5white ;
1228 fi ;
1229 do_show_par(txy, 4pt, .5green) ;
1230 do_show_par(bxy, 6pt, .5blue ) ;
1231 do_show_par(pxy, 8pt, .5red ) ;
1232 draw pref withpen pencircle scaled 2pt ;
1233enddef ;
1234
1235def 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 ;
1254enddef ;
1255
1256def collapse_multi_pars =
1257 if nofmultipars>1 :
1258 begingroup ;
1259 save _nofmultipars_ ; numeric _nofmultipars_ ;
1260 _nofmultipars_ := 1 ;
1261 sort_multi_pars ;
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 ;
1282enddef ;
1283
1284def 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,ExHeight2) ;
1296 elseif boxgridtype=11 :
1297 draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance2,boxgriddistance2) ;
1298 elseif boxgridtype=12 :
1299 draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ;
1300 fi ;
1301 endfor ;
1302enddef ;
1303
1304def show_multi_pars =
1305 for i=1 upto nofmultipars :
1306 do_show_par(multipars[i], 6pt, .5blue) ;
1307 endfor ;
1308enddef ;
1309
1310vardef 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
1321 begingroup ;
1322 interim linejoin := mitered ;
1323 filldraw pp boxfilloptions withpen pencircle scaled (2boxfilloffset) ;
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 ;
1333enddef ;
1334
1335vardef 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
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 (
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
1373enddef ;
1374
1375vardef 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
1391enddef ;
1392
1393def anchor_box (expr n,x,y,w,h,d) =
1394 currentpicture := currentpicture shifted (x,y) ;
1395enddef ;
1396
1397let draw_area = draw_box ;
1398let anchor_area = anchor_box ;
1399let anchor_par = anchor_box ;
1400
1401numeric sync_n[], sync_p[][], sync_w[][], sync_h[][], sync_d[][], sync_t[][] ;
1402pair sync_xy[][] ; color sync_c[][] ;
1403
1404def 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 := .5white ; fi ;
1411 if (SyncLeftOffset = 0) and (SyncWidth = 0) :
1412 SyncWidth := if known TextWidth : TextWidth else : -1cm fi ;
1413 fi ;
1414enddef ;
1415
1416ResetSyncTasks ;
1417
1418vardef 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 (widthleftoffset,sync_h[n][i]topoffset) --
1422 o shifted (widthleftoffset,bottomoffset) --
1423 o shifted (leftoffset,bottomoffset) -- cycle
1424enddef ;
1425
1426def SetSyncColor(expr n, i, c) =
1427 sync_c[n][i] := c ;
1428enddef ;
1429
1430def SetSyncThreshold(expr n, i, th) =
1431 sync_th[n][i] := th ;
1432enddef ;
1433
1434vardef TheSyncColor(expr n, i) =
1435 if known sync_c[n][i] : sync_c[n][i] else : SyncColor fi
1436enddef ;
1437
1438vardef TheSyncThreshold(expr n, i) =
1439 if known sync_th[n][i] : sync_th[n][i] else : SyncThreshold fi
1440enddef ;
1441
1442vardef 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 > 0pt) 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] :
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 ;
1544enddef ;
1545
1546def SyncTask(expr n) =
1547 if known SyncTasks[n] : SyncTasks[n] else : 0 fi
1548enddef ;
1549
1550def FlushSyncTasks =
1551 for i = 1 upto NOfSyncPaths :
1552 ProcessSyncTask(SyncPaths[i], TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]])) ;
1553 endfor ;
1554enddef ;
1555
1556def ProcessSyncTask(expr p, c) =
1557 fill p withcolor c ;
1558enddef ;
1559 |