diff options
author | Hans Hagen <pragma@wxs.nl> | 2000-10-22 00:00:00 +0200 |
---|---|---|
committer | Hans Hagen <pragma@wxs.nl> | 2000-10-22 00:00:00 +0200 |
commit | e78478392e9717499b101d0fed642c945c104097 (patch) | |
tree | 7f3dbe64040cbcf413644cae6516872c0fb5cd2b /metapost | |
parent | 73000ea3b7c8225c980f40ef90b86e2d57fe4003 (diff) | |
download | context-e78478392e9717499b101d0fed642c945c104097.tar.gz |
stable 2000.10.22
Diffstat (limited to 'metapost')
-rw-r--r-- | metapost/context/metafun.mp | 41 | ||||
-rw-r--r-- | metapost/context/mp-back.mp | 206 | ||||
-rw-r--r-- | metapost/context/mp-butt.mp | 75 | ||||
-rw-r--r-- | metapost/context/mp-char.mp | 968 | ||||
-rw-r--r-- | metapost/context/mp-core.mp | 232 | ||||
-rw-r--r-- | metapost/context/mp-page.mp | 218 | ||||
-rw-r--r-- | metapost/context/mp-shap.mp | 261 | ||||
-rw-r--r-- | metapost/context/mp-spec.mp | 147 | ||||
-rw-r--r-- | metapost/context/mp-text.mp | 202 | ||||
-rw-r--r-- | metapost/context/mp-tool.mp | 1216 |
10 files changed, 3566 insertions, 0 deletions
diff --git a/metapost/context/metafun.mp b/metapost/context/metafun.mp new file mode 100644 index 000000000..802264351 --- /dev/null +++ b/metapost/context/metafun.mp @@ -0,0 +1,41 @@ +%D \module +%D [ file=metafun.mp, +%D version=2000.07.15, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=format generation file, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 When generating many graphics at runtime, it can save run +%D time to use a format file. We could have named this file +%D \type {context}, but this is error prone, because it forces +%D to use the progname \type {mpost} or \type {context} +%D explicitly, depending on the needs. When using the format, +%D a mismatch in the memory specification of \type {mpost} or +%D \type {context} (the \TEX\ one) could lead to lost strings +%D (and as a result in buggy boundingbox and special +%D handling). By using the name \type {metatex} we make sure +%D %D that we use (unless overloaded) the settings of \type +%D {mpost}. + +if unknown ahangle : + input plain.mp ; % John Hobby's file +else : + let dump = relax ; +fi ; + +input mp-tool.mp ; +input mp-spec.mp ; +input mp-core.mp ; +input mp-page.mp ; +input mp-text.mp ; +input mp-shap.mp ; +input mp-butt.mp ; +input mp-char.mp ; + +dump ; endinput . diff --git a/metapost/context/mp-back.mp b/metapost/context/mp-back.mp new file mode 100644 index 000000000..99e88554b --- /dev/null +++ b/metapost/context/mp-back.mp @@ -0,0 +1,206 @@ +%D \module +%D [ file=mp-back.mp, +%D version=2000.05.31, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=backgrounds, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +if unknown context_tool : input mp-tool ; fi ; +if known context_back : endinput ; fi ; + +boolean context_back ; context_back := true ; + +def some_hash ( expr hash_width , + hash_height , + hash_linewidth , + hash_linecolor , + hash_angle , + hash_gap ) = + + stripe_gap := hash_gap ; + stripe_angle := hash_angle ; + drawoptions (withpen pencircle scaled hash_linewidth + withcolor hash_linecolor) ; + path p ; p := unitsquare xscaled hash_width yscaled hash_height ; + stripe_path_a () (draw) p ; % next we move it all to quadrant 1 + currentpicture := currentpicture shifted urcorner currentpicture ; + +enddef ; + +def some_double_back (expr back_type , + back_width , + back_height , + back_delta , + back_linewidth , + back_linecolor , + back_fillcolor , + back_topcolor , + back_bottomcolor , + back_leftcolor , + back_rightcolor ) = + + numeric ww ; ww := back_width ; + numeric hh ; hh := back_height ; + numeric dd ; dd := back_delta ; + + color back_nillcolor ; back_nillcolor := back_topcolor ; + + path p ; p := fullsquare xscaled ww yscaled hh ; + path q ; q := fullsquare xscaled (ww-2dd) yscaled (hh-2dd) ; + path r ; r := llcorner p -- + lrcorner p shifted (-3dd,0) .. controls lrcorner p .. + lrcorner p shifted (0, 3dd) -- + urcorner p shifted (0,-3dd) .. controls urcorner p .. + urcorner p shifted (-3dd,0) -- + ulcorner p -- cycle ; + path s ; s := r xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ; + path t ; t := llcorner p -- + lrcorner p -- + urcorner p shifted (0,-3dd) .. controls urcorner p .. + urcorner p shifted (-3dd,0) -- + ulcorner p shifted ( 3dd,0) .. controls ulcorner p .. + ulcorner p shifted (0,-3dd) -- + llcorner p -- cycle ; + path u ; u := t xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ; + path v ; v := llcorner p shifted ( 3dd,0) -- + lrcorner p shifted (-3dd,0) .. controls lrcorner p .. + lrcorner p shifted (0, 3dd) -- + urcorner p shifted (0,-3dd) .. controls urcorner p .. + urcorner p shifted (-3dd,0) -- + ulcorner p shifted ( 3dd,0) .. controls ulcorner p .. + ulcorner p shifted (0,-3dd) .. + llcorner p shifted (0, 3dd) .. controls llcorner p .. cycle ; % {down} .. cycle ; + path w ; w := t xscaled ((ww-2dd)/ww) yscaled ((hh-2dd)/hh) ; + path a ; a := llcorner p -- ulcorner p -- + ulcorner q -- llcorner q -- cycle ; + path b ; b := llcorner p -- lrcorner p -- + lrcorner q -- llcorner q -- cycle ; + path c ; c := lrcorner p -- urcorner p -- + urcorner q -- lrcorner q -- cycle ; + path d ; d := ulcorner p -- urcorner p -- + urcorner q -- ulcorner q -- cycle ; + path e ; e := llcorner p -- lrcorner p -- + urcorner p -- urcorner q -- + lrcorner q -- llcorner q -- cycle ; + path f ; f := llcorner p -- ulcorner p -- + urcorner p -- urcorner q -- + ulcorner q -- llcorner q -- cycle ; + + linecap := butt ; pickup pencircle scaled back_linewidth ; + + if back_type=1 : + + fill p withcolor back_fillcolor ; + fill a withcolor back_leftcolor ; + fill b withcolor back_bottomcolor ; + fill c withcolor back_rightcolor ; + fill d withcolor back_topcolor ; + draw a withcolor back_linecolor ; + draw d withcolor back_linecolor ; + draw b withcolor back_linecolor ; + draw c withcolor back_linecolor ; + + elseif back_type=2 : + + fill p withcolor back_fillcolor ; + fill e withcolor back_bottomcolor ; + fill f withcolor back_topcolor ; + draw e withcolor back_linecolor ; + draw f withcolor back_linecolor ; + + elseif back_type=3 : + + fill v withcolor back_nillcolor ; + fill w withcolor back_fillcolor ; + draw v withcolor back_linecolor ; + draw w withcolor back_linecolor ; + + elseif back_type=4 : + + fill t withcolor back_nillcolor ; + fill u withcolor back_fillcolor ; + draw t withcolor back_linecolor ; + draw u withcolor back_linecolor ; + + elseif back_type=5 : + + t := t rotatedaround(center t,180) ; + u := u rotatedaround(center u,180) ; + + fill t withcolor back_nillcolor ; + fill u withcolor back_fillcolor ; + draw t withcolor back_linecolor ; + draw u withcolor back_linecolor ; + + elseif back_type=6 : + + r := r rotatedaround(center r,180) ; + s := s rotatedaround(center s,180) ; + + fill r withcolor back_nillcolor ; + fill s withcolor back_fillcolor ; + draw r withcolor back_linecolor ; + draw s withcolor back_linecolor ; + + elseif back_type=7 : + + fill r withcolor back_nillcolor ; + fill s withcolor back_fillcolor ; + draw r withcolor back_linecolor ; + draw s withcolor back_linecolor ; + +fi ; + +enddef ; + +endinput ; + +beginfig (1) ; + +some_double_back (1, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, .6white, .7white, .6white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (2, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, .6white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (3, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (4, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (5, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (6, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (7, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +currentpicture := currentpicture shifted (0,-3cm) ; + +some_double_back (8, 4.5cm, 1.5cm, .25cm, 1mm, + .5white, .8white, .7white, white, white, white) + +endfig ; + +end . diff --git a/metapost/context/mp-butt.mp b/metapost/context/mp-butt.mp new file mode 100644 index 000000000..cf580211e --- /dev/null +++ b/metapost/context/mp-butt.mp @@ -0,0 +1,75 @@ +%D \module +%D [ file=mp-butt.mp, +%D version=2000.05.31, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=buttons, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +if unknown context_tool : input mp-tool ; fi ; +if known context_butt : endinput ; fi ; + +boolean context_butt ; context_butt := true ; + +def some_button (expr button_type , + button_size , + button_linecolor , + button_fillcolor ) = + + numeric button_linewidth ; button_linewidth := button_size/10 ; + + drawoptions (withpen pencircle scaled button_linewidth + withcolor button_linecolor) ; + + path p ; p := unitsquare scaled button_size ; + numeric d ; d := button_size ; + numeric l ; l := button_linewidth ; + + fill p withcolor button_fillcolor ; draw p ; + + if button_type=101 : + draw (d-2l,2l)--(2l,.5d)--(d-2l,d-2l)--cycle ; + elseif button_type=102 : + draw (2l,2l)--(d-2l,.5d)--(2l,d-2l)--cycle ; + elseif button_type=103 : + for i=2l step 2l until d-2l : + draw (2l,i)--(2l ,i) ; + draw (4l,i)--(d-2l,i) ; + endfor ; + elseif button_type=104 : + for i=2l step 2l until d-2l : + draw (2l ,i)--(d/2-l,i) ; + draw (d/2+l,i)--(d-2l ,i) ; + endfor ; + elseif button_type=105 : + fill fullcircle scaled (.2d) shifted (.5d,.7d) ; + fill fullcircle xscaled (.6d) yscaled d shifted (.5d,0) ; + clip currentpicture to p ; + draw p ; + elseif button_type=106 : + draw (2l,2l)--(d-2l,d-2l) ; + draw (d-2l,2l)--(2l,d-2l) ; + elseif button_type=107 : + p := (3l,d-2l)--(d-3l,d-2l)--(.5d,4l)--cycle ; + fill p ; draw p ; + draw (.5d,2l) ; + elseif button_type=108 : + draw (.5d,2l)--(d-2l,d-2l)--(2l,d-2l)--cycle ; + elseif button_type=109 : + draw (.5d,d-2l)--(d-2l,2l)--(2l,2l)--cycle ; + elseif button_type=110 : + button_linewidth := button_linewidth/2 ; + draw p enlarged (-2l,-l) ; + for i=2l step l until d-2l : + draw (3l,i)--(d-3l,i) ; + endfor ; + fi ; + +enddef ; + +endinput ; diff --git a/metapost/context/mp-char.mp b/metapost/context/mp-char.mp new file mode 100644 index 000000000..8c0d53f75 --- /dev/null +++ b/metapost/context/mp-char.mp @@ -0,0 +1,968 @@ +%D \module +%D [ file=mp-char.mp, +%D version=1998.10.10, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=charts, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +if unknown context_tool : input mp-tool ; fi ; +if unknown context_shap : input mp-shap ; fi ; +if known context_char : endinput ; fi ; + +boolean context_char ; context_char := true ; + +vardef enlarged_path (expr p, w) = % NAAR mp-tool + (llcorner p shifted (-w,-w) -- + lrcorner p shifted ( w,-w) -- + urcorner p shifted ( w, w) -- + ulcorner p shifted (-w, w) -- cycle) +enddef; + +secondarydef p peepholed q = + begingroup ; + save start ; pair start ; start := point 0 of p ; + %drawdot start scaled_to_grid withpen pencircle scaled 2shape_line_width withcolor red ; + if xpart start >= xpart center p : + if ypart start >= ypart center p : + urcorner q -- ulcorner q -- llcorner q -- lrcorner q -- + reverse p -- lrcorner q -- cycle + else : + lrcorner q -- urcorner q -- ulcorner q -- llcorner q -- + reverse p -- llcorner q -- cycle + fi + else : + if ypart start > ypart center p : + ulcorner q -- llcorner q -- lrcorner q -- urcorner q -- + reverse p -- urcorner q -- cycle + else : + llcorner q -- lrcorner q -- urcorner q -- ulcorner q -- + reverse p -- ulcorner q -- cycle + fi + fi + endgroup +enddef ; + +boolean intersection_found ; + +secondarydef p intersection_point q = + begingroup + save x_, y_ ; + (x_,y_) = p intersectiontimes q ; + if x_<0 : + intersection_found := false ; + center p % origin + else : + intersection_found := true ; + .5[point x_ of p, point y_ of q] + fi + endgroup +enddef ; + +current_position := 0 ; + +def save_text_position (expr p) = % beware: clip shift needed + current_position := current_position + 1 ; + savedata + "\MPposition{" & decimal current_position & "}{" + & decimal xpart p & "}{" + & decimal ypart p & "}" ; +enddef ; + +%D settings + +grid_width := 60pt ; +grid_height := 40pt ; + +shape_width := 45pt ; +shape_height := 30pt ; + +chart_offset := 2pt ; + +color chart_background_color ; chart_background_color := white ; + +%D test mode + +boolean show_mid_points ; show_mid_points := false ; +boolean show_con_points ; show_con_points := false ; +boolean show_all_points ; show_all_points := false ; + +%D shapes + +color shape_line_color, shape_fill_color ; + +shape_line_width := 2pt ; +shape_line_color := .5white ; +shape_fill_color := .9white ; + +shape_node := 0 ; +shape_action := 24 ; +shape_procedure := 5 ; +shape_product := 12 ; +shape_decision := 14 ; +shape_archive := 19 ; +shape_loop := 35 ; +shape_wait := 6 ; +shape_subprocedure := 20 ; shape_sub_procedure := 20 ; +shape_singledocument := 32 ; shape_single_document := 32 ; +shape_multidocument := 33 ; shape_multi_document := 33 ; +shape_right := 66 ; +shape_left := 67 ; +shape_up := 68 ; +shape_down := 69 ; + +% vardef some_shape_path (expr type) == imported from mp-shap + +def show_shapes (expr n) = + + begin_chart(n,8,10) ; + show_con_points := true ; + for i=0 upto 7 : + for j=0 upto 9 : + new_shape(i+1,j+1,i*10+j); + endfor ; + endfor ; + end_chart ; + +enddef ; + +%D connections + +color connection_line_color ; + +connection_line_width := shape_line_width ; +connection_line_color := .8white ; +connection_smooth_size := 5pt ; +connection_arrow_size := 4pt ; +connection_dash_size := 3pt ; + +max_x := 6 ; +max_y := 4 ; + +numeric xypoint ; xypoint := 0 ; + +pair xypoints [] ; + +boolean xyfree [][] ; +path xypath [][] ; +numeric xysx [][] ; +numeric xysy [][] ; +color xyfill [][] ; +color xydraw [][] ; +numeric xyline [][] ; +boolean xypeep [][] ; + +numeric cpath ; cpath := 0 ; +path cpaths [] ; +numeric cline [] ; +color ccolor [] ; +boolean carrow [] ; +boolean cdash [] ; +boolean ccross [] ; + +boolean smooth ; smooth := true ; +boolean peepshape ; peepshape := false ; +boolean arrowtip ; arrowtip := true ; +boolean dashline ; dashline := false ; +boolean forcevalid ; forcevalid := false ; +boolean touchshape ; touchshape := false ; +boolean showcrossing ; showcrossing := false ; + +picture dash_pattern ; + +boolean reverse_y ; reverse_y := true ; + +def y_pos (expr y) = + if reverse_y : max_y + 1 - y else : y fi +enddef ; + +def initialize_grid (expr maxx, maxy) = + begingroup ; + save i, j ; + max_x := maxx ; + max_y := maxy ; + for x=1 upto max_x : + for y=1 upto max_y : + xyfree [x][y] := true ; + xyfill [x][y] := shape_fill_color ; + xydraw [x][y] := shape_line_color ; + xyline [x][y] := shape_line_width ; + endfor ; + endfor ; + endgroup ; +enddef ; + +def scaled_to_grid = + xscaled grid_width yscaled grid_height +enddef ; + +def xy_offset (expr x, y) = + (x+.5,y+.5) +enddef ; + +def draw_shape (expr x, yy, p, sx, sy) = + begingroup ; + save y ; + y := y_pos(yy) ; + xypath [x][y] := (p xscaled sx yscaled sy) shifted xy_offset(x,y) ; + xyfree [x][y] := false ; + xysx [x][y] := sx ; + xysy [x][y] := sy ; + xyfill [x][y] := shape_fill_color ; + xydraw [x][y] := shape_line_color ; + xyline [x][y] := shape_line_width ; + xypeep [x][y] := peepshape ; + endgroup ; +enddef ; + +vardef i_point (expr x, y, p, t) = + begingroup ; + save q, ok ; + pair q ; + boolean ok ; + q := xypath[x][y] intersection_point ((p) shifted xy_offset(x,y)) ; + ok := true ; +% if xpart q < -.5 : ok := false ; q := (-.45,ypart q) fi ; +% if xpart q > .5 : ok := false ; q := ( .45,ypart q) fi ; +% if ypart q < -.5 : ok := false ; q := (xpart q,-.45) fi ; +% if ypart q > .5 : ok := false ; q := (xpart q, .45) fi ; + if not ok : + message (t & " of shape (" & decimal x & "," & decimal y & ") limited") ; + fi ; + q + endgroup +enddef ; + +vardef trimmed (expr x, y, z, t) = + if touchshape and t : xyline[x][y]/z else : epsilon fi +enddef ; + +zfactor := 1/3 ; + +vardef xy_bottom (expr x, y, z, t) = + i_point (x, y, ((0,0)--(0,-2)) shifted (zfactor*z*xysx[x][y],0), "bottom") + shifted(0,-trimmed(x,y,grid_height,t)) +enddef ; + +vardef xy_top (expr x, y, z, t) = + i_point (x, y, ((0,0)--(0,2)) shifted (zfactor*z*xysx[x][y],0), "top") + shifted(0,trimmed(x,y,grid_height,t)) +enddef ; + +vardef xy_left (expr x, y, z, t) = + i_point (x, y, ((0,0)--(-2,0)) shifted (0,zfactor*z*xysy[x][y]), "left") + shifted(-trimmed(x,y,grid_width,t),0) +enddef ; + +vardef xy_right (expr x, y, z, t) = + i_point (x, y, ((0,0)--(2,0)) shifted (0,zfactor*z*xysy[x][y]), "right") + shifted(trimmed(x,y,grid_width,t),0) +enddef ; + +def flush_shapes = + for x=1 upto max_x : + for y=1 upto max_y : + flush_shape (x, y) ; + endfor ; + endfor ; +enddef ; + +def draw_connection_point (expr x, y, z) = + pickup pencircle scaled if (z=0): 2 fi xyline[x][y] ; + drawdot xy_bottom(x,y,z,false) scaled_to_grid withcolor (1,0,0) ; + drawdot xy_top (x,y,z,false) scaled_to_grid withcolor (0,1,0) ; + drawdot xy_left (x,y,z,false) scaled_to_grid withcolor (0,0,1) ; + drawdot xy_right (x,y,z,false) scaled_to_grid withcolor (1,1,0) ; +enddef ; + +def flush_shape (expr x, yy) = + begingroup ; + save y ; + y := y_pos(yy) ; + if not xyfree[x][y] : + pickup pencircle scaled xyline[x][y] ; + if xypeep[x][y] : + fill (xypath[x][y] peepholed (unitsquare shifted (x,y))) + scaled_to_grid withpen pencircle scaled 0 + withcolor chart_background_color ; + else : + fill xypath[x][y] scaled_to_grid withcolor xyfill[x][y] ; + fi ; + draw xypath[x][y] scaled_to_grid withcolor xydraw[x][y] ; + if show_con_points or show_all_points : + draw_connection_point (x, y, 0) ; + fi ; + if show_all_points : + for i=-1 upto 1 : + draw_connection_point (x, y, i) ; + endfor ; + fi ; + fi ; + endgroup ; +enddef ; + +vardef points_initialized (expr xfrom, yfrom, xto, yto, n) = + if not xyfree[xfrom][yfrom] and not xyfree[xto][yto] : + xypoint := n ; true + else : + xypoint := 0 ; false + fi +enddef ; + +def collapse_points = + % remove redundant points + n := 1 ; + for i=2 upto xypoint: + if not (xypoints[i]=xypoints[n]) : + n := n + 1 ; + xypoints[n] := xypoints[i] + fi ; + endfor ; + xypoint := n ; + % make straight lines + if xypoints[2]=xypoints[xypoint-1] : + xypoints[3] := xypoints[xypoint] ; + xypoint := 3 ; + fi ; +enddef ; + +vardef smoothed (expr a,b) = + sx := connection_smooth_size/grid_width ; + sy := connection_smooth_size/grid_height ; + if ypart a = ypart b : + a shifted (if xpart a >= xpart b : - fi sx,0) + else : + a shifted (0,if ypart a >= ypart b : - fi sy) + fi +enddef ; + +vardef trim_points = + begingroup + save p, a, b, d, i ; path p ; pair d ; + p := for i=1 upto xypoint-1 : xypoints[i]-- endfor xypoints[xypoint] ; + if touchshape : + a := shape_line_width/grid_width ; + b := shape_line_width/grid_height ; + else : + a := epsilon ; + b := epsilon ; + fi ; + d := direction infinity of p ; + xypoints[xypoint] := xypoints[xypoint] shifted + if xpart d < 0 : (+a,0) ; + elseif xpart d > 0 : (-a,0) ; + elseif ypart d < 0 : (0,+b) ; + elseif ypart d > 0 : (0,-b) ; + else : origin ; + fi ; + d := direction 0 of p ; + xypoints[1] := xypoints[1] shifted + if xpart d < 0 : (-a,0) ; + elseif xpart d > 0 : (+a,0) ; + elseif ypart d < 0 : (0,-b) ; + elseif ypart d > 0 : (0,+b) ; + else : origin ; + fi ; + endgroup +enddef ; + +vardef trim_points = enddef ; + +vardef connection_path = + if reverse_connection : reverse fi (xypoints[1]-- + for i=2 upto xypoint-1 : + if smooth : + smoothed(xypoints[i],xypoints[i-1]) .. + controls xypoints[i] and xypoints[i] .. + smoothed(xypoints[i],xypoints[i+1]) -- + else : + xypoints[i]-- + fi + endfor + xypoints[xypoint]) +enddef ; + +def draw_connection = + if xypoint>0 : + collapse_points ; + trim_points ; + cpath := cpath + 1 ; + cpaths[cpath] := connection_path scaled_to_grid ; + cline[cpath] := connection_line_width ; + ccolor[cpath] := connection_line_color ; + carrow[cpath] := arrowtip ; + cdash[cpath] := dashline ; + ccross[cpath] := showcrossing ; + else : + message("no connection defined") ; + fi ; + reverse_connection := false ; +enddef ; + +def flush_connections = + pair ip ; + boolean crossing ; + ahlength := connection_arrow_size ; + dash_pattern := dashpattern(on connection_dash_size off connection_dash_size ) ; + for i=1 upto cpath : + if ccross[i] : + crossing := false ; + for j=1 upto i : + %if not ((point infinity of cpaths[i] = point infinity of cpaths[j]) or + % (point 0 of cpaths[i] = point 0 of cpaths[j])) : + if not (point infinity of cpaths[i] = point infinity of cpaths[j]) : + ip := cpaths[i] intersection_point cpaths[j] ; + if intersection_found : crossing := true fi ; + fi ; + endfor ; + if crossing : + pickup pencircle scaled 2cline[i] ; +% draw cpaths[i] withcolor chart_background_color ; +path cp ; cp := cpaths[i] ; +cp := cp cutbefore point .05 length cp of cp ; +cp := cp cutafter point .95 length cp of cp ; +draw cp withcolor chart_background_color ; + fi ; + fi ; + pickup pencircle scaled cline[i] ; + if carrow[i] : + if cdash[i] : + drawarrow cpaths[i] withcolor ccolor[i] dashed dash_pattern ; + else : + drawarrow cpaths[i] withcolor ccolor[i] ; + fi ; + else : + if cdash[i] : + draw cpaths[i] withcolor ccolor[i] dashed dash_pattern ; + else : + draw cpaths[i] withcolor ccolor[i] ; + fi ; + fi ; + draw_midpoint (i) ; + endfor ; +enddef ; + +def draw_midpoint (expr n) = + begingroup + save p ; + pair p ; + p := point .5*length(cpaths[n]) of cpaths[n]; + pickup pencircle scaled 2cline[n] ; + save_text_position (p) ; + if show_mid_points : + drawdot p withcolor .7white ; + fi ; + endgroup ; +enddef ; + +boolean reverse_connection ; reverse_connection := false ; + +vardef up_on_grid (expr n) = + (xpart xypoints[n],(ypart xypoints[n]+1) div 1) +enddef ; + +vardef down_on_grid (expr n) = + (xpart xypoints[n],(ypart xypoints[n]) div 1) +enddef ; + +vardef left_on_grid (expr n) = + ((xpart xypoints[n]) div 1, ypart xypoints[n]) +enddef ; + +vardef right_on_grid (expr n) = + ((xpart xypoints[n]+1) div 1, ypart xypoints[n]) +enddef ; + +vardef x_on_grid (expr n, xfrom, xto, zfrom) = + if (xfrom=xto) and not (zfrom=0) : + if (zfrom=1) : right_on_grid(2) else : left_on_grid(2) fi + elseif xpart xypoints[1] < xpart xypoints[6] : + right_on_grid(n) + else : + left_on_grid(n) + fi +enddef ; + +vardef y_on_grid (expr n, yfrom, yto, zfrom) = + if (yfrom=yto) and not (zfrom=0) : + if (zfrom=1) : up_on_grid(2) else : down_on_grid(2) fi + elseif ypart xypoints[1] < ypart xypoints[6] : + up_on_grid(n) + else : + down_on_grid(n) + fi +enddef ; + +vardef xy_on_grid (expr n, m) = + (xpart xypoints[n], ypart xypoints[m]) +enddef ; + +vardef down_to_grid (expr a,b) = + (xpart xypoints[a], + ypart xypoints[if ypart xypoints[a]<ypart xypoints[b]:a else:b fi]) +enddef ; + +vardef up_to_grid (expr a,b) = + (xpart xypoints[a], + ypart xypoints[if ypart xypoints[a]>ypart xypoints[b]:a else:b fi]) +enddef ; + +vardef left_to_grid (expr a,b) = + (xpart xypoints[if xpart xypoints[a]<xpart xypoints[b]:a else:b fi], + ypart xypoints[a]) +enddef ; + +vardef right_to_grid (expr a,b) = + (xpart xypoints[if xpart xypoints[a]>xpart xypoints[b]:a else:b fi], + ypart xypoints[a]) +enddef ; + +vardef valid_connection (expr xfrom, yfrom, xto, yto) = + begingroup ; + save ok, vc, pp ; + boolean ok ; + % check for slanted lines + ok := true ; + for i=1 upto xypoint-1 : + if not ((xpart xypoints[i]=xpart xypoints[i+1]) or + (ypart xypoints[i]=ypart xypoints[i+1])) : ok := false ; + fi ; + endfor ; + if not ok : + %message("slanted"); + false + elseif forcevalid : + %message("force"); + true + elseif (xfrom=xto) and (yfrom=yto) : + %message("self"); + false + else : + % check for crossing shapes + pair vc ; + path pp ; + + pair xyfirst, xylast ; + xyfirst := xypoints[1] ; + xylast := xypoints[xypoint] ; + trim_points ; + pp := for i=1 upto xypoint-1 : xypoints[i]-- endfor xypoints[xypoint] ; + xypoints[1] := xyfirst ; + xypoints[xypoint] := xylast ; + + for i=1 upto max_x : + for j=1 upto max_y : +if not ( ( (i,j) = (xfrom,yfrom) ) or ( (i,j) = (yfrom,yto) ) ) : + if not xyfree[i][j] : + vc := pp intersection_point xypath[i][j] ; + if intersection_found : ok := false fi ; + fi ; +fi ; + endfor ; + endfor ; + %if not ok: message("crossing") ; fi ; + ok + fi + endgroup +enddef ; + +def connect_top_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_top(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_bottom(xto,yto,zto,true) ; + xypoints[2] := up_on_grid(1) ; + xypoints[5] := down_on_grid(6) ; + xypoints[3] := up_to_grid(2,5) ; + xypoints[4] := up_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ; + xypoints[4] := xy_on_grid(3,5) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_left_right (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_right(xto,yto,zto,true) ; + xypoints[2] := left_on_grid(1) ; + xypoints[5] := right_on_grid(6) ; + xypoints[3] := left_to_grid(2,5) ; + xypoints[4] := left_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := y_on_grid(2,yfrom,yto,zfrom) ; + xypoints[4] := xy_on_grid(5,3) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_left_top (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,5) : + xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; + xypoints[5] := xy_top(xto,yto,zto,true) ; + xypoints[2] := left_on_grid(1) ; + xypoints[4] := up_on_grid(5) ; + xypoints[3] := left_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := xy_on_grid(2,4) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_left_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,5) : + xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; + xypoints[5] := xy_bottom(xto,yto,zto,true) ; + xypoints[2] := left_on_grid(1) ; + xypoints[4] := down_on_grid(5) ; + xypoints[3] := left_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := xy_on_grid(2,4) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_right_top (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,5) : + xypoints[1] := xy_right(xfrom,yfrom,zfrom,true) ; + xypoints[5] := xy_top(xto,yto,zto,true) ; + xypoints[2] := right_on_grid(1) ; + xypoints[4] := up_on_grid(5) ; + xypoints[3] := right_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := xy_on_grid(2,4) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_right_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,5) : + xypoints[1] := xy_right(xfrom,yfrom,zfrom,true) ; + xypoints[5] := xy_bottom(xto,yto,zto,true) ; + xypoints[2] := right_on_grid(1) ; + xypoints[4] := down_on_grid(5) ; + xypoints[3] := right_to_grid(2,5) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := xy_on_grid(2,4) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_left_left (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_left(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_left(xto,yto,zto,true) ; + xypoints[2] := left_on_grid(1) ; + xypoints[5] := left_on_grid(6) ; + xypoints[3] := left_to_grid(2,5) ; + xypoints[4] := left_to_grid(5,2) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := y_on_grid(2,yfrom,yto,zfrom) ; + xypoints[4] := xy_on_grid(5,3) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_right_right (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_right(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_right(xto,yto,zto,true) ; + xypoints[2] := right_on_grid(1) ; + xypoints[5] := right_on_grid(6) ; + xypoints[3] := right_to_grid(2,5) ; + xypoints[4] := right_to_grid(5,2) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := y_on_grid(2,yfrom,yto,zfrom) ; + xypoints[4] := xy_on_grid(5,3) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_top_top (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_top(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_top(xto,yto,zto,true) ; + xypoints[2] := up_on_grid(1) ; + xypoints[5] := up_on_grid(6) ; + xypoints[3] := up_to_grid(2,5) ; + xypoints[4] := up_to_grid(5,2) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ; + xypoints[4] := xy_on_grid(3,5) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_bottom_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = + yfrom := y_pos(yyfrom) ; yto := y_pos(yyto) ; + if points_initialized(xfrom,yfrom,xto,yto,6) : + xypoints[1] := xy_bottom(xfrom,yfrom,zfrom,true) ; + xypoints[6] := xy_bottom(xto,yto,zto,true) ; + xypoints[2] := down_on_grid(1) ; + xypoints[5] := down_on_grid(6) ; + xypoints[3] := down_to_grid(2,5) ; + xypoints[4] := down_to_grid(5,2) ; + if not valid_connection(xfrom,yfrom,xto,yto) : + xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ; + xypoints[4] := xy_on_grid(3,5) ; + fi ; + draw_connection ; + fi ; +enddef ; + +def connect_bottom_top (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_top_bottom (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def connect_right_left (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_left_right (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def connect_top_left (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_left_top (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def connect_bottom_left (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_left_bottom (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def connect_top_right (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_right_top (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def connect_bottom_right (expr xfrom,yfrom,zfrom) (expr xto,yto,zto) = + reverse_connection := true ; + connect_right_bottom (xto,yto,zto) (xfrom,yfrom,zfrom) ; +enddef ; + +def draw_test_shape (expr x, y) = + draw_shape(x,y,fullcircle, .7, .7) ; +enddef ; + +def draw_test_shapes = + for i=1 upto max_x : + for j=1 upto max_y : + draw_test_shape(i,j) ; + endfor ; + endfor ; +enddef; + +def draw_test_area = + pickup pencircle scaled .5shape_line_width ; + draw (unitsquare xscaled max_x yscaled max_y shifted (1,1)) + scaled_to_grid withcolor blue ; +enddef ; + +def show_connection (expr n, m) = + + begin_chart(100+n,6,6) ; + + draw_test_area ; + + smooth := true ; + arrowtip := true ; + dashline := true ; + + draw_test_shape(2,2) ; draw_test_shape(4,5) ; + draw_test_shape(3,3) ; draw_test_shape(5,1) ; + draw_test_shape(2,5) ; draw_test_shape(1,3) ; + draw_test_shape(6,2) ; draw_test_shape(4,6) ; + + if (m=1) : + connect_top_bottom (2,2,0) (4,5,0) ; + connect_top_bottom (3,3,0) (5,1,0) ; + connect_top_bottom (2,5,0) (1,3,0) ; + connect_top_bottom (6,2,0) (4,6,0) ; + elseif (m=2) : + connect_top_top (2,2,0) (4,5,0) ; + connect_top_top (3,3,0) (5,1,0) ; + connect_top_top (2,5,0) (1,3,0) ; + connect_top_top (6,2,0) (4,6,0) ; + elseif (m=3) : + connect_bottom_bottom (2,2,0) (4,5,0) ; + connect_bottom_bottom (3,3,0) (5,1,0) ; + connect_bottom_bottom (2,5,0) (1,3,0) ; + connect_bottom_bottom (6,2,0) (4,6,0) ; + elseif (m=4) : + connect_left_right (2,2,0) (4,5,0) ; + connect_left_right (3,3,0) (5,1,0) ; + connect_left_right (2,5,0) (1,3,0) ; + connect_left_right (6,2,0) (4,6,0) ; + elseif (m=5) : + connect_left_left (2,2,0) (4,5,0) ; + connect_left_left (3,3,0) (5,1,0) ; + connect_left_left (2,5,0) (1,3,0) ; + connect_left_left (6,2,0) (4,6,0) ; + elseif (m=6) : + connect_right_right (2,2,0) (4,5,0) ; + connect_right_right (3,3,0) (5,1,0) ; + connect_right_right (2,5,0) (1,3,0) ; + connect_right_right (6,2,0) (4,6,0) ; + elseif (m=7) : + connect_left_top (2,2,0) (4,5,0) ; + connect_left_top (3,3,0) (5,1,0) ; + connect_left_top (2,5,0) (1,3,0) ; + connect_left_top (6,2,0) (4,6,0) ; + elseif (m=8) : + connect_left_bottom (2,2,0) (4,5,0) ; + connect_left_bottom (3,3,0) (5,1,0) ; + connect_left_bottom (2,5,0) (1,3,0) ; + connect_left_bottom (6,2,0) (4,6,0) ; + elseif (m=9) : + connect_right_top (2,2,0) (4,5,0) ; + connect_right_top (3,3,0) (5,1,0) ; + connect_right_top (2,5,0) (1,3,0) ; + connect_right_top (6,2,0) (4,6,0) ; + else : + connect_right_bottom (2,2,0) (4,5,0) ; + connect_right_bottom (3,3,0) (5,1,0) ; + connect_right_bottom (2,5,0) (1,3,0) ; + connect_right_bottom (6,2,0) (4,6,0) ; + fi ; + + end_chart ; + +enddef ; + +def show_connections = + for f=1 upto 10 : + show_connection(f,f) ; + endfor ; +enddef ; + +%D charts + +def clip_chart (expr minx, miny, maxx, maxy) = + cmin_x := minx ; + cmax_x := maxx ; + cmin_y := miny ; + cmax_y := maxy ; +enddef ; + +def begin_chart (expr n, maxx, maxy) = + chart_figure := n ; + chart_scale := 1 ; + if chart_figure>0: beginfig(chart_figure) ; fi ; + initialize_grid (maxx, maxy) ; + bboxmargin := 0 ; + cmin_x := 1 ; + cmax_x := maxx ; + cmin_y := 1 ; + cmax_y := maxy ; +enddef ; + +def end_chart = + flush_shapes ; + flush_connections ; + cmin_x := cmin_x ; + cmax_x := cmin_x+cmax_x ; + cmin_y := cmin_y-1 ; + cmax_y := cmin_y+cmax_y ; + if reverse_y : + cmin_y := y_pos(cmin_y) ; + cmax_y := y_pos(cmax_y) ; + fi ; + path p ; + p := (((cmin_x,cmin_y)--(cmax_x,cmin_y)-- + (cmax_x,cmax_y)--(cmin_x,cmax_y)--cycle)) + scaled_to_grid ; + %draw p withcolor red ; + p := enlarged_path (p,chart_offset) ; + clip currentpicture to p ; + setbounds currentpicture to p ; + savedata + "\MPclippath{" & + decimal xpart llcorner p & "}{" & + decimal ypart llcorner p & "}{" & + decimal xpart urcorner p & "}{" & + decimal ypart urcorner p & "}" ; + savedata + "\MPareapath{" & + decimal (xpart llcorner p + 2chart_offset) & "}{" & + decimal (ypart llcorner p + 2chart_offset) & "}{" & + decimal (xpart urcorner p - 2chart_offset) & "}{" & + decimal (ypart urcorner p - 2chart_offset) & "}" ; + currentpicture := currentpicture scaled chart_scale ; + if chart_figure>0: endfig ; fi ; +enddef ; + +def new_shape (expr x, y, n) = + if known n : + if (x>0) and (x<=max_x) and (y>0) and (y<=max_y) : + sx := shape_width/grid_width ; + sy := shape_height/grid_height ; + draw_shape(x,y,some_shape_path(n), sx, sy) ; + else : + message ("shape outside grid ignored") ; + fi ; + else + message ("shape not known" ) ; + fi ; +enddef ; + +def begin_sub_chart = + begingroup ; + save shape_line_width , connection_line_width ; + save shape_line_color, shape_fill_color, connection_line_color ; + color shape_line_color, shape_fill_color, connection_line_color ; + save smooth, arrowtip, dashline, peepshape ; + boolean smooth, arrowtip, dashline, peepshape ; +enddef ; + +def end_sub_chart = + endgroup ; +enddef ; + +%D done + +endinput ; + +%D testing + +show_shapes(100) ; + +end + +%D more testing + +show_connections ; + +begin_chart (1,4,5) ; + %clip_chart(1,1,1,2) ; + new_shape (1,1,31) ; + new_shape (1,2,3) ; + new_shape (4,4,5) ; + connect_top_left (1,1,0) (4,4,0) ; + connect_bottom_top (1,2,0) (4,4,0) ; + connect_left_right (1,2,0) (1,1,0) ; +end_chart ; + +end diff --git a/metapost/context/mp-core.mp b/metapost/context/mp-core.mp new file mode 100644 index 000000000..d4045d3da --- /dev/null +++ b/metapost/context/mp-core.mp @@ -0,0 +1,232 @@ +%D \module +%D [ file=mp-core.mp, +%D version=1999.08.12, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=core interfacing, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +if unknown context_tool : input mp-tool ; fi ; +if known context_core : endinput ; fi ; + +boolean context_core ; context_core := true ; + +pair lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ; +path pxy[] ; +numeric hxy[], wxy[], dxy[], nxy[] ; + +def box_found (expr n,x,y,w,h,d) = + not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0)) +enddef ; + +def initialize_box_pos (expr pos,n,x,y,w,h,d) = + pair lxy, rxy, cxy, llxy, lrxy, ulxy, urxy ; + path pxy ; numeric hxy, wxy, dxy, nxy; + lxy := (x,y) ; lxy[pos] := lxy ; + llxy := (x,y-d) ; llxy[pos] := llxy ; + lrxy := (x+w,y-d) ; lrxy[pos] := lrxy ; + urxy := (x+w,y+h) ; urxy[pos] := urxy ; + ulxy := (x,y+h) ; ulxy[pos] := ulxy ; + wxy := w ; wxy[pos] := wxy ; + hxy := h ; hxy[pos] := hxy ; + dxy := d ; dxy[pos] := dxy ; + rxy := lxy shifted (wxy,0) ; rxy[pos] := rxy ; + pxy := llxy--lrxy--urxy--ulxy--cycle ; pxy[pos] := pxy ; + cxy := center pxy ; cxy[pos] := cxy ; + nxy := n ; nxy[pos] := nxy ; +enddef ; + +def initialize_box (expr n,x,y,w,h,d) = + + numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ; + +enddef ; + +def initialize_area (expr fn,fx,fy,fw,fh,fd, + tn,tx,ty,tw,th,td) = + + numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; + numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; + + do_initialize_area (fpos, tpos) ; + +enddef ; + +def do_initialize_area (expr fpos, tpos) = + lxy := lxy[fpos] ; + llxy := (xpart llxy[fpos], ypart llxy[tpos]) ; + lrxy := lrxy[tpos] ; + urxy := (xpart urxy[tpos], ypart urxy[fpos]) ; + ulxy := ulxy[fpos] ; + wxy := xpart lrxy - xpart llxy ; + hxy := hxy[fpos] ; + dxy := dxy[tpos] ; + rxy := lxy shifted (wxy,0) ; + pxy := llxy--lrxy--urxy--ulxy--cycle ; + cxy := center pxy ; +enddef ; + +def initialize_par (expr fn,fx,fy,fw,fh,fd, ln,lx,ly,lw,lh,ld, + rn,rx,ry,rw,rh,rd, tn,tx,ty,tw,th,td) = + + numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; + numeric lpos ; lpos := 3 ; initialize_box_pos(lpos,ln,lx,ly,lw,lh,ld) ; + numeric rpos ; rpos := 4 ; initialize_box_pos(rpos,rn,rx,ry,rw,rh,rd) ; + numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; + + do_initialize_area (fpos, tpos) ; + do_initialize_par (fpos, lpos, rpos, tpos) ; + +enddef ; + +def do_initialize_par (expr fpos, lpos, rpos, tpos) = + + pair leftxy, righxy ; path txy, mxy, bxy ; % top mid bot + + leftxy := if xpart ulxy[fpos] > xpart ulxy[lpos] : ulxy[fpos] else : ulxy[lpos] fi ; + righxy := if xpart urxy[tpos] < xpart urxy[rpos] : urxy[tpos] else : urxy[rpos] fi ; + + pxy := origin ; + + if (round(ypart llxy[fpos]) = round(ypart ulxy[tpos])) and + (round(xpart lrxy[tpos]) < round(xpart llxy[fpos])) : + + txy := llxy[fpos] -- (xpart lrxy[rpos], ypart lrxy[fpos]) -- + (xpart urxy[rpos], ypart urxy[fpos]) -- ulxy[fpos] -- cycle ; + mxy := origin ; + bxy := (xpart llxy[lpos], ypart llxy[tpos]) -- lrxy[tpos] -- + urxy[tpos] -- (xpart ulxy[lpos], ypart ulxy[tpos]) -- cycle ; + + elseif ypart llxy[fpos] = ypart llxy[tpos] : + + txy := llxy[fpos] -- lrxy[tpos] -- urxy[tpos] -- ulxy[fpos] --cycle ; + mxy := origin ; + bxy := origin ; + + else : + + txy := (xpart lrxy[rpos], ypart lrxy[fpos]) -- + (xpart urxy[rpos], ypart urxy[fpos]) -- + ulxy[fpos] -- llxy[fpos] -- cycle ; + mxy := (xpart llxy[lpos], ypart ulxy[tpos]) -- + (xpart llxy[rpos], ypart ulxy[tpos]) -- + (xpart lrxy[rpos], ypart lrxy[fpos]) -- + (xpart llxy[lpos], ypart llxy[fpos]) -- cycle ; + bxy := (xpart llxy[lpos], ypart llxy[tpos]) -- + (xpart righxy, ypart lrxy[tpos]) -- + (xpart righxy, ypart urxy[tpos]) -- + (xpart llxy[lpos], ypart ulxy[tpos]) -- cycle ; + + if (round(point 0 of bxy) = round(point 1 of bxy)) or + (round(point 0 of bxy) = round(point 2 of bxy)) : + bxy := origin ; + fi ; + + if (round(point 0 of mxy) = round(point 1 of mxy)) or + (round(point 0 of mxy) = round(point 2 of mxy)) : + mxy := origin ; + fi ; + + if (round(point 0 of txy) = round(point 1 of txy)) or + (round(point 0 of txy) = round(point 2 of txy)) : + txy := origin ; + fi ; + + if (round (length(mxy)) > 1) : + if (round (length(txy)) < 2) : + if (round (length(bxy)) < 2) : + pxy := mxy ; + else : + pxy := point 0 of bxy -- point 1 of bxy -- point 2 of bxy -- + point 1 of mxy -- point 2 of mxy -- point 3 of mxy -- + cycle ; + fi ; + else : + if (round (length(bxy)) < 2) : + pxy := point 1 of mxy -- + point 1 of txy -- point 2 of txy -- point 3 of txy -- + point 3 of mxy -- point 0 of mxy -- + cycle ; + else : + pxy := point 1 of mxy -- + point 1 of txy -- point 2 of txy -- point 3 of txy -- + point 3 of mxy -- + point 0 of bxy -- point 1 of bxy -- point 2 of bxy -- + cycle ; + fi ; + fi ; + fi ; + + fi ; + +enddef ; + +color boxfillcolor ; boxfillcolor := .8white ; +color boxlinecolor ; boxlinecolor := .8blue ; + +def draw_box = + pickup pencircle scaled .5 ; + draw pxy withcolor boxlinecolor ; + draw lxy -- rxy withcolor boxlinecolor ; +% pickup pencircle scaled 1.5 ; +% draw llxy withcolor green ; +% draw lrxy withcolor green ; +% draw urxy withcolor green ; +% draw ulxy withcolor green ; +% draw cxy withcolor red ; +% pickup pencircle scaled 1 ; +% draw lxy withcolor red ; +% draw rxy withcolor red ; +enddef ; + +def draw_par = + pickup pencircle scaled .5 ; + if length pxy > 1 : + fill pxy withcolor boxfillcolor ; draw pxy withcolor boxlinecolor ; + else : + draw_par_top ; draw_par_mid ; draw_par_bot ; + fi ; +% pickup pencircle scaled 1.5 ; +% draw llxy[lpos] withcolor red ; +% draw llxy[rpos] withcolor red ; +% draw llxy[tpos] withcolor green ; +% draw llxy[fpos] withcolor green ; +enddef ; + +def draw_par_top = + pickup pencircle scaled .5 ; + if length txy > 1 : + fill txy withcolor boxfillcolor ; draw txy withcolor boxlinecolor ; + fi ; +enddef ; + +def draw_par_mid = + pickup pencircle scaled .5 ; + if length mxy > 1 : + fill mxy withcolor boxfillcolor ; draw mxy withcolor boxlinecolor ; + fi ; +enddef ; + +def draw_par_bot = + pickup pencircle scaled .5 ; + if length bxy > 1 : + fill bxy withcolor boxfillcolor ; draw bxy withcolor boxlinecolor ; + fi ; +enddef ; + +def anchor_box (expr n,x,y,w,h,d) = +% bboxmargin := 0 ; +% setbounds currentpicture to unitsquare shifted (x,y) ; + currentpicture := currentpicture shifted (-x,-y) ; +enddef ; + +let draw_area = draw_box ; +let anchor_area = anchor_box ; +let anchor_par = anchor_box ; + +endinput ; diff --git a/metapost/context/mp-page.mp b/metapost/context/mp-page.mp new file mode 100644 index 000000000..7133ae6ff --- /dev/null +++ b/metapost/context/mp-page.mp @@ -0,0 +1,218 @@ +%D \module +%D [ file=mp-page.mp, +%D version=1999.03.10, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=page enhancements, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 module is rather preliminary and subjected to +%D changes. + +if unknown context_tool : input mp-tool ; fi ; +if known context_page : endinput ; fi ; + +boolean context_page ; context_page := true ; + +if unknown PageStateAvailable : + boolean PageStateAvailable ; PageStateAvailable := false ; +fi ; + +if unknown OnRightPage : + boolean OnRightPage ; OnRightPage := true ; +fi ; + +PageNumber := 0 ; +PaperHeight := 845.04684pt ; +PaperWidth := 597.50787pt ; +PrintPaperHeight := 845.04684pt ; +PrintPaperWidth := 597.50787pt ; +TopSpace := 71.12546pt ; +BackSpace := 71.13275pt ; +MakeupHeight := 711.3191pt ; +MakeupWidth := 426.78743pt ; +TopHeight := 0.0pt ; +TopDistance := 0.0pt ; +HeaderHeight := 56.90294pt ; +HeaderDistance := 0.0pt ; +TextHeight := 597.51323pt ; +FooterDistance := 0.0pt ; +FooterHeight := 56.90294pt ; +BottomDistance := 0.0pt ; +BottomHeight := 0.0pt ; +LeftEdgeWidth := 0.0pt ; +LeftEdgeDistance := 0.0pt ; +LeftMarginWidth := 75.58197pt ; +LeftMarginDistance := 11.99829pt ; +TextWidth := 426.78743pt ; +RightMarginDistance := 11.99829pt ; +RightMarginWidth := 75.58197pt ; +RightEdgeDistance := 0.0pt ; +RightEdgeWidth := 0.0pt ; + +PageOffset := 0.0pt ; +PageDepth := 0.0pt ; + +LeftEdge := -4 ; Top := -40 ; +LeftEdgeSeparator := -3 ; TopSeparator := -30 ; +LeftMargin := -2 ; Header := -20 ; +LeftMarginSeparator := -1 ; HeaderSeparator := -10 ; +Text := 0 ; Text := 0 ; +RightMarginSeparator := +1 ; FooterSeparator := +10 ; +RightMargin := +2 ; Footer := +20 ; +RightEdgeSeparator := +3 ; BottomSeparator := +30 ; +RightEdge := +4 ; Bottom := +40 ; + +Margin := LeftMargin ; +Edge := LeftEdge ; +InnerMargin := RightMargin ; +InnerEdge := RightEdge ; +OuterMargin := LeftMargin ; +OuterEdge := LeftEdge ; + +path Area [][] ; pair Location [][] ; path Field [][] ; path Page ; +numeric HorPos ; numeric Hstep [] ; numeric Hsize [] ; +numeric VerPos ; numeric Vstep [] ; numeric Vsize [] ; + +for VerPos=Top step 10 until Bottom: + for HorPos=LeftEdge step 1 until RightEdge: + Area[HorPos][VerPos] := origin--cycle ; + Area[VerPos][HorPos] := Area[HorPos][VerPos] ; + Location[HorPos][VerPos] := origin ; + Location[VerPos][HorPos] := Location[HorPos][VerPos] ; + Field[HorPos][VerPos] := origin--cycle ; + Field[VerPos][HorPos] := Field[HorPos][VerPos] ; + endfor ; +endfor ; + +% def LoadPageState = +% scantokens "input mp-state.tmp" ; +% enddef ; + +def SwapPageState = + if not OnRightPage : + BackSpace := PaperWidth-MakeupWidth-BackSpace ; + i := LeftMarginWidth ; + LeftMarginWidth := RightMarginWidth ; + RightMarginWidth := i ; + i := LeftMarginDistance ; + LeftMarginDistance := RightMarginDistance ; + RightMarginDistance := i ; + i := LeftEdgeWidth ; + LeftEdgeWidth := RightEdgeWidth ; + RightEdgeWidth := i ; + i := LeftEdgeDistance ; + LeftEdgeDistance := RightEdgeDistance ; + RightEdgeDistance := i ; + + Margin := LeftMargin ; + Edge := LeftEdge ; + InnerMargin := RightMargin ; + InnerEdge := RightEdge ; + OuterMargin := LeftMargin ; + OuterEdge := LeftEdge ; + else : + Margin := RightMargin ; + Edge := RightEdge ; + InnerMargin := LeftMargin ; + InnerEdge := LeftEdge ; + OuterMargin := RightMargin ; + OuterEdge := RightEdge ; + fi ; +enddef ; + +def StartPage = + + if PageStateAvailable : + LoadPageState ; + SwapPageState ; + fi ; + + numeric Vsize[], Hsize[], Vstep[], Hstep[] ; + + Vsize[Top] = TopHeight ; + Vsize[TopSeparator] = TopDistance ; + Vsize[Header] = HeaderHeight ; + Vsize[HeaderSeparator] = HeaderDistance ; + Vsize[Text] = TextHeight ; + Vsize[FooterSeparator] = FooterDistance ; + Vsize[Footer] = FooterHeight ; + Vsize[BottomSeparator] = BottomDistance ; + Vsize[Bottom] = BottomHeight ; + + Vstep[Top] = Vstep[TopSeparator] +Vsize[TopSeparator] ; + Vstep[TopSeparator] = PaperHeight-TopSpace ; + Vstep[Header] = Vstep[TopSeparator] -Vsize[Header] ; + Vstep[HeaderSeparator] = Vstep[Header] -Vsize[HeaderSeparator] ; + Vstep[Text] = Vstep[HeaderSeparator]-Vsize[Text] ; + Vstep[FooterSeparator] = Vstep[Text] -Vsize[FooterSeparator] ; + Vstep[Footer] = Vstep[FooterSeparator]-Vsize[Footer] ; + Vstep[BottomSeparator] = Vstep[Footer] -Vsize[BottomSeparator] ; + Vstep[Bottom] = Vstep[BottomSeparator]-Vsize[Bottom] ; + + Hsize[LeftEdge] = LeftEdgeWidth ; + Hsize[LeftEdgeSeparator] = LeftEdgeDistance ; + Hsize[LeftMargin] = LeftMarginWidth ; + Hsize[LeftMarginSeparator] = LeftMarginDistance ; + Hsize[Text] = MakeupWidth ; + Hsize[RightMarginSeparator] = RightMarginDistance ; + Hsize[RightMargin] = RightMarginWidth ; + Hsize[RightEdgeSeparator] = RightEdgeDistance ; + Hsize[RightEdge] = RightEdgeWidth ; + + Hstep[LeftEdge] = Hstep[LeftEdgeSeparator] -Hsize[LeftEdge] ; + Hstep[LeftEdgeSeparator] = Hstep[LeftMargin] -Hsize[LeftEdgeSeparator] ; + Hstep[LeftMargin] = Hstep[LeftMarginSeparator] -Hsize[LeftMargin] ; + Hstep[LeftMarginSeparator] = Hstep[Text] -Hsize[LeftMarginSeparator] ; + Hstep[Text] = BackSpace ; + Hstep[RightMarginSeparator] = Hstep[Text] +Hsize[Text] ; + Hstep[RightMargin] = Hstep[RightMarginSeparator]+Hsize[RightMarginSeparator] ; + Hstep[RightEdgeSeparator] = Hstep[RightMargin] +Hsize[RightMargin] ; + Hstep[RightEdge] = Hstep[RightEdgeSeparator] +Hsize[RightEdgeSeparator] ; + + for VerPos=Top step 10 until Bottom: + for HorPos=LeftEdge step 1 until RightEdge: + Area[HorPos][VerPos] := unitsquare xscaled Hsize[HorPos] yscaled Vsize[VerPos] ; + Area[VerPos][HorPos] := Area[HorPos][VerPos] ; + Location[HorPos][VerPos] := (Hstep[HorPos],Vstep[VerPos]) ; + Location[VerPos][HorPos] := Location[HorPos][VerPos] ; + Field[HorPos][VerPos] := Area[HorPos][VerPos] shifted Location[HorPos][VerPos] ; + Field[VerPos][HorPos] := Field[HorPos][VerPos] ; + endfor ; + endfor ; + +% pickup pencircle scaled 0pt ; + + Page := unitsquare xscaled PaperWidth yscaled PaperHeight ; + bboxmargin := 0 ; setbounds currentpicture to Page ; + +enddef ; + +def StopPage = + + %pickup pencircle scaled 0pt ; + + bboxmargin := 0 ; setbounds currentpicture to Page ; + +enddef ; + +% obsolete + +def llEnlarged (expr p,d) = (llcorner p shifted (-d,-d)) enddef ; +def lrEnlarged (expr p,d) = (lrcorner p shifted (+d,-d)) enddef ; +def urEnlarged (expr p,d) = (urcorner p shifted (+d,+d)) enddef ; +def ulEnlarged (expr p,d) = (ulcorner p shifted (-d,+d)) enddef ; + +def Enlarged (expr p, d) = + (llEnlarged (p,d) -- + lrEnlarged (p,d) -- + urEnlarged (p,d) -- + ulEnlarged (p,d) -- cycle) +enddef ; + +endinput ; diff --git a/metapost/context/mp-shap.mp b/metapost/context/mp-shap.mp new file mode 100644 index 000000000..5b95e71aa --- /dev/null +++ b/metapost/context/mp-shap.mp @@ -0,0 +1,261 @@ +%D \module +%D [ file=mp-shap.mp, +%D version=2000.05.31, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=shapes, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +if unknown context_tool : input mp-tool ; fi ; +if known context_shap : endinput ; fi ; + +boolean context_shap ; context_shap := true ; + +vardef some_shape_path (expr type) = + + begingroup ; + + save border, xradius, yradius, + normal, mirror, rotate, + lc, rc, tc, bc, ll, lr, ur, ul, + llx, lrx, urx, ulx, lly, lry, ury, uly ; + + path border ; + + xradius := .15 ; xxradius := .10 ; + yradius := .15 ; yyradius := .10 ; + + pair ll ; ll := llcorner (unitsquare shifted (-.5,-.5)) ; + pair lr ; lr := lrcorner (unitsquare shifted (-.5,-.5)) ; + pair ur ; ur := urcorner (unitsquare shifted (-.5,-.5)) ; + pair ul ; ul := ulcorner (unitsquare shifted (-.5,-.5)) ; + + pair llx ; llx := ll shifted (xradius,0) ; + pair lly ; lly := ll shifted (0,yradius) ; + + pair lrx ; lrx := lr shifted (-xradius,0) ; + pair lry ; lry := lr shifted (0,yradius) ; + + pair urx ; urx := ur shifted (-xradius,0) ; + pair ury ; ury := ur shifted (0,-yradius) ; + + pair ulx ; ulx := ul shifted (xradius,0) ; + pair uly ; uly := ul shifted (0,-yradius) ; + + pair llxx ; llxx := ll shifted (xxradius,0) ; + pair llyy ; llyy := ll shifted (0,yyradius) ; + + pair lrxx ; lrxx := lr shifted (-xxradius,0) ; + pair lryy ; lryy := lr shifted (0,yyradius) ; + + pair urxx ; urxx := ur shifted (-xxradius,0) ; + pair uryy ; uryy := ur shifted (0,-yyradius) ; + + pair ulxx ; ulxx := ul shifted (xxradius,0) ; + pair ulyy ; ulyy := ul shifted (0,-yyradius) ; + + pair lc ; lc := ll shifted (0,.5) ; + pair rc ; rc := lr shifted (0,.5) ; + pair tc ; tc := ul shifted (.5,0) ; + pair bc ; bc := ll shifted (.5,0) ; + + def mirror (expr p) = + p rotatedaround(origin,180) + enddef ; + + def normal (expr p ) = + p + enddef ; + + def rotate (expr p) = + p rotated 45 + enddef ; + + if type= 0 : + border := normal (origin--cycle) ; + + elseif type= 5 : + border := normal (llx--lrx{right}...rc...{left}urx--ulx{left}...lc...{right}cycle) ; + elseif type= 6 : + border := normal (ll--lrx{right}...rc...{left}urx--ul--cycle) ; + elseif type= 7 : + border := mirror (ll--lrx{right}...rc...{left}urx--ul--cycle) ; + elseif type= 8 : + border := normal (lr--ury{up}...tc...{down}uly--ll--cycle) ; + elseif type= 9 : + border := mirror (lr--ury{up}...tc...{down}uly--ll--cycle) ; + elseif type=10 : + border := normal (ll--lr--ur--ul--ll--ur--ul--ll--cycle) ; + elseif type=11 : + border := normal (ll--lr--ur--ul--ll--lr--ul--ll--cycle) ; + elseif type=12 : + border := normal (ll--lrx--ur--ulx--cycle) ; + elseif type=13 : + border := normal (llx--lr--urx--ul--cycle) ; + elseif type=14 : + border := normal (lly--bc--lry--ury--tc--uly--cycle) ; + elseif type=15 : + border := normal (llx--lrx--rc--urx--ulx--lc--cycle) ; + elseif type=16 : + border := normal (ll--lrx--rc--urx--ul--cycle) ; + elseif type=17 : + border := mirror (ll--lrx--rc--urx--ul--cycle) ; + elseif type=18 : + border := normal (lr--ury--tc--uly--ll--cycle) ; + elseif type=19 : + border := mirror (lr--ury--tc--uly--ll--cycle) ; + elseif type=20 : + border := normal (ll--lr--ur--ul--ll--llxx--ulxx--ul--ll-- + lr--ur--urxx--lrxx--cycle) ; + elseif type=21 : + border := normal (ul--ll--lr--ur--ul--ulyy--uryy--ur--ul-- + ll--lr--lryy--llyy--cycle) ; + elseif type=22 : + border := normal (ll--lrx--lry--ur--ulx--uly--cycle) ; + elseif type=23 : + border := normal (llx--lr--ury--urx--ul--lly--cycle) ; + elseif type=24 : + border := normal (ll--lr--ur--ul--cycle) ; + elseif type=25 : + border := normal (llx--lrx--lry--ury--urx--ulx--uly--lly--cycle) ; + elseif type=26 : + border := normal (ll--lrx--lry--ur--ul--cycle) ; + elseif type=27 : + border := mirror (ll--lr--ury--urx--ul--cycle) ; + elseif type=28 : + border := normal (ll--lr--ury--urx--ul--cycle) ; + elseif type=29 : + border := mirror (ll--lrx--lry--ur--ul--cycle) ; + elseif type=30 : + border := rotate (bc{right}...{up}rc...tc{left}...{down}lc...{right}bc & + bc--tc & tc{left}..{down}lc & lc--rc & + rc{up}..tc{left}...{down}lc...{right}bc & cycle) ; + elseif type=31 : + border := normal (bc{right}...{up}rc...tc{left}...{down}lc...{right}bc & + bc--tc & tc{left}..{down}lc & lc--rc & + rc{up}..tc{left}...{down}lc...{right}bc & cycle) ; + elseif type=32 : + border := normal (ll{right}...{right}lry--ur--ul--ll--cycle) ; + elseif type=33 : + border := normal (ll{right}...{right}lry--ur--ul--ll--cycle + --ul--ulx--ulx shifted(0,yyradius) + --ur shifted(yyradius,yyradius) + --lry shifted(yyradius,yyradius) + --lry shifted(0,yyradius) + --ur--ul--cycle ) ; + elseif type=34 : + border := normal (uly..tc..ury & + ury..tc shifted (0,-2yradius)..uly & + uly--lly & + lly..bc..lry & + lry--ury & + ury..tc shifted (0,-2yradius)..uly & cycle ) ; + elseif type=35 : + border := normal (bc{right}...rc{up}...tc{left}...lc{down}...cycle) ; + elseif type=36 : + border := normal (ul--tc{right}..rc{down}..{left}bc--ll & + ll..(xpart llx, ypart lc)..ul & cycle) ; + elseif type=37 : + border := mirror (ul--tc{right}..rc{down}..{left}bc--ll & + ll..(xpart llx, ypart lc)..ul & cycle) ; + elseif type=38 : + border := normal (ll--lc{up}..tc{right}..{down}rc--lr & + lr..(xpart bc, ypart lly)..ll & cycle) ; + elseif type=39 : + border := mirror (ll--lc{up}..tc{right}..{down}rc--lr & + lr..(xpart bc, ypart lly)..ll & cycle) ; + elseif type=40 : + border := normal (ll--lr--ur--ul--ll--ur--ul--ll--lr--ul--ll--cycle) ; + elseif type=41 : + border := normal (ll--lr--ur--ul--ll--lr--rc--lc--ll--bc--tc--ul--ll & cycle) ; + elseif type=42 : + border := normal (ll--lr--origin shifted (+epsilon,0)-- + ur--ul--origin shifted (-epsilon,0)--cycle) ; + elseif type=43 : + border := normal (ll--ul--origin shifted (0,+epsilon)-- + ur--lr--origin shifted (0,-epsilon)--cycle) ; + elseif type=45 : + border := normal (bc--rc--tc--lc--cycle) ; + elseif type=46 : + border := normal (ll--ul--rc--cycle) ; + elseif type=47 : + border := mirror (ll--ul--rc--cycle) ; + elseif type=48 : + border := mirror (ul--ur--bc--cycle) ; + elseif type=49 : + border := normal (ul--ur--bc--cycle) ; + + elseif type=56 : + border := normal (ll--lry--ury--ul--cycle) ; + elseif type=57 : + border := mirror (ll--lry--ury--ul--cycle) ; + elseif type=58 : + border := normal (ll--ulx--urx--lr--cycle) ; + elseif type=59 : + border := mirror (ll--ulx--urx--lr--cycle) ; + + elseif type= 61 : + border := normal (fullcircle scaled (1.5*yradius) xscaled (grid_height/grid_width)) ; + elseif type= 62 : + border := normal (fullcircle scaled (2.0*yradius) xscaled (grid_height/grid_width)) ; + + elseif type= 66 : + border := normal (rc--origin shifted ( epsilon,0) --cycle & + rc--origin --cycle ) ; + elseif type= 67 : + border := normal (lc--origin shifted (-epsilon,0) --cycle & + lc--origin --cycle ) ; + elseif type= 68 : + border := normal (tc--origin shifted (0, epsilon) --cycle & + tc--origin --cycle ) ; + elseif type= 69 : + border := normal (bc--origin shifted (0,-epsilon) --cycle & + bc--origin --cycle ) ; + + elseif type= 75 : + border := mirror (lly--lry--ury--uly--cycle) ; + elseif type= 76 : + border := mirror (ll--lr--ur--uly--cycle) ; + elseif type= 77 : + border := mirror (ll--lr--ury--ul--cycle) ; + elseif type= 78 : + border := mirror (lly--lr--ur--ul--cycle) ; + elseif type= 79 : + border := mirror (ll--lry--ur--ul--cycle) ; + + else : + border := normal (origin--cycle) ; + %border := normal (ll--lr--ur--ul--cycle) ; + fi ; + + border + + endgroup + +enddef; + +def some_shape ( expr shape_type , + shape_width , + shape_height , + shape_linewidth , + shape_linecolor , + shape_fillcolor ) = + + path p ; p := + some_shape_path (shape_type) + xscaled shape_width + yscaled shape_height ; + + pickup pencircle scaled shape_linewidth ; + + fill p withcolor shape_fillcolor ; + draw p withcolor shape_linecolor ; + +enddef ; + +endinput ; diff --git a/metapost/context/mp-spec.mp b/metapost/context/mp-spec.mp new file mode 100644 index 000000000..7fa743cbc --- /dev/null +++ b/metapost/context/mp-spec.mp @@ -0,0 +1,147 @@ +%D \module +%D [ file=mp-spec.mp, +%D version=1999.6.26, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=special extensions, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +%D This module is rather preliminary and subjected to +%D changes. Here we closely cooperates with the \METAPOST\ +%D to \PDF\ converter module built in \CONTEXT\ and provides +%D for instance shading. More information can be found in +%D type {supp-mpe.tex}. + +if unknown context_tool : input mp-tool ; fi ; +if known context_spec : endinput ; fi ; + +boolean context_spec ; context_spec := true ; + +numeric _special_counter_ ; _special_counter_ := 0 ; +numeric _color_counter_ ; _color_counter_ := 0 ; +numeric _special_signal_ ; _special_signal_ := 123 ; + +%D When set to \type {true}, shading will be supported. Some +%D day I will also write an additional directive. + +boolean _inline_specials_ ; _inline_specials_ := false ; + +%D Because we want to output only those specials that are +%D actually used in a figure, we need a bit complicated +%D bookkeeping and collection of specials. At the cost of some +%D obscurity, we now have rather efficient resources. + +string _all_specials_ ; _all_specials_ := "" ; + +vardef add_special_signal = + if (length _all_specials_>0) : + special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ ) ; % version + fi ; +enddef ; + +vardef add_extra_specials = + scantokens _all_specials_ ; +enddef ; + +vardef reset_extra_specials = + _all_specials_ := "" ; +enddef ; + +extra_endfig := + " add_special_signal ; " & + extra_endfig & + " add_extra_specials ; " & + " reset_extra_specials ; " ; + +def flush_special (expr typ, siz, dat) = + _special_counter_ := _special_counter_ + 1 ; + if _inline_specials_ : + _all_specials_ := _all_specials_ + & "special " + & "(" & ditto + & dat & " " + & decimal _special_counter_ & " " + & decimal typ & " " + & decimal siz + & " special" + & ditto & ");" ; + else : + _all_specials_ := _all_specials_ + & "special " + & "(" & ditto + & "%%MetaPostSpecial: " + & decimal siz & " " + & dat & " " + & decimal _special_counter_ & " " + & decimal typ + & ditto & ");" ; + fi ; +enddef ; + +%D Shade allocation. + +vardef define_circular_shade (expr a, b, ra, rb, ca, cb) = + flush_special(3, 17, "0 1 1" & + dddecimal ca & ddecimal a & " " & decimal ra & + dddecimal cb & ddecimal b & " " & decimal rb ) ; + _special_counter_ +enddef ; + +vardef define_linear_shade (expr a, b, ca, cb) = + flush_special(2, 15, "0 1 1" & + dddecimal ca & ddecimal a & + dddecimal cb & ddecimal b ) ; + _special_counter_ +enddef ; + +%D A few predefined shading macros. + +boolean trace_shades ; trace_shades := false ; + +def linear_shade (expr p, n, ca, cb) = + begingroup ; + save a, b, sh ; pair a, b ; + if (n=1) : a := llcorner p ; b := urcorner p ; + elseif (n=2) : a := llcorner p ; b := ulcorner p ; + elseif (n=3) : a := lrcorner p ; b := ulcorner p ; + else : a := llcorner p ; b := lrcorner p ; + fi ; + fill p withshade define_linear_shade (a,b,ca,cb) ; + if trace_shades : + drawarrow a -- b withpen pencircle scaled 1pt ; + fi ; + endgroup ; +enddef ; + +def circular_shade (expr p, n, ca, cb) = + begingroup ; + save ab, r ; pair ab ; numeric r ; + r := (xpart lrcorner p - xpart llcorner p) ++ + (ypart urcorner p - ypart lrcorner p) ; + if (n=1) : ab := llcorner p ; + elseif (n=2) : ab := lrcorner p ; + elseif (n=3) : ab := urcorner p ; + elseif (n=4) : ab := ulcorner p ; + else : ab := center p ; r := .5r ; + fi ; + fill p withshade define_circular_shade(ab,ab,0,r,ca,cb) ; + if trace_shades : + drawarrow ab -- ab shifted (0,r) withpen pencircle scaled 1pt ; + fi ; + endgroup ; +enddef ; + +%D Since a \type {fill p withshade s} syntax looks better +%D than some macro, we implement a new primary. + +primarydef p withshade sc = + hide (_color_counter_ := _color_counter_ + 1) + p withcolor (_special_signal_/1000,_color_counter_/1000,sc/1000) +enddef ; + +endinput ; diff --git a/metapost/context/mp-text.mp b/metapost/context/mp-text.mp new file mode 100644 index 000000000..c08bac5ff --- /dev/null +++ b/metapost/context/mp-text.mp @@ -0,0 +1,202 @@ +%D \module +%D [ file=mp-text.mp, +%D version=2000.07.10, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=text support, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +%D Under construction. + +if unknown context_tool : input mp-tool ; fi ; +if known context_text : endinput ; fi ; + +boolean context_text ; context_text := true ; + +if unknown noftexpictures : + numeric noftexpictures ; noftexpictures := 0 ; +fi ; + +if unknown texpictures[1] : + picture texpictures[] ; +fi ; + +numeric textextoffset ; textextoffset := 0 ; + +vardef textext@#(expr txt) = + interim labeloffset := textextoffset ; + noftexpictures := noftexpictures + 1 ; + if string txt : + write "% figure " & decimal charcode & " : " & + "texpictures[" & decimal noftexpictures & "] := btex " & + txt & " etex ;" to jobname & ".mpt" ; + if unknown texpictures[noftexpictures] : + thelabel@#("unknown",origin) + else : + thelabel@#(texpictures[noftexpictures],origin) + fi + else : + thelabel@#(txt,origin) + fi +enddef ; + +pair laboff.origin ; laboff.origin = (infinity,infinity) ; +pair laboff.raw ; laboff.raw = (infinity,infinity) ; + +vardef thelabel@#(expr s, z) = + save p ; picture p ; + p = s if not picture s : infont defaultfont scaled defaultscale fi ; + if laboff@#<>laboff.origin : + (p shifted (z + labeloffset*laboff@# - (labxf@#*lrcorner p + + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p))) + else : + (p shifted z) + fi +enddef; + +def build_parshape (expr p, offset_or_path, dx, dy, + baselineskip, strutheight, strutdepth, topskip) = + + if unknown trace_parshape : + boolean trace_parshape ; trace_parshape := false ; + fi ; + + begingroup ; + + save q, l, r, line, tt, bb, + n, hsize, vsize, vvsize, voffset, hoffset, width, indent, + ll, lll, rr, rrr, cp, cq, t, b ; + + path q, l, r, line, tt, bb ; + numeric n, hsize, vsize, vvsize, voffset, hoffset, width[], indent[] ; + pair ll, lll, rr, rrr, cp, cq, t, b ; + + n := 0 ; cp := center p ; + + if path offset_or_path : + q := offset_or_path ; cq := center q ; + voffset := dy ; + hoffset := dx ; + else : + q := p ; cq := center q ; + hoffset := offset_or_path + dx ; + voffset := offset_or_path + dy ; + fi ; + + hsize := xpart lrcorner q - xpart llcorner q ; + vsize := ypart urcorner q - ypart lrcorner q ; + + q := p shifted - cp ; + + startsavingdata ; + + savedata "\global\parvoffset " & decimal voffset&"bp " ; + savedata "\global\parhoffset " & decimal hoffset&"bp " ; + savedata "\global\parwidth " & decimal hsize&"bp " ; + savedata "\global\parheight " & decimal vsize&"bp " ; + + if not path offset_or_path : + q := q xscaled ((hsize-2hoffset)/hsize) + yscaled ((vsize-2voffset)/vsize) ; + fi ; + + hsize := xpart lrcorner q - xpart llcorner q ; + vsize := ypart urcorner q - ypart lrcorner q ; + + t := (ulcorner q -- urcorner q) intersection_point q ; + b := (llcorner q -- lrcorner q) intersection_point q ; + + if xpart directionpoint t of q < 0 : + q := reverse q ; + fi ; + + l := q cutbefore t ; + l := l if xpart point 0 of q < 0 : & q fi cutafter b ; + + r := q cutbefore b ; + r := r if xpart point 0 of q > 0 : & q fi cutafter t ; + +% tt := (ulcorner q -- urcorner q) shifted (0,-topskip) ; +% bb := (llcorner q -- lrcorner q) shifted (0,strutdepth) ; +% +% l := l cutbefore (l intersection_point tt) ; +% l := l cutafter (l intersection_point bb) ; +% r := r cutbefore (r intersection_point bb) ; +% r := r cutafter (r intersection_point tt) ; + + if trace_parshape : + drawarrow p withpen pencircle scaled 2pt withcolor red ; + drawarrow l shifted cp withpen pencircle scaled 1pt withcolor green ; + drawarrow r shifted cp withpen pencircle scaled 1pt withcolor blue ; + fi ; + + vardef found_point (expr lin, pat, sig) = + pair a, b ; + a := pat intersection_point (lin shifted (0,strutheight)) ; + if intersection_found : + a := a shifted (0,-strutheight) ; + else : + a := pat intersection_point lin ; + fi ; + b := pat intersection_point (lin shifted (0,-strutdepth)) ; + if intersection_found : + if sig : + if xpart b > xpart a : a := b shifted (0,strutdepth) fi ; + else : + if xpart b < xpart a : a := b shifted (0,strutdepth) fi ; + fi ; + fi ; + a + enddef ; + + if (strutheight+strutdepth<baselineskip) : + vvsize := vsize ; + else : + vvsize := (vsize div baselineskip) * baselineskip ; + fi ; + + for i=topskip step baselineskip until vvsize : + + line := (ulcorner q -- urcorner q) shifted (0,-i-eps) ; + + ll := found_point(line,l,true ) ; + rr := found_point(line,r,false) ; + + if trace_parshape : + fill (ll--rr--rr shifted (0,strutheight)--ll + shifted (0,strutheight)--cycle) shifted cp withcolor .5white ; + fill (ll--rr--rr shifted (0,-strutdepth)--ll + shifted (0,-strutdepth)--cycle) shifted cp withcolor .7white ; + draw ll shifted cp withpen pencircle scaled 2pt ; + draw rr shifted cp withpen pencircle scaled 2pt ; + draw (ll--rr) shifted cp withpen pencircle scaled .5pt ; + fi ; + + n := n + 1 ; + indent[n] := abs(xpart ll - xpart llcorner q) ; + width[n] := abs(xpart rr - xpart ll) ; + + if (i=strutheight) and (width[n]<baselineskip) : + n := n - 1 ; + savedata "\global\chardef\parfirst=1 " ; + fi ; + + endfor ; + + savedata "\global\parlines " & decimal n ; + savedata "\global\partoks{ " ; + for i=1 upto n: + savedata decimal indent[i]&"bp " & decimal width[i]&"bp " ; + endfor ; + savedata "}" ; + + stopsavingdata ; + + endgroup ; + +enddef ; diff --git a/metapost/context/mp-tool.mp b/metapost/context/mp-tool.mp new file mode 100644 index 000000000..a3ad4927e --- /dev/null +++ b/metapost/context/mp-tool.mp @@ -0,0 +1,1216 @@ +%D \module +%D [ file=mp-tool.mp, +%D version=1998.02.15, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=auxiliary macros, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%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 module is rather preliminary and subjected to +%D changes. + +if known context_tool : endinput ; fi ; + +boolean context_tool ; context_tool := true ; + +%D We always want \EPS\ conforming output, so we say: + +prologues := 2 ; % 1 = troff, 2 = tex +warningcheck := 0 ; + +%D A semicolor to be used in specials: + +string semicolor ; semicolor := char 59 ; + +%D By including this module, \METAPOST\ automatically writes a +%D high resolution boundingbox to the \POSTSCRIPT\ file. This +%D hack is due to John Hobby himself. + +% somehow the first one gets no HiRes. + +vardef ddecimal primary p = + " " & decimal xpart p & + " " & decimal ypart p +enddef ; + +extra_endfig := extra_endfig + & "special " + & "(" + & ditto + & "%%HiResBoundingBox:" + & ditto + & "&ddecimal llcorner currentpicture" + & "&ddecimal urcorner currentpicture" + & ");"; + +%D Also handy (when we flush colors): + +vardef dddecimal primary c = + " " & decimal redpart c & + " " & decimal greenpart c & + " " & decimal bluepart c +enddef ; + +%D We have standardized data file names: + +if not known _data_prefix_ : + + string _data_prefix_ ; _data_prefix_ = "mpd-" ; + string _data_suffix_ ; _data_suffix_ = ".tmp" ; + +fi ; + +def data_file = + _data_prefix_ & decimal charcode & _data_suffix_ +enddef ; + +%D Because \METAPOST\ has a hard coded limit of 4~datafiles, +%D we need some trickery when we have multiple files. + +if unknown collapse_data : + boolean collapse_data ; collapse_data := false ; +fi ; + +boolean savingdata ; savingdata := false ; + +def savedata expr txt = + if collapse_data : + write if savingdata : txt else : + "\MPdata{" & decimal charcode & "}{" & txt & "}" + fi + & "%" to jobname & _data_suffix_ ; + else : + write txt to data_file ; + fi ; +enddef ; + +def startsavingdata = + savingdata := true ; + if collapse_data : + write + "\MPdata{" & decimal charcode & "}{%" + to + jobname & _data_suffix_ ; + fi ; +enddef ; + +def stopsavingdata = + savingdata := false ; + if collapse_data : + write "}%" to jobname & _data_suffix_ ; + fi ; +enddef ; + +%D Instead of a keystroke eating save and allocation +%D sequence, you can use the \quote {new} alternatives to +%D save and allocate in one command. + +def newcolor text v = forsuffixes i=v : save i ; color i ; endfor ; enddef ; +def newnumeric text v = forsuffixes i=v : save i ; numeric i ; endfor ; enddef ; +def newboolean text v = forsuffixes i=v : save i ; boolean i ; endfor ; enddef ; +def newtransform text v = forsuffixes i=v : save i ; transform i ; endfor ; enddef ; +def newpath text v = forsuffixes i=v : save i ; path i ; endfor ; enddef ; +def newpicture text v = forsuffixes i=v : save i ; picture i ; endfor ; enddef ; +def newstring text v = forsuffixes i=v : save i ; string i ; endfor ; enddef ; + +%D Sometimes we don't want parts of the graphics add to the +%D bounding box. One way of doing this is to save the bounding +%D box, draw the graphics that may not count, and restore the +%D bounding box. +%D +%D \starttypen +%D push_boundingbox currentpicture; +%D pop_boundingbox currentpicture; +%D \stoptypen +%D +%D The bounding box can be called with: +%D +%D \starttypen +%D boundingbox currentpicture +%D inner_boundingbox currentpicture +%D outer_boundingbox currentpicture +%D \stoptypen +%D +%D Especially the latter one can be of use when we include +%D the graphic in a document that is clipped to the bounding +%D box. In such occasions one can use: +%D +%D \starttypen +%D set_outer_boundingbox currentpicture; +%D \stoptypen +%D +%D Its counterpart is: +%D +%D \starttypen +%D set_inner_boundingbox p +%D \stoptypen + +path pushed_boundingbox; + +def push_boundingbox text p = + pushed_boundingbox := boundingbox p; +enddef; + +def pop_boundingbox text p = + setbounds p to pushed_boundingbox; +enddef; + +vardef boundingbox primary p = + llcorner p -- + lrcorner p -- + urcorner p -- + ulcorner p -- cycle +enddef; + +vardef inner_boundingbox primary p = + top rt llcorner p -- + top lft lrcorner p -- + bot lft urcorner p -- + bot rt ulcorner p -- cycle +enddef; + +vardef outer_boundingbox primary p = + bot lft llcorner p -- + bot rt lrcorner p -- + top rt urcorner p -- + top lft ulcorner p -- cycle +enddef; + +def innerboundingbox = inner_boundingbox enddef ; +def outerboundingbox = outer_boundingbox enddef ; + +vardef set_inner_boundingbox text q = + setbounds q to inner_boundingbox q; +enddef; + +vardef set_outer_boundingbox text q = + setbounds q to outer_boundingbox q; +enddef; + +%D Some missing functions can be implemented rather +%D straightforward: + +def tand (expr x) = (sind(x)/cosd(x)) enddef ; +def sqr (expr x) = (x*x) enddef ; +def log (expr x) = (if x=0: 0 else: mlog(x)/mlog(10) fi) enddef ; +def ln (expr x) = (if x=0: 0 else: mlog(x)/256 fi) enddef ; +def exp (expr x) = ((mexp 256)**x) enddef ; +def pow (expr x) = (x**power) enddef ; +def inv (expr x) = (if x=0: 0 else: x**-1 fi) enddef ; +def asin (expr x) = (x+(x**3)/6+3(x**5)/40) enddef ; +def acos (expr x) = (asin(-x)) enddef ; +def atan (expr x) = (x-(x**3)/3+(x**5)/5-(x**7)/7) enddef ; + +numeric Pi ; Pi := 3.14159 ; + +%D We provide two macros for drawing stripes across a shape. +%D The first method (with the n suffix) uses another method, +%D slower in calculation, but more efficient when drawn. The +%D first macro divides the sides into n equal parts. The +%D first argument specifies the way the lines are drawn, while +%D the second argument identifier the way the shape is to be +%D drawn. +%D +%D \starttypen +%D stripe_path_n +%D (dashed evenly withcolor blue) +%D (filldraw) +%D fullcircle xscaled 100 yscaled 40 shifted (50,50) withpen pencircle scaled 4; +%D \stoptypen +%D +%D The a (or angle) alternative supports arbitrary angles and +%D is therefore more versatile. +%D +%D \starttypen +%D stripe_path_a +%D (withpen pencircle scaled 2 withcolor red) +%D (draw) +%D fullcircle xscaled 100 yscaled 40 withcolor blue; +%D \stoptypen +%D +%D The first alternative obeys: + +stripe_n := 10; +stripe_slot := 3; + +%D When no pen dimensions are passed, the slot determines +%D the spacing. +%D +%D The angle alternative is influenced by: + +stripe_gap := 5; +stripe_angle := 45; + +def stripe_path_n (text s_spec) (text s_draw) expr s_path = + do_stripe_path_n (s_spec) (s_draw) (s_path) +enddef; + +def do_stripe_path_n (text s_spec) (text s_draw) (expr s_path) text s_text = + begingroup + save curpic, newpic, bb, pp, ww; + picture curpic, newpic; + path bb, pp; + pp := s_path; + curpic := currentpicture; + currentpicture := nullpicture; + s_draw pp s_text; + bb := boundingbox currentpicture; + newpic := currentpicture; + currentpicture := nullpicture; + ww := min(ypart urcorner newpic - ypart llcorner newpic, + xpart urcorner newpic - xpart llcorner newpic); + ww := ww/(stripe_slot*stripe_n); + for i=1/stripe_n step 1/stripe_n until 1: + draw point (1+i) of bb -- point (3-i) of bb + withpen pencircle scaled ww s_spec ; + endfor; + for i=0 step 1/stripe_n until 1: + draw point (3+i) of bb -- point (1-i) of bb + withpen pencircle scaled ww s_spec; + endfor; + clip currentpicture to pp; + addto newpic also currentpicture; + currentpicture := curpic; + addto currentpicture also newpic; + endgroup +enddef; + +def stripe_path_a (text s_spec) (text s_draw) expr s_path = + do_stripe_path_a (s_spec) (s_draw) (s_path) +enddef; + +def do_stripe_path_a (text s_spec) (text s_draw) (expr s_path) text s_text = + begingroup + save curpic, newpic, pp; picture curpic, newpic; path pp ; + pp := s_path ; + curpic := currentpicture; + currentpicture := nullpicture; + s_draw pp s_text ; + def do_stripe_rotation (expr p) = + (currentpicture rotatedaround(center p,stripe_angle)) + enddef ; + s_max := max + (xpart llcorner do_stripe_rotation(currentpicture), + xpart urcorner do_stripe_rotation(currentpicture), + ypart llcorner do_stripe_rotation(currentpicture), + ypart urcorner do_stripe_rotation(currentpicture)); + newpic := currentpicture; + currentpicture := nullpicture; + for i=-s_max-.5stripe_gap step stripe_gap until s_max: + draw (-s_max,i)--(s_max,i) s_spec; + endfor; + currentpicture := do_stripe_rotation(newpic); + clip currentpicture to pp ; + addto newpic also currentpicture; + currentpicture := curpic; + addto currentpicture also newpic; + endgroup +enddef; + +%D A few normalizing macros: +%D +%D \starttypen +%D xscale_currentpicture ( width ) +%D yscale_currentpicture ( height ) +%D xyscale_currentpicture ( width, height ) +%D scale_currentpicture ( width, height ) +%D \stoptypen + +% def xscale_currentpicture(expr the_width) = +% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture; +% currentpicture := currentpicture scaled (the_width/natural_width) ; +% enddef; +% +% def yscale_currentpicture(expr the_height ) = +% natural_height := ypart urcorner currentpicture - ypart llcorner currentpicture; +% currentpicture := currentpicture scaled (the_height/natural_height) ; +% enddef; +% +% def xyscale_currentpicture(expr the_width, the_height) = +% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture; +% natural_height := ypart urcorner currentpicture - ypart llcorner currentpicture; +% currentpicture := currentpicture +% xscaled (the_width/natural_width) +% yscaled (the_height/natural_height) ; +% enddef; +% +% def scale_currentpicture(expr the_width, the_height) = +% xscale_currentpicture(the_width) ; +% yscale_currentpicture(the_height) ; +% enddef; + +% nog eens uitbreiden zodat path en pic worden afgehandeld. + +% natural_width := xpart urcorner currentpicture - xpart llcorner currentpicture; +% currentpicture := currentpicture scaled (the_width/natural_width) ; + +% TODO TODO TODO TODO, not yet ok + +primarydef p xsized w = + (p scaled (w/(xpart urcorner p - xpart llcorner p))) +enddef ; + +primarydef p ysized h = + (p scaled (h/(ypart urcorner p - ypart llcorner p))) +enddef ; + +primarydef p sized wh = + (p xscaled (xpart wh/(xpart urcorner p - xpart llcorner p)) + yscaled (ypart wh/(ypart urcorner p - ypart llcorner p))) +enddef ; + +primarydef p xysized wh = + (p xscaled (xpart wh/(xpart urcorner p - xpart llcorner p)) + yscaled (ypart wh/(ypart urcorner p - ypart llcorner p))) +enddef ; + +def xscale_currentpicture(expr w) = + currentpicture := currentpicture xsized w ; +enddef; + +def yscale_currentpicture(expr h) = + currentpicture := currentpicture ysized h ; +enddef; + +def xyscale_currentpicture(expr w, h) = + currentpicture := currentpicture xysized (w,h) ; +enddef; + +def scale_currentpicture(expr w, h) = + currentpicture := currentpicture xsized w ; + currentpicture := currentpicture ysized h ; +enddef; + +%D A full circle is centered at the origin, while a unitsquare +%D is located in the first quadrant. Now guess what kind of +%D path fullsquare and unitcircle do return. + +path fullsquare, unitcircle ; + +fullsquare := unitsquare shifted - center unitsquare ; +unitcircle := fullcircle shifted urcorner fullcircle ; + +%D Some more paths: + +path urcircle, ulcircle, llcircle, lrcircle ; + +urcircle := origin--(+.5,0)&(+.5,0){up} ..(0,+.5)&(0,+.5)--cycle ; +ulcircle := origin--(0,+.5)&(0,+.5){left} ..(-.5,0)&(-.5,0)--cycle ; +llcircle := origin--(-.5,0)&(-.5,0){down} ..(0,-.5)&(0,-.5)--cycle ; +lrcircle := origin--(0,-.5)&(0,-.5){right}..(+.5,0)&(+.5,0)--cycle ; + +path tcircle, bcircle, lcircle, rcircle ; + +tcircle = origin--(+.5,0)&(+.5,0){up} ..(0,+.5)..{down} (-.5,0)--cycle ; +bcircle = origin--(-.5,0)&(-.5,0){down} ..(0,-.5)..{up} (+.5,0)--cycle ; +lcircle = origin--(0,+.5)&(0,+.5){left} ..(-.5,0)..{right}(0,-.5)--cycle ; +rcircle = origin--(0,-.5)&(0,-.5){right}..(+.5,0)..{left} (0,+.5)--cycle ; + +path urtriangle, ultriangle, lltriangle, lrtriangle ; + +urtriangle := origin--(+.5,0)--(0,+.5)--cycle ; +ultriangle := origin--(0,+.5)--(-.5,0)--cycle ; +lltriangle := origin--(-.5,0)--(0,-.5)--cycle ; +lrtriangle := origin--(0,-.5)--(+.5,0)--cycle ; + +path unitdiamond, fulldiamond ; + +unitdiamond := (.5,0)--(1,.5)--(.5,1)--(0,.5)--cycle ; +fulldiamond := unitdiamond shifted - center unitdiamond ; + +%D shorter + +primarydef p xyscaled q = + p xscaled (xpart paired(q)) yscaled (ypart paired(q)) +enddef ; + +%D Experimenteel, zie folder-3.tex. + +def set_grid(expr w, h, nx, ny) = + boolean grid[][] ; boolean grid_full ; + grid_w := w ; + grid_h := h ; + grid_nx := nx ; + grid_ny := ny ; + grid_x := round(w/grid_nx) ; % +.5) ; + grid_y := round(h/grid_ny) ; % +.5) ; + grid_left := (1+grid_x)*(1+grid_y) ; + grid_full := false ; + for i=0 upto grid_x: + for j=0 upto grid_y: + grid[i][j] := false ; + endfor ; + endfor ; +enddef ; + +vardef new_on_grid(expr _dx_, _dy_) = + dx := _dx_ ; + dy := _dy_ ; + ddx := min(round(dx/grid_nx),grid_x) ; % +.5),grid_x) ; + ddy := min(round(dy/grid_ny),grid_y) ; % +.5),grid_y) ; + if not grid_full and not grid[ddx][ddy]: + grid[ddx][ddy] := true ; + grid_left := grid_left-1 ; + grid_full := (grid_left=0) ; + true + else: + false + fi +enddef ; + +%D usage: \type{innerpath peepholed outerpath}. +%D +%D beginfig(1); +%D def fullsquare = (unitsquare shifted -center unitsquare) enddef ; +%D fill (fullsquare scaled 200) withcolor red ; +%D path p ; p := (fullcircle scaled 100) ; bboxmargin := 0 ; +%D fill p peepholed bbox p ; +%D endfig; + +secondarydef p peepholed q = + begingroup ; + save start ; pair start ; start := point 0 of p ; + if xpart start >= xpart center p : + if ypart start >= ypart center p : + urcorner q -- ulcorner q -- llcorner q -- lrcorner q -- + reverse p -- lrcorner q -- cycle + else : + lrcorner q -- urcorner q -- ulcorner q -- llcorner q -- + reverse p -- llcorner q -- cycle + fi + else : + if ypart start > ypart center p : + ulcorner q -- llcorner q -- lrcorner q -- urcorner q -- + reverse p -- urcorner q -- cycle + else : + llcorner q -- lrcorner q -- urcorner q -- ulcorner q -- + reverse p -- ulcorner q -- cycle + fi + fi + endgroup +enddef ; + +boolean intersection_found ; + +secondarydef p intersection_point q = + begingroup + save x_, y_ ; + (x_,y_) = p intersectiontimes q ; + if x_<0 : + intersection_found := false ; + center p % origin + else : + intersection_found := true ; + .5[point x_ of p, point y_ of q] + fi + endgroup +enddef ; + +%D New, undocumented, experimental: + +vardef tensecircle (expr width, height, offset) = + ((-width/2,-height/2) ... (0,-height/2-offset) ... + (+width/2,-height/2) ... (+width/2+offset,0) ... + (+width/2,+height/2) ... (0,+height/2+offset) ... + (-width/2,+height/2) ... (-width/2-offset,0) ... cycle) +enddef ; + +%vardef tensecircle (expr width, height, offset) = +% ((-width/2,-height/2)..(0,-height/2-offset)..(+width/2,-height/2) & +% (+width/2,-height/2)..(+width/2+offset,0)..(+width/2,+height/2) & +% (+width/2,+height/2)..(0,+height/2+offset)..(-width/2,+height/2) & +% (-width/2,+height/2)..(-width/2-offset,0)..(-width/2,-height/2)..cycle) +%enddef ; + +%D Some colors. + +color cyan ; cyan = (0,1,1) ; +color magenta ; magenta = (1,0,1) ; +color yellow ; yellow = (1,1,0) ; + +%D Well, this is the dangerous and naive version: + +def drawfill text t = + fill t ; + draw t ; +enddef; + +%D This two step approach saves the path first, since it can +%D be a function. Attributes must not be randomized. + +def drawfill expr c = + path _c_ ; _c_ := c ; + do_drawfill +enddef ; + +def do_drawfill text t = + draw _c_ t ; + fill _c_ t ; +enddef; + +def undrawfill expr c = + drawfill c withcolor background +enddef ; + +%D Moved from mp-char.mp + +vardef paired (expr d) = + if pair d : d else : (d,d) fi +enddef ; + +%primarydef p enlarged d = +% begingroup ; save dd ; pair dd ; +% dd := if pair d : d else : (d,d) fi ; +% (llcorner p shifted (-xpart dd,-ypart dd) -- +% lrcorner p shifted (+xpart dd,-ypart dd) -- +% urcorner p shifted (+xpart dd,+ypart dd) -- +% ulcorner p shifted (-xpart dd,+ypart dd) -- +% cycle) +% endgroup +%enddef; + +primarydef p enlarged d = + (p llmoved d -- p lrmoved d -- p urmoved d -- p ulmoved d -- cycle) +enddef; + +primarydef p llenlarged d = + (p llmoved d -- lrcorner p -- urcorner p -- ulcorner p -- cycle) +enddef ; + +primarydef p lrenlarged d = + (llcorner p -- p lrmoved d -- urcorner p -- ulcorner p -- cycle) +enddef ; + +primarydef p urenlarged d = + (llcorner p -- lrcorner p -- p urmoved d -- ulcorner p -- cycle) +enddef ; + +primarydef p ulenlarged d = + (llcorner p -- lrcorner p -- urcorner p -- p ulmoved d -- cycle) +enddef ; + +primarydef p llmoved d = + ((llcorner p) shifted (-xpart paired(d),-ypart paired(d))) +enddef ; + +primarydef p lrmoved d = + ((lrcorner p) shifted (+xpart paired(d),-ypart paired(d))) +enddef ; + +primarydef p urmoved d = + ((urcorner p) shifted (+xpart paired(d),+ypart paired(d))) +enddef ; + +primarydef p ulmoved d = + ((ulcorner p) shifted (-xpart paired(d),+ypart paired(d))) +enddef ; + +%D Nice too: + +primarydef p superellipsed s = + superellipse + (.5[lrcorner p,urcorner p], + .5[urcorner p,ulcorner p], + .5[ulcorner p,llcorner p], + .5[llcorner p,lrcorner p], + s) +enddef ; + +primarydef p squeezed s = + ((llcorner p .. .5[llcorner p,lrcorner p] shifted ( 0, ypart paired(s)) .. lrcorner p) & + (lrcorner p .. .5[lrcorner p,urcorner p] shifted (-xpart paired(s), 0) .. urcorner p) & + (urcorner p .. .5[urcorner p,ulcorner p] shifted ( 0,-ypart paired(s)) .. ulcorner p) & + (ulcorner p .. .5[ulcorner p,llcorner p] shifted ( xpart paired(s), 0) .. llcorner p) & cycle) +enddef ; + +primarydef p randomshifted s = + begingroup ; save ss ; pair ss ; ss := paired(s) ; + p shifted (-.5xpart ss + uniformdeviate xpart ss, + -.5ypart ss + uniformdeviate ypart ss) + endgroup +enddef ; + +primarydef p randomized s = + for i=0 upto length(p)-1 : + ((point i of p) randomshifted s) .. controls + ((postcontrol i of p) randomshifted s) and + ((precontrol (i+1) of p) randomshifted s) .. + endfor cycle +enddef ; + +%D Rather fundamental. + +% vardef rightpath expr p = +% save q, t, b ; path q ; pair t, b ; +% t := (ulcorner p -- urcorner p) intersection_point p ; +% b := (llcorner p -- lrcorner p) intersection_point p ; +% if xpart directionpoint t of p < 0 : p := reverse p ; fi ; +% q := p cutbefore b ; +% q := q if xpart point 0 of p > 0 : & p fi cutafter t ; +% q +% enddef ; +% +% vardef leftpath expr p = +% save q, t, b ; path q ; pair t, b ; +% t := (ulcorner p -- urcorner p) intersection_point p ; +% b := (llcorner p -- lrcorner p) intersection_point p ; +% if xpart directionpoint t of p < 0 : p := reverse p ; fi ; +% q := p cutbefore t ; +% q := q if xpart point 0 of p > 0 : & p fi cutafter b ; +% q +% enddef ; + +def leftrightpath(expr p, l) = + save q, t, b ; path q ; pair t, b ; + t := (ulcorner p -- urcorner p) intersection_point p ; + b := (llcorner p -- lrcorner p) intersection_point p ; + if xpart directionpoint t of p < 0 : p := reverse p ; fi ; + q := p cutbefore if l: t else: b fi ; + q := q if xpart point 0 of p > 0 : & + p fi cutafter if l: b else: t fi ; + q +enddef ; + +vardef leftpath expr p = leftrightpath(p,true ) enddef ; +vardef rightpath expr p = leftrightpath(p,false) enddef ; + +%D Tracing. + +let normaldraw = draw ; +let normalfill = fill ; + +def drawlineoptions (text t) = def _lin_opt_ = t enddef ; enddef ; +def drawpointoptions (text t) = def _pnt_opt_ = t enddef ; enddef ; +def drawcontroloptions(text t) = def _ctr_opt_ = t enddef ; enddef ; +def drawlabeloptions (text t) = def _lab_opt_ = t enddef ; enddef ; +def draworiginoptions (text t) = def _ori_opt_ = t enddef ; enddef ; +def drawboundoptions (text t) = def _bnd_opt_ = t enddef ; enddef ; +def drawpathoptions (text t) = def _pth_opt_ = t enddef ; enddef ; + +drawlineoptions (withpen pencircle scaled 1 withcolor .5white) ; +drawpointoptions (withpen pencircle scaled 4 withcolor black) ; +drawcontroloptions(withpen pencircle scaled 2.5 withcolor black) ; +drawlabeloptions () ; +draworiginoptions (withpen pencircle scaled 1 withcolor .5white) ; +drawboundoptions (dashed evenly _ori_opt_) ; +drawpathoptions (withpen pencircle scaled 5 withcolor .8white) ; + +%D Path. + +def drawpath expr p = + normaldraw p _pth_opt_ +enddef; + +%D Arrow. + +vardef drawarrowpath expr p = + save autoarrows ; boolean autoarrows ; autoarrows := true ; + drawarrow p _pth_opt_ +enddef ; + +%D Points. + +def drawpoint expr c = + if string c : + string _c_ ; _c_ := "(" & c & ")" ; + dotlabel.urt(_c_, scantokens _c_) ; + drawdot scantokens _c_ + else : + dotlabel.urt("(" & decimal xpart c & "," & decimal ypart c & ")", c) ; + drawdot c + fi _pnt_opt_ +enddef ; + +%D PathPoints. + +def drawpoints expr c = path _c_ ; _c_ := c ; do_drawpoints enddef ; +def drawcontrolpoints expr c = path _c_ ; _c_ := c ; do_drawcontrolpoints enddef ; +def drawcontrollines expr c = path _c_ ; _c_ := c ; do_drawcontrollines enddef ; +def drawpointlabels expr c = path _c_ ; _c_ := c ; do_drawpointlabels enddef ; + +def do_drawpoints text t = + for _i_=0 upto length(_c_) : + normaldraw point _i_ of _c_ _pnt_opt_ t ; + endfor ; +enddef; + +def do_drawcontrolpoints text t = + for _i_=0 upto length(_c_) : + normaldraw precontrol _i_ of _c_ _ctr_opt_ t ; + normaldraw postcontrol _i_ of _c_ _ctr_opt_ t ; + endfor ; +enddef; + +def do_drawcontrollines text t = + for _i_=0 upto length(_c_) : + normaldraw point _i_ of _c_ -- precontrol _i_ of _c_ _lin_opt_ t ; + normaldraw point _i_ of _c_ -- postcontrol _i_ of _c_ _lin_opt_ t ; + endfor ; +enddef; + +boolean swappointlabels ; swappointlabels := false ; + +def do_drawpointlabels text t = + for _i_=0 upto length(_c_) : + pair _u_ ; _u_ := unitvector(direction _i_ of _c_) + rotated if swappointlabels : - fi 90 ; + pair _p_ ; _p_ := (point _i_ of _c_) ; + _u_ := 12 * defaultscale * _u_ ; + normaldraw thelabel ( decimal _i_, + _p_ shifted if cycle _c_ and (_i_=0) : - fi _u_ ) _lab_opt_ t ; + endfor ; +enddef; + +%D Bounding box. + +def drawboundingbox expr p = + normaldraw boundingbox p _bnd_opt_ +enddef ; + +%D Origin. + +numeric originlength ; originlength := .5cm ; + +def draworigin text t = + normaldraw (origin shifted (0, originlength) -- + origin shifted (0,-originlength)) _ori_opt_ t ; + normaldraw (origin shifted ( originlength,0) -- + origin shifted (-originlength,0)) _ori_opt_ t ; +enddef; + +%D Axis. + +numeric tickstep ; tickstep := 5mm ; +numeric ticklength ; ticklength := 2mm ; + +def drawxticks expr c = path _c_ ; _c_ := c ; do_drawxticks enddef ; +def drawyticks expr c = path _c_ ; _c_ := c ; do_drawyticks enddef ; +def drawticks expr c = path _c_ ; _c_ := c ; do_drawticks enddef ; + +% Adding eps prevents disappearance due to rounding errors. + +def do_drawxticks text t = + for i=0 step -tickstep until xpart llcorner _c_ - eps : + if (i<=xpart lrcorner _c_) : + normaldraw (i,-ticklength)--(i,ticklength) _ori_opt_ t ; + fi ; + endfor ; + for i=0 step tickstep until xpart lrcorner _c_ + eps : + if (i>=xpart llcorner _c_) : + normaldraw (i,-ticklength)--(i,ticklength) _ori_opt_ t ; + fi ; + endfor ; + normaldraw (llcorner _c_ -- ulcorner _c_) + shifted (-xpart llcorner _c_,0) _ori_opt_ t ; +enddef ; + +def do_drawyticks text t = + for i=0 step -tickstep until ypart llcorner _c_ - eps : + if (i<=ypart ulcorner _c_) : + normaldraw (-ticklength,i)--(ticklength,i) _ori_opt_ t ; + fi ; + endfor ; + for i=0 step tickstep until ypart ulcorner _c_ + eps : + if (i>=ypart llcorner _c_) : + normaldraw (-ticklength,i)--(ticklength,i) _ori_opt_ t ; + fi ; + endfor ; + normaldraw (llcorner _c_ -- lrcorner _c_) + shifted (0,-ypart llcorner _c_) _ori_opt_ t ; +enddef ; + +def do_drawticks text t = + drawxticks _c_ t ; + drawyticks _c_ t ; +enddef ; + +%D All of it except axis. + +def drawwholepath expr p = + draworigin ; + drawpath p ; + drawcontrollines p ; + drawcontrolpoints p ; + drawpoints p ; + drawboundingbox p ; + drawpointlabels p ; +enddef ; + +%D Tracing. + +def visualizeddraw expr c = + if picture c : normaldraw c else : path _c_ ; _c_ := c ; do_visualizeddraw fi +enddef ; + +def visualizedfill expr c = + if picture c : normalfill c else : path _c_ ; _c_ := c ; do_visualizedfill fi +enddef ; + +def do_visualizeddraw text t = + draworigin ; + drawpath _c_ t ; + drawcontrollines _c_ ; + drawcontrolpoints _c_ ; + drawpoints _c_ ; + drawboundingbox _c_ ; + drawpointlabels _c_ ; +enddef ; + +def do_visualizedfill text t = + if cycle _c_ : normalfill _c_ t fi ; + draworigin ; + drawcontrollines _c_ ; + drawcontrolpoints _c_ ; + drawpoints _c_ ; + drawboundingbox _c_ ; + drawpointlabels _c_ ; +enddef ; + +def visualizepaths = + let fill = visualizedfill ; + let draw = visualizeddraw ; +enddef ; + +def naturalizepaths = + let fill = normalfill ; + let draw = normaldraw ; +enddef ; + +extra_endfig := extra_endfig & " naturalizepaths ; " ; + +%D Normally, arrowheads don't scale well. So we provide a +%D hack. + +boolean autoarrows ; autoarrows := false ; +numeric ahfactor ; ahfactor := 2.5 ; + +def set_ahlength (text t) = + ahlength := (ahfactor*pen_size(t)) ; +enddef ; + +vardef pen_size (text t) = + save p ; picture p ; p := nullpicture ; + addto p doublepath (top origin -- bot origin) t ; + (ypart urcorner p - ypart lrcorner p) +enddef ; + +%D The next two macros are adapted versions of plain +%D \METAPOST\ definitions. + +def _finarr text t = + if autoarrows : set_ahlength (t) fi ; + draw _apth t ; + filldraw arrowhead _apth t ; +enddef; + +def _findarr text t = + if autoarrows : set_ahlength (t) fi ; + draw _apth t ; + fill arrowhead _apth withpen currentpen t ; + fill arrowhead reverse _apth withpen currentpen t ; +enddef ; + +%D Handy too ...... + +vardef pointarrow (expr pat, loc, len, off) = + save l, r, s, t ; path l, r ; numeric s ; pair t ; + t := if pair loc : loc else : point loc along pat fi ; +% draw t withpen pencircle scaled 10 withcolor .5white ; + s := len/2 - off ; if s<=0 : s := 0 elseif s>len : s := len fi ; + r := pat cutbefore t ; + r := (r cutafter point (arctime s of r) of r) ; + s := len/2 + off ; if s<=0 : s := 0 elseif s>len : s := len fi ; + l := reverse (pat cutafter t) ; + l := (reverse (l cutafter point (arctime s of l) of l)) ; + (l..r) +enddef ; + +def rightarrow (expr pat,tim,len) = pointarrow(pat,tim,len,-len) enddef ; +def leftarrow (expr pat,tim,len) = pointarrow(pat,tim,len,+len) enddef ; +def centerarrow (expr pat,tim,len) = pointarrow(pat,tim,len, 0) enddef ; + +%D The \type {along} and \type {on} operators can be used +%D as follows: +%D +%D \starttypen +%D drawdot point .5 along somepath ; +%D drawdot point 3cm on somepath ; +%D \stoptypen +%D +%D The number denotes a percentage (fraction). + +primarydef pct along pat = % also negative + (arctime (pct * (arclength pat)) of pat) of pat +enddef ; + +% primarydef len on pat = +% (arctime len of pat) of pat +% enddef ; + +primarydef len on pat = + (arctime if len>0 : len else : (arclength(pat)+len) fi of pat) of pat +enddef ; + +% this cuts of a piece from both ends + +tertiarydef pat cutends len = + begingroup ; save tap ; path tap ; + tap := pat cutbefore (point len on pat) ; + (tap cutafter (point -len on tap)) + endgroup +enddef ; + +%D To be documented. + +path freesquare ; + +freesquare := ((-1,0)--(-1,-1)--(0,-1)--(+1,-1)-- + (+1,0)--(+1,+1)--(0,+1)--(-1,+1)--cycle) scaled .5 ; + +numeric freelabeloffset ; freelabeloffset := 3pt ; +numeric freedotlabelsize ; freedotlabelsize := 3pt ; + +vardef thefreelabel (expr str, loc, ori) = + save s, p, q, l ; picture s ; path p, q ; pair l ; + interim labeloffset := freelabeloffset ; + s := if string str : thelabel(str,loc) else : str shifted -center str shifted loc fi ; + setbounds s to boundingbox s enlarged freelabeloffset ; + p := fullcircle scaled (2*length(loc-ori)) shifted ori ; + q := freesquare xyscaled (urcorner s - llcorner s) ; + l := point (xpart (p intersectiontimes (ori--loc))) of q ; +setbounds s to boundingbox s enlarged -freelabeloffset ; % new + %draw boundingbox s shifted -l withpen pencircle scaled .5pt withcolor red ; + (s shifted -l) +enddef ; + +vardef freelabel (expr str, loc, ori) = + draw thefreelabel(str,loc,ori) ; +enddef ; + +vardef freedotlabel (expr str, loc, ori) = + interim linecap:=rounded ; + draw loc withpen pencircle scaled freedotlabelsize ; + freelabel(str,loc,ori) ; +enddef ; + +%D \starttypen +%D drawarrow anglebetween(line_a,line_b,somelabel) ; +%D \stoptypen + +% angleoffset ; angleoffset := 0pt ; +numeric anglelength ; anglelength := 20pt ; +numeric anglemethod ; anglemethod := 1 ; + +vardef anglebetween (expr a, b, str) = % path path string + save pointa, pointb, common, middle, offset ; + pair pointa, pointb, common, middle, offset ; + save curve ; path curve ; + save where ; numeric where ; + if round point 0 of a = round point 0 of b : + common := point 0 of a ; + else : + common := a intersectionpoint b ; + fi ; + pointa := point anglelength on a ; + pointb := point anglelength on b ; + where := turningnumber (common--pointa--pointb--cycle) ; + if anglemethod = 1 : + curve := pointa{pointa rotated (where*90)} .. pointb ; + middle := point .5 along curve ; + elseif anglemethod = 2 : + middle := common rotatedaround(.5[pointa,pointb],180) ; + curve := pointa--middle--pointb ; + elseif anglemethod = 3 : + middle := ((common--pointa) rotatedaround (pointa,-where*90)) + intersectionpoint + ((common--pointb) rotatedaround (pointb, where*90)) ; + curve := pointa--middle--pointb ; + fi ; + draw thefreelabel(str, middle, common) withcolor black ; + curve +enddef ; + +% Stack + +picture currentpicturestack[] ; +numeric currentpicturedepth ; currentpicturedepth := 0 ; + +def pushcurrentpicture = + currentpicturedepth := currentpicturedepth + 1 ; + currentpicturestack[currentpicturedepth] := currentpicture ; + currentpicture := nullpicture ; +enddef ; + +def popcurrentpicture = + if currentpicturedepth > 0 : + addto currentpicturestack[currentpicturedepth] also currentpicture ; + currentpicture := currentpicturestack[currentpicturedepth] ; + currentpicturedepth := currentpicturedepth - 1 ; + fi ; +enddef ; + +%D colorcircle(size, red, green, blue) ; + +% vardef colorcircle (expr size, red, green, blue) = +% save r, g, b, rr, gg, bb, cc, mm, yy ; save radius ; +% path r, g, b, rr, bb, gg, cc, mm, yy ; numeric radius ; +% +% radius := 5cm ; pickup pencircle scaled (radius/25) ; +% +% r := g := b := fullcircle scaled radius shifted (0,radius/4) ; +% +% r := r rotatedaround (origin, 15) ; +% g := g rotatedaround (origin,135) ; +% b := b rotatedaround (origin,255) ; +% +% r := r rotatedaround(center r,-90) ; +% g := g rotatedaround(center g, 90) ; +% +% gg := buildcycle(buildcycle(reverse r,b),g) ; +% cc := buildcycle(buildcycle(b,reverse g),r) ; +% +% rr := gg rotatedaround(origin,120) ; +% bb := gg rotatedaround(origin,240) ; +% +% yy := cc rotatedaround(origin,120) ; +% mm := cc rotatedaround(origin,240) ; +% +% pushcurrentpicture ; +% +% fill fullcircle scaled radius withcolor white ; +% +% fill rr withcolor red ; fill cc withcolor white-red ; +% fill gg withcolor green ; fill mm withcolor white-green ; +% fill bb withcolor blue ; fill yy withcolor white-blue ; +% +% for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ; +% +% currentpicture := currentpicture xsized size ; +% +% popcurrentpicture ; +% enddef ; + +% vardef colorcircle (expr size, red, green, blue) = +% save r, g, b, rr, gg, bb, cc, mm, yy ; save radius ; +% path r, g, b, rr, bb, gg, cc, mm, yy ; numeric radius ; +% +% radius := 5cm ; pickup pencircle scaled (radius/25) ; +% +% transform t ; t := identity rotatedaround(origin,120) ; +% +% r := fullcircle scaled radius +% shifted (0,radius/4) rotatedaround(origin,15) ; +% +% g := r transformed t ; b := g transformed t ; +% +% r := r rotatedaround(center r,-90) ; +% g := g rotatedaround(center g, 90) ; +% +% gg := buildcycle(buildcycle(reverse r,b),g) ; +% cc := buildcycle(buildcycle(b,reverse g),r) ; +% +% rr := gg transformed t ; bb := rr transformed t ; +% yy := cc transformed t ; mm := yy transformed t ; +% +% pushcurrentpicture ; +% +% fill fullcircle scaled radius withcolor white ; +% +% fill rr withcolor red ; fill cc withcolor white-red ; +% fill gg withcolor green ; fill mm withcolor white-green ; +% fill bb withcolor blue ; fill yy withcolor white-blue ; +% +% for i = rr,gg,bb,cc,mm,yy : draw i withcolor .5white ; endfor ; +% +% currentpicture := currentpicture xsized size ; +% +% popcurrentpicture ; +% enddef ; + +vardef colorcircle (expr size, red, green, blue) = + save r, g, b, c, m, y, w ; save radius ; + path r, g, b, c, m, y, w ; numeric radius ; + + radius := 5cm ; pickup pencircle scaled (radius/25) ; + + transform t ; t := identity rotatedaround(origin,120) ; + + r := fullcircle rotated 90 scaled radius + shifted (0,radius/4) rotatedaround(origin,135) ; + + b := r transformed t ; g := b transformed t ; + + c := buildcycle(subpath(1,7) of g,subpath(1,7) of b) ; + y := c transformed t ; m := y transformed t ; + + w := buildcycle(subpath(3,5) of r, subpath(3,5) of g,subpath(3,5) of b) ; + + pushcurrentpicture ; + + fill r withcolor red ; + fill g withcolor green ; + fill b withcolor blue ; + fill c withcolor white-red ; + fill m withcolor white-green ; + fill y withcolor white-blue ; + fill w withcolor white ; + + for i = r,g,b,c,m,y : draw i withcolor .5white ; endfor ; + + currentpicture := currentpicture xsized size ; + + popcurrentpicture ; +enddef ; + +% penpoint (i,2) of somepath -> inner / outer point + +vardef penpoint expr pnt of p = + save n, d ; numeric n, d ; + (n,d) = if pair pnt : pnt else : (pnt,1) fi ; + (point n of p shifted ((penoffset direction n of p of currentpen) scaled d)) +enddef ; + +% nice: currentpicture := inverted currentpicture ; + +vardef inverted expr p = + save pp ; picture pp ; pp := nullpicture ; + for i within p : + addto pp + if stroked i or filled i : + if filled i : contour else : doublepath fi pathpart i + dashed dashpart i withpen penpart i + else : + also i + fi + withcolor white-(redpart i, greenpart i, bluepart i) ; + endfor ; + pp +enddef ; + +% yes or no: "text" infont "cmr12" at 24pt ; + +% let normalinfont = infont ; +% +% numeric lastfontsize ; lastfontsize = fontsize defaultfont ; +% +% def infont primary name = % no vardef, no expr +% hide(lastfontsize := fontsize name) % no ; +% normalinfont name +% enddef ; +% +% def scaledat expr size = +% scaled (size/lastfontsize) +% enddef ; +% +% let at = scaledat ; + +% like decimal + +def condition primary b = if b : "true" else : "false" fi enddef ; + +endinput ; |