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\ifdefined\??sh \else \definesystemvariable {sh} \fi
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 {\doifsomething{##1}
84 {\ifcase\scratchcounter\relax
85 \expandafter\appendtoks\space##1 \to\scratchtoks
86 \else
87 \advance\scratchcounter\minusone
88 \fi}}
89 \scratchcounter\prevgraf
90 \doglobal\decrement(\totalparlines,\scratchcounter)
91 \multiply\scratchcounter\plustwo
92 \scratchtoks\emptytoks
93 \expanded{\processseparatedlist[\the\partoks][\space]}\docommand
94 \global\partoks\scratchtoks
95 \parshape\totalparlines\the\partoks\relax}
96
97\unexpanded\def\getshapecharacteristics
98 {\doglobal\increment\currentshapetext
99 \doifelsedefined{parlines:\currentshapetext}
100 {\getvalue{parlines:\currentshapetext}}
101 {\global\parlines \plusone
102 \global\parfirst \zerocount
103 \global\parvoffset\zeropoint
104 \global\parhoffset\zeropoint
105 \global\parwidth \hsize
106 \global\parheight \vsize}}
107
108\unexpanded\def\setshapecharacteristics
109 {\doglobal\increment\currentshapetext
110 \setxvalue{parlines:\currentshapetext}
111 {\global\parlines \the\parlines
112 \global\parfirst \the\parfirst
113 \global\parvoffset\the\parvoffset
114 \global\parhoffset\the\parhoffset
115 \global\parwidth \the\parwidth
116 \global\parheight \the\parheight}}
117
118\unexpanded\def\getshapetext
119 {\vbox\bgroup
120 \forgetall
121 \dontcomplain
122 \setbox\scratchbox\vbox to \parheight
123 {\switchtobodyfont[\@@shbodyfont]
124 \splittopskip\strutheight
125 \vskip\parvoffset
126 \ifcase\parfirst\else\vskip\lineheight\fi
127 \hskip\parhoffset
128 \hbox{\vsplit\shapetextbox to \parlines\lineheight}}
129 \wd\scratchbox\parwidth
130 \ht\scratchbox\parheight
131 \dp\scratchbox\zeropoint
132 \box\scratchbox
133 \getshapecharacteristics
134 \egroup}
135
136\doifundefined{RotFont}{\definefont[RotFont][RegularBold*default]}
137
138\unexpanded\def\getfollowtoken#1
139 {\hbox\bgroup
140 \strut
141 \ctxlua{mp.follow_text(#1)}
142 \egroup}
143
144\definefontfeature[mp:tp][liga=no]
145
146\startMPdefinitions
147 def mfun_follow_draw (expr alternative) =
148 if unknown RotPath : path RotPath ; RotPath := origin ; fi ;
149
150 if unknown TraceRot : boolean TraceRot ; TraceRot := false ; fi ;
151 if unknown ExtraRot : numeric ExtraRot ; ExtraRot := 0 ; fi ;
152 picture pic[] ;
153 numeric len[] ; len[0] := 0 ;
154 numeric n ; n := lua.mp.follow_size() ;
155 for i=1 upto n :
156 pic[i] := lua.mp.follow_slot(i) ;
157 pic[i] := pic[i] shifted llcorner pic[i] ;
158 len[i] := len[i-1] lua.mp.follow_width(i) ;
159 endfor ;
160 numeric al, at, pl, pc, wid, pos ; pair ap, ad ;
161 al := arclength RotPath ;
162 if al = 0 :
163 al := len[n] ExtraRot ;
164 RotPath := origin -- (al,0) ;
165 fi ;
166 if al < len[n]:
167 RotPath := RotPath scaled ((len[n]ExtraRot)al) ;
168 al := arclength RotPath ;
169 fi ;
170 if alternative = 1 :
171 pl := (allen[n])(if n>1 : (n-1) else : 1 fi) ;
172 pc := 0 ;
173 else :
174 pl := 0 ;
175 pc := arclength RotPath2 len[n]2 ;
176 fi ;
177 if TraceRot :
178 draw RotPath withpen pencircle scaled 1pt withcolor blue ;
179 fi ;
180 for i=1 upto n :
181
182 wid := lua.mp.follow_width(i) ;
183 pos := len[i]wid2 (i-1)pl pc ;
184 at := arctime pos of RotPath ;
185 ap := point at of RotPath ;
186 ad := direction at of RotPath ;
187 if mfun_trial_run :
188
189
190 else :
191 pic[i] := pic[i] shifted (wid2,0) rotated(angle(ad)) shifted ap ;
192 draw pic[i] ;
193 if TraceRot :
194 draw boundingbox pic[i] withpen pencircle scaled .25pt withcolor red ;
195 draw ap withpen pencircle scaled .50pt withcolor green ;
196 fi ;
197 fi ;
198 endfor ;
199 if TraceRot :
200 draw boundingbox currentpicture withpen pencircle scaled .25pt withcolor blue ;
201 fi ;
202 enddef ;
203\stopMPdefinitions
204
205\startluacode
206 local context = context
207
208 local nodecodes = nodes.nodecodes
209 local kerncodes = nodes.kerncodes
210
211 local visible_code = {
212 [nodecodes.glyph] = true,
213 [nodecodes.glue] = true,
214 [nodecodes.hlist] = true,
215 [nodecodes.vlist] = true,
216 [nodecodes.rule] = true,
217 }
218
219 local kern_code = nodecodes.kern
220 local c_userkern = kerncodes.userkern
221 local a_fontkern = attributes.private("fontkern")
222
223 local copynode = nodes.copy
224 local freenode = nodes.free
225
226 local topoints = number.topoints
227 local mpprint = mp.print
228
229 local n = nil
230 local s = 0
231
232 function mp.follow_reset()
233 for i=1,#n do
234 freenode(n[i])
235 end
236 n = nil
237 s = 0
238 end
239
240 function mp.follow_initialize(b)
241 if not n then
242 local head = tex.takebox(b).list
243 if head then
244 n = { }
245 s = 0
246 head = nodes.flattendiscretionaries(head)
247 local current = head
248 while current do
249 local id = current.id
250 if visible_code[id] then
251 s = s + 1
252 head, current, n[s] = nodes.remove(head,current)
253 elseif id == kern_code and current.subtype == c_userkern and not current[a_fontkern] then
254 s = s + 1
255 head, current, n[s] = nodes.remove(head,current)
256 else
257 current = current.next
258 end
259 end
260 nodes.flush_list(head)
261 end
262 end
263 end
264
265 function mp.follow_size()
266 mpprint(s)
267 end
268
269 function mp.follow_slot(i)
270 mpprint('textext("\\getfollowtoken{' .. i .. '}")')
271 end
272
273 function mp.follow_text(s)
274 context(copynode(n[s]))
275 end
276
277 function mp.follow_width(i)
278 mpprint(topoints(n[i].width))
279 end
280\stopluacode
281
282\unexpanded\def\dofollowtokens#1#2
283 {\vbox\bgroup
284 \forgetall
285 \dontcomplain
286 \setbox\scratchbox\hbox{\addff{mp:tp}#2}
287 \ctxlua{mp.follow_initialize(\number\scratchbox)}
288 \startMPcode
289 \includeMPgraphic{followtokens} ;
290 mfun_follow_draw(\number#1) ;
291 \stopMPcode
292 \ctxlua{mp.follow_reset()}
293 \egroup}
294
295\unexpanded\def\followtokens {\dofollowtokens\plusone}
296\unexpanded\def\followtokenscentered{\dofollowtokens\zerocount}
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
330\startuseMPgraphic{fuzzycount}
331 begingroup
332 save height, span, drift, d, cp ;
333 height := 3 5 \baselinedistance ;
334 span := 1 3 height ;
335 drift := 110 height ;
336 pickup pencircle scaled (112 height) ;
337 def d = (uniformdeviate drift) enddef ;
338 for i := 1 upto \MPvar{n} :
339 draw
340 if (i mod 5)=0 : ((d-4.5span,d)--(d-0.5span,heightd))
341 else : ((d,d)--(d,heightd)) fi
342 shifted (spani,ddrift) ;
343 endfor;
344 picture cp ; cp := currentpicture ;
345 setbounds currentpicture to
346 (llcorner cp shifted (0,ypart llcorner cp) --
347 lrcorner cp shifted (0,ypart lrcorner cp) --
348 urcorner cp -- ulcorner cp -- cycle) ;
349 endgroup ;
350\stopuseMPgraphic
351
352\setupMPvariables
353 [fuzzycount]
354 [n=10]
355
356\unexpanded\def\fuzzycount#1
357 {{\tx\useMPgraphic{fuzzycount}{n=#1}}}
358
359\defineconversion[fuzzy][\fuzzycount]
360
361
362
363\setupMPvariables
364 [EnglishRule]
365 [height=1ex,
366 width=\the\localhsize,
367 color=darkgray]
368
369\defineblank
370 [EnglishRule]
371 [medium]
372
373\startuniqueMPgraphic{EnglishRule}{height,width,color}
374 x1 = 0 ; x3 = \MPvar{width} ; x2 = x4 = .5x3 ;
375 y1 = y3 = 0 ; y2 = y4 = \MPvar{height}2 ;
376 fill z1..z2..z3 & z3..z4..z1 & cycle withcolor \MPvar{color} ;
377\stopuniqueMPgraphic
378
379\unexpanded\def\EnglishRule
380 {\startlinecorrection[EnglishRule]
381 \setlocalhsize \noindent \reuseMPgraphic{EnglishRule}
382 \stoplinecorrection}
383
384
385
386
387
388
389
390
391
392\unexpanded\def\TightText#1#2#3#4
393 {\hpack
394 {\startMPcode
395 picture p ; p := image (graphictext "#1" withfillcolor red) ;
396 draw p xsized #2 ysized #3 withcolor \MPcolor{#4} ;
397 \stopMPcode}}
398
399\protect \endinput
400 |