1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26\unprotect
27
28\definesystemvariable { sh }
29
30\unexpanded \def \setupshapetexts
31 { \dodoubleempty\getparameters [ \??sh ] }
32
33\setupshapetexts
34 [ \c!bodyfont =]
35
36\startMPextensions
37 loadmodule " text " ;
38\stopMPextensions
39
40\ifdefined \parwidth \else
41 \newdimen \parwidth
42 \newdimen \parheight
43 \newdimen \parvoffset
44 \newdimen \parhoffset
45 \newcount \parlines
46 \newtoks \partoks
47 \newbox \shapetextbox
48 \newcount \parfirst
49\fi
50
51\unexpanded \def \startshapetext [# 1 ]
52 { \global \newcounter \currentshapetext
53 \global\setbox \shapetextbox \vbox \bgroup
54 \switchtobodyfont [ \@@shbodyfont ]
55 \dontcomplain
56 \hsize \parwidth
57 \setuptolerance [ \v!verytolerant , \v!stretch ]
58 \scratchcounter \zerocount
59 \scratchtoks \emptytoks
60 \def \docommand ## 1
61 { \setbox \scratchbox \hpack { \useMPgraphic { ##1 } }
62 \global \parfirst \zerocount
63 \getMPdata
64 \setshapecharacteristics
65 \advance \scratchcounter by \parlines
66 \expandafter \appendtoks \the \partoks \to\scratchtoks }
67 \processcommalist [# 1 ] \docommand
68 \xdef \totalparlines { \the \scratchcounter }
69 \global \partoks \scratchtoks
70 \parshape \the \scratchcounter \the \scratchtoks \relax
71 \setshapecharacteristics
72 \def\par { \endgraf \adaptparshape }
73 \everypar { \begstrut }}
74
75\unexpanded \def \stopshapetext
76 { \endstrut
77 \egroup
78 \global \newcounter \currentshapetext
79 \getshapecharacteristics }
80
81\unexpanded \def \adaptparshape
82 { \def \docommand ## 1
83 { \ifcase \scratchcounter
84 \expandafter \appendtoks\space ## 1 \to\scratchtoks
85 \else
86 \advance \scratchcounter \minusone
87 \fi }
88 \scratchcounter \prevgraf
89 \doglobal \decrement ( \totalparlines , \scratchcounter )
90 \multiply \scratchcounter \plustwo
91 \scratchtoks \emptytoks
92 \expanded { \processseparatedlist [ \the \partoks ][ \space ] } \docommand
93 \global \partoks \scratchtoks
94 \parshape \totalparlines \the \partoks \relax }
95
96\unexpanded \def \getshapecharacteristics
97 { \doglobal \increment \currentshapetext
98 \doifelsedefined { parlines : \currentshapetext }
99 { \getvalue { parlines : \currentshapetext }}
100 { \global \parlines \plusone
101 \global \parfirst \zerocount
102 \global \parvoffset \zeropoint
103 \global \parhoffset \zeropoint
104 \global \parwidth \hsize
105 \global \parheight \vsize }}
106
107\unexpanded \def \setshapecharacteristics
108 { \doglobal \increment \currentshapetext
109 \setxvalue { parlines : \currentshapetext }
110 { \global \parlines \the \parlines
111 \global \parfirst \the \parfirst
112 \global \parvoffset \the \parvoffset
113 \global \parhoffset \the \parhoffset
114 \global \parwidth \the \parwidth
115 \global \parheight \the \parheight }}
116
117\unexpanded \def \getshapetext
118 { \vbox \bgroup
119 \forgetall
120 \dontcomplain
121 \setbox \scratchbox \vbox to \parheight
122 { \switchtobodyfont [ \@@shbodyfont ]
123 \splittopskip \strutheight
124 \vskip \parvoffset
125 \ifcase \parfirst \else\vskip \lineheight \fi
126 \hskip \parhoffset
127 \hbox { \vsplit \shapetextbox to \parlines \lineheight }}
128 \wd \scratchbox \parwidth
129 \ht \scratchbox \parheight
130 \dp \scratchbox \zeropoint
131 \box \scratchbox
132 \getshapecharacteristics
133 \egroup }
134
135\doifundefined { RotFont }{ \definefont [ RotFont ][ RegularBold * default ] }
136
137\unexpanded \def \getfollowtoken # 1
138 { \hbox \bgroup
139 \strut
140 \ctxlua{ mp . follow_text ( # 1 ) }
141 \egroup }
142
143\definefontfeature [ mp : tp ][ liga = no ]
144
145\startMPdefinitions
146 def mfun_follow_draw ( expr alternative ) =
147 if unknown RotPath : path RotPath ; RotPath : = origin ; fi ;
148
149 if unknown TraceRot : boolean TraceRot ; TraceRot : = false ; fi ;
150 if unknown ExtraRot : numeric ExtraRot ; ExtraRot : = 0 ; fi ;
151 picture pic [ ] ;
152 numeric len [ ] ; len [ 0 ] : = 0 ;
153 numeric n ; n : = lua.mp.follow_size ( ) ;
154 for i = 1 upto n :
155 pic [ i ] : = lua.mp.follow_slot ( i ) ;
156 pic [ i ] : = pic [ i ] shifted llcorner pic [ i ] ;
157 len [ i ] : = len [ i -1 ] lua.mp.follow_width ( i ) ;
158 endfor ;
159 numeric al , at , pl , pc , wid , pos ; pair ap , ad ;
160 al : = arclength RotPath ;
161 if al = 0 :
162 al : = len [ n ] ExtraRot ;
163 RotPath : = origin -- ( al , 0 ) ;
164 fi ;
165 if al < len [ n ] :
166 RotPath : = RotPath scaled ( ( len [ n ] ExtraRot ) al ) ;
167 al : = arclength RotPath ;
168 fi ;
169 if alternative = 1 :
170 pl : = ( al len [ n ] ) ( if n > 1 : ( n -1 ) else : 1 fi ) ;
171 pc : = 0 ;
172 else :
173 pl : = 0 ;
174 pc : = arclength RotPath 2 len [ n ] 2 ;
175 fi ;
176 if TraceRot :
177 draw RotPath withpen pencircle scaled 1 pt withcolor blue ;
178 fi ;
179 for i = 1 upto n :
180
181 wid : = lua.mp.follow_width ( i ) ;
182 pos : = len [ i ] wid 2 ( i -1 ) pl pc ;
183 at : = arctime pos of RotPath ;
184 ap : = point at of RotPath ;
185 ad : = direction at of RotPath ;
186 if mfun_trial_run :
187
188
189 else :
190 pic [ i ] : = pic [ i ] shifted ( wid 2 , 0 ) rotated ( angle ( ad ) ) shifted ap ;
191 draw pic [ i ] ;
192 if TraceRot :
193 draw boundingbox pic [ i ] withpen pencircle scaled .25 pt withcolor red ;
194 draw ap withpen pencircle scaled .50 pt withcolor green ;
195 fi ;
196 fi ;
197 endfor ;
198 if TraceRot :
199 draw boundingbox currentpicture withpen pencircle scaled .25 pt withcolor blue ;
200 fi ;
201 enddef ;
202\stopMPdefinitions
203
204\startluacode
205 local context = context
206
207 local nodecodes = nodes . nodecodes
208 local kerncodes = nodes . kerncodes
209
210 local visible_code = {
211 [ nodecodes . glyph ] = true ,
212 [ nodecodes . glue ] = true ,
213 [ nodecodes . hlist ] = true ,
214 [ nodecodes . vlist ] = true ,
215 [ nodecodes . rule ] = true ,
216 }
217
218 local kern_code = nodecodes . kern
219 local c_userkern = kerncodes . userkern
220 local a_fontkern = attributes . private ( " fontkern " )
221
222 local copynode = nodes . copy
223 local freenode = nodes . free
224
225 local topoints = number . topoints
226 local mpprint = mp . print
227
228 local n = nil
229 local s = 0
230
231 function mp . follow_reset ( )
232 for i = 1 , # n do
233 freenode ( n [ i ] )
234 end
235 n = nil
236 s = 0
237 end
238
239 function mp . follow_initialize ( b )
240 if not n then
241 local head = tex . takebox ( b ) . list
242 if head then
243 n = { }
244 s = 0
245 head = node . flatten_discretionaries ( head )
246 local current = head
247 while current do
248 local id = current . id
249 if visible_code [ id ] then
250 s = s + 1
251 head , current , n [ s ] = nodes . remove ( head , current )
252 elseif id = = kern_code and current . subtype = = c_userkern and not current [ a_fontkern ] then
253 s = s + 1
254 head , current , n [ s ] = nodes . remove ( head , current )
255 else
256 current = current . next
257 end
258 end
259 nodes . flush_list ( head )
260 end
261 end
262 end
263
264 function mp . follow_size ( )
265 mpprint ( s )
266 end
267
268 function mp . follow_slot ( i )
269 mpprint ( ' textext("\\getfollowtoken{ ' . . i . . ' }") ' )
270 end
271
272 function mp . follow_text ( s )
273 context ( copynode ( n [ s ] ) )
274 end
275
276 function mp . follow_width ( i )
277 mpprint ( topoints ( n [ i ] . width ) )
278 end
279\stopluacode
280
281\unexpanded \def \dofollowtokens # 1 # 2
282 { \vbox \bgroup
283 \forgetall
284 \dontcomplain
285 \setbox \scratchbox \hbox { \addff { mp : tp } # 2 }
286 \ctxlua{ mp . follow_initialize ( \number \scratchbox ) }
287 \startMPcode
288 \includeMPgraphic { followtokens } ;
289 mfun_follow_draw ( \number # 1 ) ;
290 \stopMPcode
291 \ctxlua{ mp . follow_reset ( ) }
292 \egroup }
293
294\unexpanded \def \followtokens { \dofollowtokens \plusone }
295\unexpanded \def \followtokenscentered { \dofollowtokens \zerocount }
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329\startuseMPgraphic { fuzzycount }
330 begingroup
331 save height , span , drift , d , cp ;
332 height : = 3 5 \baselinedistance ;
333 span : = 1 3 height ;
334 drift : = 1 10 height ;
335 pickup pencircle scaled ( 1 12 height ) ;
336 def d = ( uniformdeviate drift ) enddef ;
337 for i : = 1 upto \MPvar { n } :
338 draw
339 if ( i mod 5 ) = 0 : ( ( d -4.5 span , d ) -- ( d -0.5 span , height d ) )
340 else : ( ( d , d ) -- ( d , height d ) ) fi
341 shifted ( span i , d drift ) ;
342 endfor ;
343 picture cp ; cp : = currentpicture ;
344 setbounds currentpicture to
345 ( llcorner cp shifted ( 0 , ypart llcorner cp ) --
346 lrcorner cp shifted ( 0 , ypart lrcorner cp ) --
347 urcorner cp -- ulcorner cp -- cycle ) ;
348 endgroup ;
349\stopuseMPgraphic
350
351\setupMPvariables
352 [ fuzzycount ]
353 [ n = 1 0 ]
354
355\unexpanded \def \fuzzycount # 1
356 {{ \tx\useMPgraphic { fuzzycount }{ n =# 1 }}}
357
358\defineconversion [ fuzzy ][ \fuzzycount ]
359
360
361
362\setupMPvariables
363 [ EnglishRule ]
364 [ height = 1 ex ,
365 width = \the \localhsize ,
366 color = darkgray ]
367
368\defineblank
369 [ EnglishRule ]
370 [ medium ]
371
372\startuniqueMPgraphic { EnglishRule } { height,width,color }
373 x 1 = 0 ; x 3 = \MPvar { width } ; x 2 = x 4 = .5 x 3 ;
374 y 1 = y 3 = 0 ; y 2 = y 4 = \MPvar { height } 2 ;
375 fill z 1. . z 2. . z 3 & z 3. . z 4. . z 1 & cycle withcolor \MPvar { color } ;
376\stopuniqueMPgraphic
377
378\unexpanded \def \EnglishRule
379 { \startlinecorrection [ EnglishRule ]
380 \setlocalhsize \noindent \reuseMPgraphic { EnglishRule }
381 \stoplinecorrection }
382
383
384
385
386
387
388
389
390
391\unexpanded \def \TightText # 1 # 2 # 3 # 4
392 { \hpack
393 { \startMPcode
394 picture p ; p : = image ( graphictext " #1 " withfillcolor red ) ;
395 draw p xsized # 2 ysized # 3 withcolor \MPcolor { #4 } ;
396 \stopMPcode }}
397
398\protect \endinput
399 |