summaryrefslogtreecommitdiff
path: root/metapost/context/base/mpiv/mp-blob.mpiv
blob: 78fa6bfe921aa6a11f382fdeecba66ca894aad19 (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
%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 ; " ;

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 ;

% An example of usage:

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

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 ;