summaryrefslogtreecommitdiff
path: root/metapost/context/base/mpiv/mp-blob.mpiv
blob: d2bdf741a04c88a6458e264cb3194b14002ecfc9 (plain)
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
%D \module
%D   [       file=mp-blob.mpiv,
%D        version=2018.04.08,
%D          title=\CONTEXT\ \METAPOST\ graphics,
%D       subtitle=Blobs,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

%D This is a follow up on good old \type {meta-imp-txt}.

if known context_blob : endinput ; fi ;

boolean context_blob ; context_blob := true ;

numeric mfun_blob_n ; mfun_blob_n := 0 ;
picture mfun_blob_c ;
color   mfun_blob_b ;

def mfun_reset_tex_blobs =
    mfun_blob_n := 0 ;
    mfun_blob_c := nullpicture ;
enddef ;

extra_endfig := extra_endfig & "mfun_reset_tex_blobs ; " ;

if mfun_use_one_pass :

    vardef mfun_inject_blob(expr n) =
        mfun_blob_c := nullpicture ;
        mfun_blob_b := lua.mp.blob_dimensions(mfun_blob_n,n) ;
        addto mfun_blob_c doublepath unitsquare
            xscaled redpart mfun_blob_b
            yscaled (greenpart mfun_blob_b + bluepart mfun_blob_b)
            shifted (0,- bluepart mfun_blob_b)
            withprescript "tb_blob=" & decimal lua.mp.blob_index(mfun_blob_n,n) ;
        mfun_blob_c
    enddef ;

else :

    vardef mfun_inject_blob(expr n) =
        mfun_blob_c := nullpicture ;
        mfun_blob_b := lua.mp.blob_dimensions(mfun_blob_n,n) ;
        addto mfun_blob_c doublepath unitsquare
            xscaled redpart mfun_blob_b
            yscaled (greenpart mfun_blob_b + bluepart mfun_blob_b)
            shifted (0,- bluepart mfun_blob_b)
            withprescript "tb_stage=inject"
            withprescript "tb_blob=" & decimal lua.mp.blob_index(mfun_blob_n,n) ;
        mfun_blob_c
    enddef ;

fi ;

% An example of usage:

newinternal followtextalternative   ; followtextalternative   := 1 ;
newinternal tracingfollowtext       ; tracingfollowtext       := 0 ;
newinternal autoscaleupfollowtext   ; autoscaleupfollowtext   := 2 ;
newinternal autoscaledownfollowtext ; autoscaledownfollowtext := 0 ;

if mfun_use_one_pass :

    vardef followtext(expr pth, txt) =
        image (
            mfun_blob_n := mfun_blob_n + 1 ;
            lua.mp.InjectBlobB(mfun_blob_n,txt);
            save pat, al, at, pl, pc, wid, pos, ap, ad, pic, len, n, sc ;
            path pat ; pat := pth ;
            numeric al, at, pl, pc, wid, pos, len[], n, sc ;
            pair ap, ad ;
            picture pic[] ;
            len[0] := 0 ;
            n := lua.mp.blob_size(mfun_blob_n) ;
            sc := 0 ;
            for i=1 upto n :
                pic[i] := mfun_inject_blob(i) ;
                pic[i] := pic[i] shifted - llcorner pic[i] ;
                len[i] := len[i-1] + lua.mp.blob_width(mfun_blob_n,i) ;
            endfor ;
            al := arclength pth ;
            if al = 0 :
                al := len[n] ;
                pat := origin -- (al,0) ;
            fi ;
            if ((al < len[n]) and (autoscaleupfollowtext   > 0)) or
               ((al > len[n]) and (autoscaledownfollowtext > 0)) :
                sc := len[n] /al ;
                pat := pat scaled sc ;
                al := arclength pat ;
            fi ;
            if followtextalternative = 1 :
                pl := (al-len[n])/(if n>1 : (n-1) else : 1 fi) ;
                pc := 0 ;
            else : % centered / MP
                pl := 0 ;
                pc := arclength pat/2 - len[n]/2 ;
            fi ;
            if tracingfollowtext = 1 :
                draw pat withpen pencircle scaled 1pt withcolor blue ;
            fi ;
            for i=1 upto n :
                wid := lua.mp.blob_width(mfun_blob_n,i) ;
                pos := len[i]-wid/2 + (i-1)*pl + pc ;
                at := arctime   pos of pat ;
                ap := point     at  of pat ;
                ad := direction at  of pat ;
                pic[i] := pic[i] shifted (-wid/2,0) rotated(angle(ad)) shifted ap ;
                draw pic[i] ;
                if tracingfollowtext = 1 :
                    draw boundingbox pic[i] withpen pencircle scaled .25pt withcolor red ;
                    draw ap withpen pencircle scaled .50pt withcolor green ;
                fi ;
            endfor ;
            if ((autoscaleupfollowtext = 2) or (autoscaledownfollowtext = 2)) and
               (sc <> 0) and (sc <> 1):
                currentpicture := currentpicture scaled (1/sc) ;
            fi ;
            if tracingfollowtext = 1 :
                draw boundingbox currentpicture withpen pencircle scaled .25pt withcolor blue ;
            fi ;
            draw fullcircle scaled 100bp
                withprescript "ft_stage=final"
                withprescript "ft_category=" & decimal mfun_blob_n ;
        )
    enddef ;

else :

    vardef followtext(expr pth, txt) =
        image (
            mfun_blob_n := mfun_blob_n + 1 ;
            if mfun_trial_run :
                draw fullcircle scaled 100bp
                    withprescript "ft_stage=trial"
                    withprescript "ft_category=" & decimal mfun_blob_n
                    withpostscript txt ;
            else :
                save pat, al, at, pl, pc, wid, pos, ap, ad, pic, len, n, sc ;
                path pat ; pat := pth ;
                numeric al, at, pl, pc, wid, pos, len[], n, sc ;
                pair ap, ad ;
                picture pic[] ;
                len[0] := 0 ;
                n := lua.mp.blob_size(mfun_blob_n) ;
                sc := 0 ;
                for i=1 upto n :
                    pic[i] := mfun_inject_blob(i) ;
                    pic[i] := pic[i] shifted - llcorner pic[i] ;
                    len[i] := len[i-1] + lua.mp.blob_width(mfun_blob_n,i) ;
                endfor ;
                al := arclength pth ;
                if al = 0 :
                    al := len[n] ;
                    pat := origin -- (al,0) ;
                fi ;
                if ((al < len[n]) and (autoscaleupfollowtext   > 0)) or
                   ((al > len[n]) and (autoscaledownfollowtext > 0)) :
                    sc := len[n] /al ;
                    pat := pat scaled sc ;
                    al := arclength pat ;
                fi ;
                if followtextalternative = 1 :
                    pl := (al-len[n])/(if n>1 : (n-1) else : 1 fi) ;
                    pc := 0 ;
                else : % centered / MP
                    pl := 0 ;
                    pc := arclength pat/2 - len[n]/2 ;
                fi ;
                if tracingfollowtext = 1 :
                    draw pat withpen pencircle scaled 1pt withcolor blue ;
                fi ;
                for i=1 upto n :
                    wid := lua.mp.blob_width(mfun_blob_n,i) ;
                    pos := len[i]-wid/2 + (i-1)*pl + pc ;
                    at := arctime   pos of pat ;
                    ap := point     at  of pat ;
                    ad := direction at  of pat ;
                    pic[i] := pic[i] shifted (-wid/2,0) rotated(angle(ad)) shifted ap ;
                    draw pic[i] ;
                    if tracingfollowtext = 1 :
                        draw boundingbox pic[i] withpen pencircle scaled .25pt withcolor red ;
                        draw ap withpen pencircle scaled .50pt withcolor green ;
                    fi ;
                endfor ;
                if ((autoscaleupfollowtext = 2) or (autoscaledownfollowtext = 2)) and
                   (sc <> 0) and (sc <> 1):
                    currentpicture := currentpicture scaled (1/sc) ;
                fi ;
                if tracingfollowtext = 1 :
                    draw boundingbox currentpicture withpen pencircle scaled .25pt withcolor blue ;
                fi ;
                draw fullcircle scaled 100bp
                    withprescript "ft_stage=final"
                    withprescript "ft_category=" & decimal mfun_blob_n ;
            fi ;
        )
    enddef ;

fi ;