mp-text.mpiv /size: 5013 b    last modification: 2020-07-01 14:35
1%D \module
2%D   [       file=mp-text.mpiv,
3%D        version=2000.07.10,
4%D          title=\CONTEXT\ \METAPOST\ graphics,
5%D       subtitle=text support,
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 licen-en.pdf for
12%C details.
13
14%D This one is only used in metafun so it will become a module.
15
16if known context_text : endinput ; fi ;
17
18boolean context_text ; context_text := true ;
19
20def build_parshape (expr p, offset_or_path, dx, dy, baselineskip, strutheight, strutdepth, topskip) =
21
22    if unknown trace_parshape :
23        boolean trace_parshape ; trace_parshape := false ;
24    fi ;
25
26    begingroup ;
27
28    save
29        q, l, r, line, tt, bb,
30        n, hsize, vsize, vvsize, voffset, hoffset, width, indent,
31        ll, lll, rr, rrr, cp, cq, t, b ;
32
33    path
34        q, l, r, line, tt, bb ;
35    numeric
36        n, hsize, vsize, vvsize, voffset, hoffset, width[], indent[] ;
37    pair
38        ll, lll, rr, rrr, cp, cq, t, b ;
39
40    n  := 0 ;
41    cp := center p ;
42
43    if path offset_or_path :
44        q       := offset_or_path ;
45        cq      := center q ;
46        voffset := dy ;
47        hoffset := dx ;
48    else :
49        q       := p ;
50        cq      := center q ;
51        hoffset := offset_or_path + dx ;
52        voffset := offset_or_path + dy ;
53    fi ;
54
55    hsize := xpart lrcorner q - xpart llcorner q ;
56    vsize := ypart urcorner q - ypart lrcorner q ;
57
58    q := p shifted - cp ;
59
60    startsavingdata ;
61
62    savedata "\global\parvoffset " & decimal voffset & "bp " ;
63    savedata "\global\parhoffset " & decimal hoffset & "bp " ;
64    savedata "\global\parwidth   " & decimal   hsize & "bp " ;
65    savedata "\global\parheight  " & decimal   vsize & "bp " ;
66
67    if not path offset_or_path :
68        q := q xscaled ((hsize-2hoffset)/hsize) yscaled ((vsize-2voffset)/vsize) ;
69    fi ;
70
71    hsize := xpart lrcorner q - xpart llcorner q ;
72    vsize := ypart urcorner q - ypart lrcorner q ;
73
74    t := (ulcorner q -- urcorner q) intersection_point q ;
75    b := (llcorner q -- lrcorner q) intersection_point q ;
76
77    if xpart directionpoint t of q < 0 :
78        q := reverse q ;
79    fi ;
80
81    l := q cutbefore t ;
82    l := l if xpart point 0 of q < 0 : & q fi cutafter b ;
83
84    r := q cutbefore b ;
85    r := r if xpart point 0 of q > 0 : & q fi cutafter t ;
86
87    % tt := (ulcorner q -- urcorner q) shifted (0,-topskip) ;
88    % bb := (llcorner q -- lrcorner q) shifted (0,strutdepth) ;
89
90    % l := l cutbefore (l intersection_point tt) ;
91    % l := l cutafter  (l intersection_point bb) ;
92    % r := r cutbefore (r intersection_point bb) ;
93    % r := r cutafter  (r intersection_point tt) ;
94
95    if trace_parshape :
96        drawarrow p            withpen pencircle scaled 2pt withcolor red ;
97        drawarrow l shifted cp withpen pencircle scaled 1pt withcolor green ;
98        drawarrow r shifted cp withpen pencircle scaled 1pt withcolor blue ;
99    fi ;
100
101    vardef found_point (expr lin, pat, sig) =
102        pair a, b ;
103        a := pat intersection_point (lin shifted (0,strutheight)) ;
104        if intersection_found :
105        a := a shifted (0,-strutheight) ;
106        else :
107        a := pat intersection_point lin ;
108        fi ;
109        b := pat intersection_point (lin shifted (0,-strutdepth)) ;
110        if intersection_found :
111        if sig :
112            if xpart b > xpart a : a := b shifted (0,strutdepth) fi ;
113        else :
114            if xpart b < xpart a : a := b shifted (0,strutdepth) fi ;
115        fi ;
116        fi ;
117        a
118    enddef ;
119
120    if (strutheight+strutdepth<baselineskip) :
121        vvsize := vsize ;
122    else :
123        vvsize := (vsize div baselineskip) * baselineskip ;
124    fi ;
125
126    for i=topskip step baselineskip until vvsize :
127
128        line := (ulcorner q -- urcorner q) shifted (0,-i-eps) ;
129
130        ll := found_point(line,l,true ) ;
131        rr := found_point(line,r,false) ;
132
133        if trace_parshape :
134            fill (ll--rr--rr shifted (0,strutheight)--ll shifted (0,strutheight)--cycle) shifted cp withcolor .5white ;
135            fill (ll--rr--rr shifted (0,-strutdepth)--ll shifted (0,-strutdepth)--cycle) shifted cp withcolor .7white ;
136            draw ll shifted cp withpen pencircle scaled 2pt ;
137            draw rr shifted cp withpen pencircle scaled 2pt ;
138            draw (ll--rr) shifted cp  withpen pencircle scaled .5pt ;
139        fi ;
140
141        n := n + 1 ;
142        indent[n] := abs(xpart ll - xpart llcorner q) ;
143        width[n]  := abs(xpart rr - xpart ll) ;
144
145        if (i=strutheight) and (width[n]<baselineskip) :
146            n := n - 1 ;
147            savedata "\global\parfirst\plusone " ;
148        fi ;
149
150    endfor ;
151
152    savedata "\global\parlines " & decimal n ;
153    savedata "\global\partoks{ " ;
154    for i=1 upto n:
155        savedata decimal indent[i]&"bp " & decimal width[i]&"bp " ;
156    endfor ;
157    savedata "}" ;
158
159    stopsavingdata ;
160
161    endgroup ;
162
163enddef ;
164