mp-blob.mpxl /size: 4280 b    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=mp-blob.mpiv,
3%D        version=2018.04.08,
4%D          title=\CONTEXT\ \METAPOST\ graphics,
5%D       subtitle=Blobs,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14%D This is a follow up on good old \type {meta-imp-txt}.
15
16if known metafun_loaded_blob : endinput ; fi ;
17
18newinternal boolean metafun_loaded_blob ; metafun_loaded_blob := true ; immutable metafun_loaded_blob ;
19
20numeric mfun_blob_n ; mfun_blob_n := 0 ;
21picture mfun_blob_c ;
22color   mfun_blob_b ;
23
24def mfun_reset_tex_blobs =
25    mfun_blob_n := 0 ;
26    mfun_blob_c := nullpicture ;
27enddef ;
28
29extra_endfig := extra_endfig & "mfun_reset_tex_blobs ; " ;
30
31vardef mfun_inject_blob(expr n) =
32    mfun_blob_c := nullpicture ;
33    mfun_blob_b := lua.mp.mf_blob_dimensions(mfun_blob_n,n) ;
34    addto mfun_blob_c doublepath unitsquare
35        xscaled redpart mfun_blob_b
36        yscaled (greenpart mfun_blob_b + bluepart mfun_blob_b)
37        shifted (0,- bluepart mfun_blob_b)
38        withprescript "mf_object=texblob"
39        withprescript "tb_blob=" & decimal lua.mp.mf_blob_index(mfun_blob_n,n) ;
40    mfun_blob_c
41enddef ;
42
43% An example of usage:
44
45newinternal followtextalternative   ; followtextalternative   := 1 ;
46newinternal tracingfollowtext       ; tracingfollowtext       := 0 ;
47newinternal autoscaleupfollowtext   ; autoscaleupfollowtext   := 2 ;
48newinternal autoscaledownfollowtext ; autoscaledownfollowtext := 0 ;
49
50permanent tracingfollowtext ;
51
52vardef followtext(expr pth, txt) =
53    image (
54        mfun_blob_n := mfun_blob_n + 1 ;
55        lua.mp.mf_inject_blob(mfun_blob_n,txt);
56        save pat, al, at, pl, pc, wid, pos, ap, ad, pic, len, n, b, sc, sb ;
57        path pat, b ; pat := pth ;
58        numeric al, at, pl, pc, wid, pos, len[], n, sc, sb ;
59        pair ap, ad ;
60        picture pic[] ;
61        len[0] := 0 ;
62        n := lua.mp.mf_blob_size(mfun_blob_n) ;
63        sc := 0 ;
64        sb := .25pt;
65        for i=1 upto n :
66            pic[i] := mfun_inject_blob(i) ;
67            pic[i] := pic[i] shifted - llcorner pic[i] ;
68            len[i] := len[i-1] + lua.mp.mf_blob_width(mfun_blob_n,i) ;
69        endfor ;
70        al := arclength pth ;
71        if al = 0 :
72            al := len[n] ;
73            pat := origin -- (al,0) ;
74        fi ;
75        if ((al < len[n]) and (autoscaleupfollowtext   > 0)) or
76           ((al > len[n]) and (autoscaledownfollowtext > 0)) :
77            sc := len[n] /al ;
78            pat := pat scaled sc ;
79            al := arclength pat ;
80        fi ;
81        if followtextalternative = 1 :
82            pl := (al-len[n])/(if n>1 : (n-1) else : 1 fi) ;
83            pc := 0 ;
84        else : % centered / MP
85            pl := 0 ;
86            pc := arclength pat/2 - len[n]/2 ;
87        fi ;
88        if tracingfollowtext = 1 :
89            draw pat withpen pencircle scaled 1pt withcolor blue ;
90        fi ;
91        for i=1 upto n :
92            wid := lua.mp.mf_blob_width(mfun_blob_n,i) ;
93            pos := len[i]-wid/2 + (i-1)*pl + pc ;
94            at := arctime   pos of pat ;
95            ap := point     at  of pat ;
96            ad := direction at  of pat ;
97            pic[i] := pic[i]
98                shifted (-wid/2,0)
99                if ad <> origin : rotated(angle(ad)) fi
100                shifted ap ;
101            draw pic[i] ;
102            if tracingfollowtext = 1 :
103                draw boundingbox pic[i] withpen pencircle scaled .25pt withcolor red ;
104                draw ap withpen pencircle scaled .50pt withcolor green ;
105            fi ;
106        endfor ;
107        if ((autoscaleupfollowtext = 2) or (autoscaledownfollowtext = 2)) and (sc <> 0) and (sc <> 1):
108            currentpicture := currentpicture scaled (1/sc) ;
109            sb := 2 * sb / sc ;
110        fi ;
111        b := boundingbox currentpicture ;
112        if tracingfollowtext = 1 :
113            draw b withpen pencircle scaled sb withcolor blue ;
114        fi ;
115        draw fullcircle scaled 100bp
116            withprescript "mf_object=followtext"
117            withprescript "ft_category=" & decimal mfun_blob_n ;
118        setbounds currentpicture to b ;
119    )
120enddef ;
121