1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16if known context_text : endinput ; fi ;
17
18boolean context_text ; context_text := true ;
19
20def build_parshape (expr p, offset_or_path, dx, dy, baselineskip, strutheight, strutdepth, topskip) =
21
22 if unknown trace_parshape :
23 boolean trace_parshape ; trace_parshape := false ;
24 fi ;
25
26 begingroup ;
27
28 save
29 q, l, r, line, tt, bb,
30 n, hsize, vsize, vvsize, voffset, hoffset, width, indent,
31 ll, lll, rr, rrr, cp, cq, t, b ;
32
33 path
34 q, l, r, line, tt, bb ;
35 numeric
36 n, hsize, vsize, vvsize, voffset, hoffset, width[], indent[] ;
37 pair
38 ll, lll, rr, rrr, cp, cq, t, b ;
39
40 n := 0 ;
41 cp := center p ;
42
43 if path offset_or_path :
44 q := offset_or_path ;
45 cq := center q ;
46 voffset := dy ;
47 hoffset := dx ;
48 else :
49 q := p ;
50 cq := center q ;
51 hoffset := offset_or_path dx ;
52 voffset := offset_or_path dy ;
53 fi ;
54
55 hsize := xpart lrcorner q xpart llcorner q ;
56 vsize := ypart urcorner q ypart lrcorner q ;
57
58 q := p shifted cp ;
59
60 startsavingdata ;
61
62 savedata "\global\parvoffset " & decimal voffset & "bp " ;
63 savedata "\global\parhoffset " & decimal hoffset & "bp " ;
64 savedata "\global\parwidth " & decimal hsize & "bp " ;
65 savedata "\global\parheight " & decimal vsize & "bp " ;
66
67 if not path offset_or_path :
68 q := q xscaled ((hsize-2hoffset)hsize) yscaled ((vsize-2voffset)vsize) ;
69 fi ;
70
71 hsize := xpart lrcorner q xpart llcorner q ;
72 vsize := ypart urcorner q ypart lrcorner q ;
73
74 t := (ulcorner q -- urcorner q) intersection_point q ;
75 b := (llcorner q -- lrcorner q) intersection_point q ;
76
77 if xpart directionpoint t of q < 0 :
78 q := reverse q ;
79 fi ;
80
81 l := q cutbefore t ;
82 l := l if xpart point 0 of q < 0 : & q fi cutafter b ;
83
84 r := q cutbefore b ;
85 r := r if xpart point 0 of q > 0 : & q fi cutafter t ;
86
87
88
89
90
91
92
93
94
95 if trace_parshape :
96 drawarrow p withpen pencircle scaled 2pt withcolor red ;
97 drawarrow l shifted cp withpen pencircle scaled 1pt withcolor green ;
98 drawarrow r shifted cp withpen pencircle scaled 1pt withcolor blue ;
99 fi ;
100
101 vardef found_point (expr lin, pat, sig) =
102 pair a, b ;
103 a := pat intersection_point (lin shifted (0,strutheight)) ;
104 if intersection_found :
105 a := a shifted (0,strutheight) ;
106 else :
107 a := pat intersection_point lin ;
108 fi ;
109 b := pat intersection_point (lin shifted (0,strutdepth)) ;
110 if intersection_found :
111 if sig :
112 if xpart b > xpart a : a := b shifted (0,strutdepth) fi ;
113 else :
114 if xpart b < xpart a : a := b shifted (0,strutdepth) fi ;
115 fi ;
116 fi ;
117 a
118 enddef ;
119
120 if (strutheightstrutdepth<baselineskip) :
121 vvsize := vsize ;
122 else :
123 vvsize := (vsize div baselineskip) baselineskip ;
124 fi ;
125
126 for i=topskip step baselineskip until vvsize :
127
128 line := (ulcorner q -- urcorner q) shifted (0,ieps) ;
129
130 ll := found_point(line,l,true ) ;
131 rr := found_point(line,r,false) ;
132
133 if trace_parshape :
134 fill (llrrrr shifted (0,strutheight)ll shifted (0,strutheight)cycle) shifted cp withcolor .5white ;
135 fill (llrrrr shifted (0,strutdepth)ll shifted (0,strutdepth)cycle) shifted cp withcolor .7white ;
136 draw ll shifted cp withpen pencircle scaled 2pt ;
137 draw rr shifted cp withpen pencircle scaled 2pt ;
138 draw (llrr) shifted cp withpen pencircle scaled .5pt ;
139 fi ;
140
141 n := n 1 ;
142 indent[n] := abs(xpart ll xpart llcorner q) ;
143 width[n] := abs(xpart rr xpart ll) ;
144
145 if (i=strutheight) and (width[n]<baselineskip) :
146 n := n 1 ;
147 savedata "\global\parfirst\plusone " ;
148 fi ;
149
150 endfor ;
151
152 savedata "\global\parlines " & decimal n ;
153 savedata "\global\partoks{ " ;
154 for i=1 upto n:
155 savedata decimal indent[i]&"bp " & decimal width[i]&"bp " ;
156 endfor ;
157 savedata "}" ;
158
159 stopsavingdata ;
160
161 endgroup ;
162
163enddef ;
164 |