summaryrefslogtreecommitdiff
path: root/metapost
diff options
context:
space:
mode:
Diffstat (limited to 'metapost')
-rw-r--r--metapost/context/metafun.mp1
-rw-r--r--metapost/context/mp-char.mp62
-rw-r--r--metapost/context/mp-core.mp431
-rw-r--r--metapost/context/mp-shap.mp46
-rw-r--r--metapost/context/mp-spec.mp352
-rw-r--r--metapost/context/mp-step.mp320
-rw-r--r--metapost/context/mp-tool.mp190
7 files changed, 1024 insertions, 378 deletions
diff --git a/metapost/context/metafun.mp b/metapost/context/metafun.mp
index e8fd1a762..cf63d289f 100644
--- a/metapost/context/metafun.mp
+++ b/metapost/context/metafun.mp
@@ -37,6 +37,7 @@ input mp-text.mp ;
input mp-shap.mp ;
input mp-butt.mp ;
input mp-char.mp ;
+input mp-step.mp ;
input mp-grph.mp ;
dump ; endinput .
diff --git a/metapost/context/mp-char.mp b/metapost/context/mp-char.mp
index 373200fc2..476199e23 100644
--- a/metapost/context/mp-char.mp
+++ b/metapost/context/mp-char.mp
@@ -1,3 +1,5 @@
+% to be cleaned up, namespace needed ! ! ! ! !
+
%D \module
%D [ file=mp-char.mp,
%D version=1998.10.10,
@@ -17,55 +19,10 @@ 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 ;
+% kan naar elders
+
def save_text_position (expr p) = % beware: clip shift needed
current_position := current_position + 1 ;
savedata
@@ -76,11 +33,8 @@ enddef ;
%D settings
-grid_width := 60pt ;
-grid_height := 40pt ;
-
-shape_width := 45pt ;
-shape_height := 30pt ;
+grid_width := 60pt ; grid_height := 40pt ;
+shape_width := 45pt ; shape_height := 30pt ;
chart_offset := 2pt ;
@@ -131,7 +85,7 @@ def show_shapes (expr n) =
enddef ;
-%D connections
+%D connections -> namespace needed ! ! !
color connection_line_color ;
@@ -895,7 +849,7 @@ def end_chart =
(cmax_x,cmax_y)--(cmin_x,cmax_y)--cycle))
scaled_to_grid ;
%draw p withcolor red ;
- p := enlarged_path (p,chart_offset) ;
+ p := p enlarged chart_offset ;
clip currentpicture to p ;
setbounds currentpicture to p ;
savedata
diff --git a/metapost/context/mp-core.mp b/metapost/context/mp-core.mp
index 3bc42ee74..1951a6bef 100644
--- a/metapost/context/mp-core.mp
+++ b/metapost/context/mp-core.mp
@@ -8,34 +8,32 @@
%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.
+%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 ;
+if unknown context_tool : input mp-tool ; fi ;
+if known context_core : endinput ; fi ;
-boolean context_core ; context_core := true ;
+boolean context_core ; context_core := true ;
pair lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ;
-path pxy[] ;
+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 ;
-% left / right page problem ! ! ! ! !
-
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 ;
+ 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 ;
+ 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 ;
@@ -47,183 +45,340 @@ 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) =
+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] ;
+ hxy := hxy[fpos] ;
dxy := dxy[tpos] ;
rxy := lxy shifted (wxy,0) ;
pxy := llxy--lrxy--urxy--ulxy--cycle ;
cxy := center pxy ;
-enddef ;
+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) =
+def initialize_par (expr fn,fx,fy,fw,fh,fd,
+ tn,tx,ty,tw,th,td,
+ mn,mx,my,mw,mh,md,
+ pn,px,py,pw,ph,pd,
+ rw,rl,rr,rh,ra,ri) =
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) ;
+ numeric mpos ; mpos := 3 ; initialize_box_pos(mpos,mn,mx,my,mw,mh,md) ;
+ numeric ppos ; ppos := 4 ; initialize_box_pos(ppos,pn,px,py,pw,ph,pd) ;
- do_initialize_area (fpos, tpos) ;
- do_initialize_par (fpos, lpos, rpos, tpos) ;
+ numeric par_strut_height, par_strut_depth, par_line_height ;
-enddef ;
+ par_strut_height := ph ;
+ par_strut_depth := pd ;
+ par_line_height := ph + pd ;
-def do_initialize_par (expr fpos, lpos, rpos, tpos) =
+ do_initialize_area (fpos, tpos) ;
+ do_initialize_par (fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) ;
- pair leftxy, righxy ; path txy, mxy, bxy ; % top mid bot
+enddef ;
- 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 ;
+def do_initialize_par (expr fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) =
+
+ pair lref, rref, pref, lhref, rhref ;
+
+ % clip the page area to the left and right skips
+
+ llxy[mpos] := llxy[mpos] shifted (+rl,0) ;
+ lrxy[mpos] := lrxy[mpos] shifted (-rr,0) ;
+ urxy[mpos] := urxy[mpos] shifted (-rr,0) ;
+ ulxy[mpos] := ulxy[mpos] shifted (+rl,0) ;
+
+ % fixate the leftskip, rightskip and hanging indentation
+
+ lref := (xpart llxy[mpos],ypart ulxy[ppos]) ; lhref := lref shifted (rh,0) ;
+ rref := (xpart lrxy[mpos],ypart urxy[ppos]) ; rhref := rref shifted (rh,0) ;
+
+ pref := lxy[ppos] ;
+
+ if nxy[tpos] > nxy[fpos] :
+ if nxy[fpos] = nxy[mpos] :
+ % first of multiple pages
+ llxy[tpos] := llxy[mpos] ;
+ lrxy[tpos] := lrxy[mpos] ;
+ urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ;
+ ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ;
+ boxgriddirection := down ;
+ elseif nxy[tpos] = nxy[mpos] :
+ % last of multiple pages
+ llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ;
+ lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ;
+ urxy[fpos] := urxy[mpos] ;
+ ulxy[fpos] := ulxy[mpos] ;
+ boxgriddirection := up ;
+ else :
+ % middle of multiple pages
+ llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ;
+ lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ;
+ urxy[fpos] := urxy[mpos] ;
+ ulxy[fpos] := ulxy[mpos] ;
+ llxy[tpos] := llxy[mpos] ;
+ lrxy[tpos] := lrxy[mpos] ;
+ urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ;
+ ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ;
+ boxgriddirection := up ;
+ fi ;
+ else :
+ % just one page
+ boxgriddirection := up ;
+ fi ;
- pxy := origin ;
+ path txy, bxy, pxy, mxy ;
- if (round(ypart llxy[fpos]) = round(ypart ulxy[tpos])) and
- (round(xpart lrxy[tpos]) < round(xpart llxy[fpos])) :
+ txy := originpath ; % top
+ bxy := originpath ; % bottom
+ pxy := originpath ; % composed
- 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 ;
+ boolean lefthang, righthang, somehang ;
- elseif ypart llxy[fpos] = ypart llxy[tpos] :
+ % we only hang on the first of a multiple page background
- txy := llxy[fpos] -- lrxy[tpos] -- urxy[tpos] -- ulxy[fpos] --cycle ;
- mxy := origin ;
- bxy := origin ;
+ if nxy[mpos] > nxy[fpos] :
+ lefthang := righthang := somehang := false ;
+ else :
+ lefthang := (rh>0) ; righthang := (rh<0) ; somehang := false ;
+ fi ;
+ if lefthang :
+ mxy := boundingbox (lref -- lref shifted (rh,ra*par_line_height)) ;
+ elseif righthang :
+ mxy := boundingbox (rref -- rref shifted (rh,ra*par_line_height)) ;
else :
+ mxy := originpath ;
+ fi ;
- 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(ypart llxy[fpos]) = round(ypart llxy[tpos]) :
- 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 ;
+ % We have a one-liner. Watch how er use the bottom pos for
+ % determining the height.
+
+ llxy[fpos] := (xpart llxy[fpos], ypart llxy[tpos]) ;
+ ulxy[fpos] := (xpart ulxy[fpos], ypart ulxy[tpos]) ;
- if (round(point 0 of txy) = round(point 1 of txy)) or
- (round(point 0 of txy) = round(point 2 of txy)) :
- txy := origin ;
+ else :
+
+ % We have a multi-liner. For convenience we now correct the
+ % begin and end points for indentation.
+
+ if lefthang and (round(ypart llxy[tpos]) >= round(ypart lrcorner mxy)) :
+ llxy[tpos] := (xpart lhref, ypart llxy[tpos]) ;
+ ulxy[tpos] := (xpart lhref, ypart ulxy[tpos]) ;
+ else :
+ llxy[tpos] := (xpart lref, ypart llxy[tpos]) ;
+ ulxy[tpos] := (xpart lref, ypart ulxy[tpos]) ;
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 ;
+ if righthang and (round(ypart lrxy[fpos]) >= round(ypart llcorner mxy)) :
+ lrxy[fpos] := (xpart rhref, ypart lrxy[fpos]) ;
+ urxy[fpos] := (xpart rhref, ypart urxy[fpos]) ;
+ else :
+ lrxy[fpos] := (xpart rref, ypart lrxy[fpos]) ;
+ urxy[fpos] := (xpart rref, ypart urxy[fpos]) ;
fi ;
+ fi ;
+
+ somehang := (ypart ulxy[fpos]>ypart llcorner mxy) and
+ (ypart llxy[tpos]<ypart llcorner mxy) ;
+
+ if round(ypart llxy[fpos]) = round(ypart llxy[tpos]) :
+
+ % A (short) one-liner goes into the top box.
+
+ txy := llxy[fpos] -- lrxy[tpos] -- urxy[tpos] -- ulxy[fpos] -- cycle ;
+
+ elseif (round(ypart llxy[fpos]) = round(ypart ulxy[tpos])) and
+ (round(xpart lrxy[tpos]) < round(xpart llxy[fpos])) :
+
+ % We have a sentence that spans two lines but with only end
+ % of line and begin of line segments. We need to take care of
+ % indentation.
+
+ txy := llxy[fpos] -- lrxy[fpos] -- urxy[fpos] -- ulxy[fpos] -- cycle ;
+ bxy := llxy[tpos] -- lrxy[tpos] -- urxy[tpos] -- ulxy[tpos] -- cycle ;
+
+ elseif (round(ypart llxy[fpos]) = round(ypart ulxy[tpos])) :
+
+ % We have a sentence that spans two lines but with overlap.
+
+ pxy := llxy[tpos] -- lrxy[tpos] -- urxy[tpos] -- lrxy[fpos] --
+ urxy[fpos] -- ulxy[fpos] -- llxy[fpos] -- ulxy[tpos] -- cycle ;
+
+ elseif lefthang and somehang :
+
+ % We have a sentence that spans more than two lines with
+ % left hanging indentation.
+
+ pxy := llxy[tpos] -- lrxy[tpos] -- urxy[tpos] --
+ (xpart urxy[fpos],ypart urxy[tpos]) --
+ urxy[fpos] -- ulxy[fpos] -- llxy[fpos] --
+ if round(ypart urxy[tpos]) < round(ypart llcorner mxy) :
+ (xpart lrcorner mxy,ypart llxy[fpos]) --
+ lrcorner mxy --
+ (xpart llxy[tpos],ypart llcorner mxy) --
+ else :
+ (xpart llxy[tpos],ypart llxy[fpos]) --
+ fi
+ cycle ;
+
+ elseif righthang and somehang :
+
+ % We have a sentence that spans more than two lines with
+ % right hanging indentation.
+
+ pxy := llxy[tpos] -- lrxy[tpos] -- urxy[tpos] --
+ if round(ypart urxy[tpos]) < round(ypart llcorner mxy) :
+ (xpart lrcorner mxy,ypart urxy[tpos]) --
+ lrcorner mxy -- llcorner mxy --
+ else :
+ (xpart urxy[fpos],ypart urxy[tpos]) --
+ fi
+ urxy[fpos] -- ulxy[fpos] -- llxy[fpos] --
+ (xpart llxy[tpos],ypart llxy[fpos]) --
+ cycle ;
+
+ else :
+
+ % We have a sentence that spans more than two lines with
+ % no hanging indentation.
+
+ pxy := llxy[tpos] -- lrxy[tpos] -- urxy[tpos] --
+ (xpart urxy[fpos],ypart urxy[tpos]) --
+ urxy[fpos] -- ulxy[fpos] -- llxy[fpos] --
+ (xpart llxy[tpos],ypart llxy[fpos]) -- cycle ;
+
fi ;
+ pxy := simplified pxy ;
+ pxy := unspiked pxy ;
+
enddef ;
-color boxfillcolor ; boxfillcolor := .8white ;
-color boxlinecolor ; boxlinecolor := .8blue ;
+color boxgridcolor ; boxgridcolor := .8red ;
+color boxlinecolor ; boxlinecolor := .8blue ;
+color boxfillcolor ; boxfillcolor := .8white ;
+numeric boxgridtype ; boxgridtype := 0 ;
+numeric boxlinetype ; boxlinetype := 1 ;
+numeric boxfilltype ; boxfilltype := 1 ;
+pair boxgriddirection ; boxgriddirection := up ;
+numeric boxgridwidth ; boxgridwidth := 1pt ;
+numeric boxlinewidth ; boxlinewidth := 1pt ;
+numeric boxlineradius ; boxlineradius := 0pt ;
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 ;
+ draw pxy withcolor boxlinecolor withpen pencircle scaled boxlinewidth ;
+ draw lxy -- rxy withcolor boxlinecolor withpen pencircle scaled boxgridwidth ;
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 ;
+def draw_par = % 1 2 11
+ numeric distance ; distance := .5cm ;
+ do_draw_par(pxy) ; do_draw_par(txy) ; do_draw_par(bxy) ;
+ for i = pxy, txy, bxy :
+ if boxgridtype= 1 :
+ draw baseline_grid (i,boxgriddirection,true ) withcolor boxgridcolor ;
+ elseif boxgridtype= 2 :
+ draw baseline_grid (i,boxgriddirection,false) withcolor boxgridcolor ;
+ elseif boxgridtype=11 :
+ draw graphic_grid(i,distance,distance,distance/2,distance/2) ;
+ fi ;
+ endfor ;
enddef ;
-def draw_par_top =
- pickup pencircle scaled .5 ;
- if length txy > 1 :
- fill txy withcolor boxfillcolor ; draw txy withcolor boxlinecolor ;
- fi ;
+def show_par =
+ def do_show_par (expr p, r, c) =
+ if length(p) > 2 : for i=0 upto length(p) :
+ draw fullcircle scaled r shifted point i of p
+ withpen pencircle scaled .5pt withcolor c ;
+ endfor ; fi ;
+ enddef ;
+ if length(mxy) > 2 :
+ draw mxy dashed evenly
+ withpen pencircle scaled .5pt withcolor .5white ;
+ fi ;
+ do_show_par(txy, 4pt, .5green) ;
+ do_show_par(bxy, 6pt, .5blue ) ;
+ do_show_par(pxy, 8pt, .5red ) ;
+ draw pref withpen pencircle scaled 2pt ;
enddef ;
-def draw_par_mid =
- pickup pencircle scaled .5 ;
- if length mxy > 1 :
- fill mxy withcolor boxfillcolor ; draw mxy withcolor boxlinecolor ;
+vardef do_draw_par (expr p) =
+ if length p > 2 :
+ save pp ; path pp ;
+ if (boxlineradius>0) and (boxlinetype=2) :
+ pp := p cornered boxlineradius ;
+ else :
+ pp := p ;
+ fi ;
+ if boxfilltype>0 :
+ fill pp withcolor boxfillcolor ;
+ fi ;
+ if boxlinetype>0 :
+ draw pp withcolor boxlinecolor withpen pencircle scaled boxlinewidth ;
+ fi ;
fi ;
enddef ;
-def draw_par_bot =
- pickup pencircle scaled .5 ;
- if length bxy > 1 :
- fill bxy withcolor boxfillcolor ; draw bxy withcolor boxlinecolor ;
- fi ;
+vardef baseline_grid (expr pxy, pdir, at_baseline) =
+ if (par_line_height>0) : % and (round(bbheight(pxy))>=round(par_line_height)) :
+ save grid, start ; picture grid ; pair start ;
+ grid := image
+ ( %fails with inlinespace
+ %
+ %if pdir=up :
+ % for i = if at_baseline : par_strut_depth else : 0 fi
+ % step par_line_height until bbheight(pxy) :
+ % start := llcorner pxy shifted (0,+i) ;
+ % draw start -- start shifted (bbwidth(pxy),0)
+ % withpen pencircle scaled boxgridwidth
+ % withcolor boxgridcolor ;
+ % endfor ;
+ %else :
+ for i = if at_baseline : par_strut_height else : 0 fi
+ step par_line_height until bbheight(pxy) :
+ start := ulcorner pxy shifted (0,-i) ;
+ draw start -- start shifted (bbwidth(pxy),0)
+ withpen pencircle scaled boxgridwidth
+ withcolor boxgridcolor ;
+ endfor ;
+ %fi ;
+ ) ;
+ clip grid to pxy ;
+ grid
+ else :
+ nullpicture
+ fi
+enddef ;
+
+vardef graphic_grid (expr pxy, dx, dy, x, y) =
+ if (bbheight(pxy)>dy) and (bbwidth(pxy)>dx) :
+ save grid ; picture grid ;
+ grid := image
+ ( for i = xpart llcorner pxy step dx until xpart lrcorner pxy :
+ draw (i,ypart llcorner pxy) -- (i,ypart ulcorner pxy)
+ withpen pencircle scaled boxgridwidth ;
+ endfor ;
+ for i = ypart llcorner pxy step dy until ypart ulcorner pxy :
+ draw (xpart llcorner pxy,i) -- (xpart lrcorner pxy,i)
+ withpen pencircle scaled boxgridwidth ;
+ endfor ) ;
+ clip grid shifted (x,y) to pxy ;
+ grid
+ else :
+ nullpicture
+ 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 ;
@@ -231,4 +386,4 @@ let draw_area = draw_box ;
let anchor_area = anchor_box ;
let anchor_par = anchor_box ;
-endinput ;
+endinput ;
diff --git a/metapost/context/mp-shap.mp b/metapost/context/mp-shap.mp
index 5b95e71aa..f8bfd50cf 100644
--- a/metapost/context/mp-shap.mp
+++ b/metapost/context/mp-shap.mp
@@ -258,4 +258,50 @@ def some_shape ( expr shape_type ,
enddef ;
+vardef drawshape (expr t, p, lw, lc, fc) =
+ save pp ;
+ if t>1 : % normal shape
+ path pp ;
+ pp := some_shape_path(t) xyscaled(bbwidth(p), bbheight(p)) shifted center p ;
+ fill pp withcolor fc ;
+ draw pp withpen pencircle scaled lw withcolor lc ;
+ elseif t=1 : % background only
+ path pp ;
+ pp := fullsquare xyscaled(bbwidth(p), bbheight(p)) shifted center p ;
+ fill pp withcolor fc ;
+ else : % dimensions only
+ picture pp ; pp := nullpicture ;
+ setbounds pp to fullsquare xyscaled(bbwidth(p), bbheight(p)) shifted center p ;
+ draw pp ;
+ fi ;
+enddef ;
+
+vardef drawline (expr t, p, lw, lc) =
+ if (t>0) and (length(p)>1) :
+ saveoptions ;
+ drawoptions(withpen pencircle scaled lw withcolor lc) ;
+ draw p ;
+ if t = 1 :
+ draw arrowheadonpath(p,1) ;
+ elseif t = 2 :
+ draw arrowheadonpath(reverse p,1) ;
+ elseif t = 3 :
+ for $ = p,reverse p : draw arrowheadonpath($,1) ; endfor ;
+ elseif t = 11 :
+ draw arrowheadonpath(p,1/2) ;
+ elseif t = 12 :
+ draw arrowheadonpath(reverse p,1/2) ;
+ elseif t = 13 :
+ for $=p,reverse p : draw arrowheadonpath($,1) ; endfor ;
+ for $=p,reverse p : draw arrowheadonpath($,3/4) ; endfor ;
+ elseif t = 21 :
+ for $=1/5,1/2,4/5 : draw arrowheadonpath(p,$) ; endfor ;
+ elseif t = 22 :
+ for $=1/5,1/2,4/5 : draw arrowheadonpath(reverse p,$) ; endfor ;
+ elseif t = 23 :
+ for $=p,reverse p : draw arrowheadonpath($,1/4) ; endfor ;
+ fi ;
+ fi ;
+enddef ;
+
endinput ;
diff --git a/metapost/context/mp-spec.mp b/metapost/context/mp-spec.mp
index db7cbd256..918e73fb4 100644
--- a/metapost/context/mp-spec.mp
+++ b/metapost/context/mp-spec.mp
@@ -2,238 +2,244 @@
%D [ file=mp-spec.mp,
%D version=1999.6.26,
%D title=\CONTEXT\ \METAPOST\ graphics,
-%D subtitle=special extensions,
+%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.
+%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}.
+% (r,g,b) => cmyk: g=1, b=hash
+% => rest: g=n, b=whatever
-if unknown context_tool : input mp-tool ; fi ;
-if known context_spec : endinput ; fi ;
+%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}.
-boolean context_spec ; context_spec := true ;
+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 ;
+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.
+%D day I will also write an additional directive.
-boolean _inline_specials_ ; _inline_specials_ := false ;
+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.
+%D obscurity, we now have rather efficient resources.
-string _all_specials_ ; _all_specials_ := "" ;
+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_special_signal =
+ if (length _all_specials_>0) : % write the version number
+ special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ ) ;
+ fi ;
+enddef ;
-vardef add_extra_specials =
- scantokens _all_specials_ ;
-enddef ;
+vardef add_extra_specials =
+ scantokens _all_specials_ ;
+enddef ;
-vardef reset_extra_specials =
+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_
+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"
+ & dat & " "
+ & decimal _special_counter_ & " "
+ & decimal typ & " "
+ & decimal siz
+ & " special"
& ditto & ");" ;
else :
- _all_specials_ := _all_specials_
- & "special "
+ _all_specials_ := _all_specials_
+ & "special "
& "(" & ditto
- & "%%MetaPostSpecial: "
- & decimal siz & " "
- & dat & " "
- & decimal _special_counter_ & " "
- & decimal typ
+ & "%%MetaPostSpecial: "
+ & decimal siz & " "
+ & dat & " "
+ & decimal _special_counter_ & " "
+ & decimal typ
& ditto & ");" ;
- fi ;
-enddef ;
+ fi ;
+enddef ;
-%D Shade allocation.
+%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 &
+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 ;
+ _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 ;
+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 ;
+boolean trace_shades ; trace_shades := false ;
-def linear_shade (expr p, n, ca, cb) =
- begingroup ;
+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 ;
+ 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_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 ;
+ 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.
+%D Since a \type {fill p withshade s} syntax looks better
+%D than some macro, we implement a new primary.
-primarydef p withshade sc =
+primarydef p withshade sc =
hide (_color_counter_ := _color_counter_ + 1)
- p withcolor (_special_signal_/1000,_color_counter_/1000,sc/1000)
-enddef ;
+ p withcolor (_special_signal_/1000,_color_counter_/1000,sc/1000)
+enddef ;
-%D Figure inclusion.
+%D Figure inclusion.
-numeric cef ; cef := 0 ;
+numeric cef ; cef := 0 ;
-def externalfigure primary filename =
- doexternalfigure (filename)
-enddef ;
+def externalfigure primary filename =
+ doexternalfigure (filename)
+enddef ;
-def doexternalfigure (expr filename) text transformation =
- begingroup ; save p, t ; picture p ; transform t ;
- p := nullpicture ; t := identity transformation ;
+def doexternalfigure (expr filename) text transformation =
+ begingroup ; save p, t ; picture p ; transform t ;
+ p := nullpicture ; t := identity transformation ;
flush_special(10, 9,
- dddecimal (xxpart t, yxpart t, xypart t) & " " &
- dddecimal (yypart t, xpart t, ypart t) & " " & filename) ;
+ dddecimal (xxpart t, yxpart t, xypart t) & " " &
+ dddecimal (yypart t, xpart t, ypart t) & " " & filename) ;
addto p contour unitsquare scaled 0 ;
- setbounds p to unitsquare transformed t ;
- _color_counter_ := _color_counter_ + 1 ; cef := cef + 1 ;
- draw p withcolor (_special_signal_/1000,_color_counter_/1000,cef/1000) ;
- endgroup ;
-enddef ;
+ setbounds p to unitsquare transformed t ;
+% _color_counter_ := _color_counter_ + 1 ; cef := cef + 1 ;
+% draw p withcolor (_special_signal_/1000,_color_counter_/1000,cef/1000) ;
+draw p withcolor (_special_signal_/1000,cef/1000,_special_counter_/1000) ;
+ endgroup ;
+enddef ;
-%D Experimental:
+%D Experimental:
-numeric currenthyperlink ; currenthyperlink := 0 ;
+numeric currenthyperlink ; currenthyperlink := 0 ;
def hyperlink primary t = dohyperlink(t) enddef ;
def hyperpath primary t = dohyperpath(t) enddef ;
-def dohyperlink (expr destination) text transformation =
- begingroup ; save somepath ; path somepath ;
- somepath := fullsquare transformation ;
+def dohyperlink (expr destination) text transformation =
+ begingroup ; save somepath ; path somepath ;
+ somepath := fullsquare transformation ;
dohyperpath(destination) somepath ;
- endgroup ;
-enddef ;
+ endgroup ;
+enddef ;
-def dohyperpath (expr destination) expr somepath =
- begingroup ;
+def dohyperpath (expr destination) expr somepath =
+ begingroup ;
flush_special(20, 7,
- ddecimal (xpart llcorner somepath, ypart llcorner somepath) & " " &
- ddecimal (xpart urcorner somepath, ypart urcorner somepath) & " " & destination) ;
- _color_counter_ := _color_counter_ + 1 ;
- currenthyperlink := currenthyperlink + 1 ;
- fill boundingbox unitsquare scaled 0
- withcolor
- (_special_signal_/1000,_color_counter_/1000,currenthyperlink/1000) ;
- endgroup ;
-enddef ;
+ ddecimal (xpart llcorner somepath, ypart llcorner somepath) & " " &
+ ddecimal (xpart urcorner somepath, ypart urcorner somepath) & " " & destination) ;
+ currenthyperlink := currenthyperlink + 1 ;
+% _color_counter_ := _color_counter_ + 1 ;
+ fill boundingbox unitsquare scaled 0 withcolor
+% (_special_signal_/1000,_color_counter_/1000,currenthyperlink/1000) ;
+ (_special_signal_/1000,currenthyperlink/1000,_special_counter_/1000) ;
+ endgroup ;
+enddef ;
% \setupinteraction[state=start]
% \setupcolors [state=start]
-%
-% Hello There! \blank
-%
-% \startMPcode
-% pickup pencircle scaled 5 ;
-% draw fullcircle scaled 4cm withcolor red ;
-% hyperpath "nextpage" boundingbox currentpicture ;
+%
+% Hello There! \blank
+%
+% \startMPcode
+% pickup pencircle scaled 5 ;
+% draw fullcircle scaled 4cm withcolor red ;
+% hyperpath "nextpage" boundingbox currentpicture ;
% draw origin withcolor blue ;
% \stopMPcode
-%
-% \blank Does it work or not?
-%
-% \startMPcode
-% pickup pencircle scaled 5 ;
-% draw fullcircle scaled 4cm withcolor red ;
-% hyperpath "nextpage" fullcircle scaled 4cm ;
+%
+% \blank Does it work or not?
+%
+% \startMPcode
+% pickup pencircle scaled 5 ;
+% draw fullcircle scaled 4cm withcolor red ;
+% hyperpath "nextpage" fullcircle scaled 4cm ;
% draw origin withcolor blue ;
-% draw fullcircle scaled 4cm shifted (1cm,1cm);
+% draw fullcircle scaled 4cm shifted (1cm,1cm);
% \stopMPcode
-%
-% \blank Does it work or not? \page Hello There! \blank
-%
-% \startMPcode
-% pickup pencircle scaled 5 ;
-% draw fullcircle scaled 2cm shifted (-2cm,-1cm) ;
-% draw fullcircle scaled 3cm shifted (2cm,1cm) withcolor red ;
-% draw fullcircle scaled 1cm ;
-% hyperlink "previouspage" scaled 3cm shifted (2cm,1cm) ;
-% draw origin withcolor blue ;
+%
+% \blank Does it work or not? \page Hello There! \blank
+%
+% \startMPcode
+% pickup pencircle scaled 5 ;
+% draw fullcircle scaled 2cm shifted (-2cm,-1cm) ;
+% draw fullcircle scaled 3cm shifted (2cm,1cm) withcolor red ;
+% draw fullcircle scaled 1cm ;
+% hyperlink "previouspage" scaled 3cm shifted (2cm,1cm) ;
+% draw origin withcolor blue ;
% \stopMPcode
-%
-% \blank Does it work or not?
+%
+% \blank Does it work or not?
_cmyk_counter_ := 0 ;
-numeric cmykcolorhash[][][][] ;
+extra_endfig := " resetcmykcolors ; " & extra_endfig ;
-boolean cmykcolors ; % cmykcolors := true ;
+def resetcmykcolors =
+ numeric cmykcolorhash[][][][] ;
+enddef ;
-let normalcmyk = cmyk ; % see mp-tool.mp
+resetcmykcolors ; boolean cmykcolors ; cmykcolors := false ; % true
vardef cmyk(expr c,m,y,k) =
if cmykcolors :
@@ -241,7 +247,7 @@ vardef cmyk(expr c,m,y,k) =
_cmyk_counter_ := _cmyk_counter_ + 1 ;
cmykcolorhash[c][m][y][k] := _cmyk_counter_ ;
flush_special(1, 7,
- decimal _cmyk_counter_ & " " &
+ decimal _cmyk_counter_ & " " &
decimal c & " " &
decimal m & " " &
decimal y & " " &
@@ -249,19 +255,19 @@ vardef cmyk(expr c,m,y,k) =
fi
(_special_signal_/1000,1/1000,cmykcolorhash[c][m][y][k]/1000)
else :
- normalcmyk(1-c-k,1-m-k,1-y-k)
+ (1-c-k,1-m-k,1-y-k)
fi
enddef ;
-%D Basic position tracking:
+%D Basic position tracking:
-def register (expr label, width, height, offset) =
- begingroup ;
+def register (expr label, width, height, offset) =
+ begingroup ;
flush_special(50, 7,
- ddecimal offset & " " &
- decimal width & " " &
- decimal height & " " & label) ;
- endgroup ;
-enddef ;
+ ddecimal offset & " " &
+ decimal width & " " &
+ decimal height & " " & label) ;
+ endgroup ;
+enddef ;
-endinput ;
+endinput ;
diff --git a/metapost/context/mp-step.mp b/metapost/context/mp-step.mp
new file mode 100644
index 000000000..d602f7014
--- /dev/null
+++ b/metapost/context/mp-step.mp
@@ -0,0 +1,320 @@
+%D \module
+%D [ file=mp-step.mp,
+%D version=2001.05.22,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=steps,
+%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_step : endinput ; fi ;
+
+boolean context_step ; context_step := true ;
+
+%D In the associated \TEX\ module \type {m-steps}, we describe
+%D three methods. The first method uses a different kind of
+%D code than the other two. The method we decided to use,
+%D is based on positional information (paths) provided by
+%D \CONTEXT.
+
+def initialize_step_variables =
+ save line_method, line_h_offset, line_v_offset ;
+ numeric line_method ; line_method := 1 ;
+ numeric line_h_offset ; line_h_offset := 3pt ;
+ numeric line_v_offset ; line_v_offset := 3pt ;
+enddef ;
+
+def begin_step_chart =
+ initialize_step_variables ;
+ save steps, texts, t, b, tb, nofcells ;
+ picture cells[][], texts[][][], lines[][][] ;
+ numeric t, b ; t := 1 ; b := 2 ;
+ numeric nofcells ; nofcells := 0 ;
+enddef ;
+
+def analyze_step_chart =
+ numeric n[], l[][], r[][] ; pair p[] ;
+ n[t] := n[b] := 0 ; numeric tb ;
+ for i=1 upto nofcells : for nn = t, b :
+ if bbwidth(cells[nn][i])>0 : n[nn] := n[nn] + 1 ; fi ;
+ l[t][i] := r[t][i] := l[b][i] := r[b][i] := 0 ;
+ endfor ; endfor ;
+ % count left and right points
+ for i=1 upto nofcells-1 : for j=i upto nofcells-1 : for nn = t, b :
+ if bbwidth(texts[nn][i][j])>0 :
+ l[nn][i] := l[nn][i] + 1 ;
+ r[nn][j+1] := r[nn][j+1] + 1 ;
+ fi ;
+ endfor ; endfor ; endfor ;
+ % calculate left and right points
+ vardef do (expr nn, mm, ii, ss) =
+ if (l[nn][ii] + r[nn][ii]) > 1 : ss else : .5 fi
+ [ ulcorner cells[mm][ii], urcorner cells[mm][ii] ]
+ enddef ;
+ % combined rows
+ tb := if n[t]>0 : t else : b fi ;
+enddef ;
+
+vardef get_step_chart_top_line (expr i, j) =
+ if bbwidth(cells[tb][i])>0 :
+ if bbwidth(texts[t][i][j])>0 :
+ if bbwidth(cells[tb][j+1])>0 :
+ p[1] := top do(t, tb, i, .6) ;
+ p[3] := top do(t, tb, j+1, .4) ;
+ p[2] := .5[p[1],p[3]] ;
+ if line_method = 1 :
+ p[2] := p[2] shifted (0, ypart
+ (llcorner texts[t][i][j] - ulcorner cells[tb][j+1])) ;
+ elseif line_method = 2 :
+ p[2] := center texts[t][i][j] ;
+ else :
+ % nothing
+ fi ;
+ p[1] := p[1] shifted (0,+line_v_offset) ;
+ p[2] := p[2] shifted (0,-line_v_offset) ;
+ p[3] := p[3] shifted (0,+line_v_offset) ;
+ (p[1] {up} ... p[2] ... {down} p[3])
+ else :
+ origin
+ fi
+ else :
+ origin
+ fi
+ else :
+ origin
+ fi
+enddef ;
+
+vardef get_step_chart_bot_line (expr i, j) =
+ if bbwidth(cells[b][i])>0 :
+ if bbwidth(texts[b][i][j])>0 :
+ if bbwidth(cells[b][j+1])>0 :
+ p[1] := (bot do(b, b, i, .6)) shifted (0,-bbheight(cells[b][i])) ;
+ p[3] := (bot do(b, b, j+1, .4)) shifted (0,-bbheight(cells[b][j+1])) ;
+ p[2] := .5[p[1],p[3]] ;
+ if line_method = 1 :
+ p[2] := p[2] shifted (0, -ypart
+ (llcorner cells[b][j+1] - ulcorner texts[b][i][j])) ;
+ elseif line_method = 2 :
+ p[2] := center texts[b][i][j] ;
+ fi ;
+ p[1] := p[1] shifted (0,-line_v_offset) ;
+ p[2] := p[2] shifted (0,+line_v_offset) ;
+ p[3] := p[3] shifted (0,-line_v_offset) ;
+ (p[1] {down} ... p[2] ... {up} p[3])
+ else :
+ origin
+ fi
+ else :
+ origin
+ fi
+ else :
+ origin
+ fi
+enddef ;
+
+def end_step_chart =
+ for i=1 upto nofcells : for nn = t, b :
+ if bbwidth(cells[nn][i]) >0 : draw cells[nn][i] ; fi ;
+ endfor ; endfor ;
+ for i=1 upto nofcells : for j=i upto nofcells : for nn = t, b :
+ if known lines[nn][i][j] :
+ if bbwidth(lines[nn][i][j])>0 : draw lines[nn][i][j] ; fi ;
+ fi ;
+ endfor ; endfor ; endfor ;
+ for i=1 upto nofcells : for j=i upto nofcells : for nn = t, b :
+ if bbwidth(texts[nn][i][j])>0 : draw texts[nn][i][j] ; fi ;
+ endfor ; endfor ; endfor ;
+enddef ;
+
+%D Step tables.
+
+def begin_step_table =
+ initialize_step_variables ;
+ picture cells[], texts[], lines[] ;
+ numeric nofcells ; nofcells := 0 ;
+enddef ;
+
+def end_step_table =
+ for i=1 upto nofcells : if known cells[i] : if bbwidth(cells[i])>0 :
+ draw cells[i] ;
+ fi ; fi ; endfor ;
+ for i=1 upto nofcells : if known lines[i] : if bbwidth(lines[i])>0 :
+ draw lines[i] ;
+ fi ; fi ; endfor ;
+ for i=1 upto nofcells : if known texts[i] : if bbwidth(texts[i])>0 :
+ draw texts[i] ;
+ fi ; fi ; endfor ;
+enddef ;
+
+vardef get_step_table_line (expr i) =
+ pair prev, self, next ;
+ if known texts[i] :
+ self := lft .5[llcorner texts[i], ulcorner texts[i] ] ;
+ prev := rt if known texts[i-1] : .3 else : .5 fi [lrcorner cells[i] , urcorner cells[i] ] ;
+ next := rt if known texts[i+1] : .7 else : .5 fi [lrcorner cells[i+1], urcorner cells[i+1]] ;
+ self := self shifted (-line_h_offset,0) ;
+ prev := prev shifted (+line_h_offset,0) ;
+ next := next shifted (+line_h_offset,0) ;
+ prev {right} ... self ... {left} next
+ else :
+ origin
+ fi
+enddef ;
+
+endinput
+
+%D The older method let \METAPOST\ do the typesetting. The
+%D macros needed for that are included here for educational
+%D purposes.
+%D
+%D \starttypen
+%D def initialize_step_variables =
+%D save line_color, line_width, arrow_alternative,
+%D text_fill_color, text_line_color, text_line_width, text_offset,
+%D cell_fill_color, cell_line_color, cell_line_width, cell_offset,
+%D line_h_offset, line_v_offset ;
+%D color line_color ; line_color := .4white ;
+%D numeric line_width ; line_width := 1.5pt ;
+%D color text_fill_color ; text_fill_color := white ;
+%D color text_line_color ; text_line_color := red ;
+%D numeric text_line_width ; text_line_width := 1pt ;
+%D numeric text_offset ; text_offset := 2pt ;
+%D color cell_fill_color ; cell_fill_color := white ;
+%D color cell_line_color ; cell_line_color := blue ;
+%D numeric cell_line_width ; cell_line_width := 1pt ;
+%D numeric cell_offset ; cell_offset := 2pt ;
+%D numeric line_alternative ; line_alternative := 1 ;
+%D numeric line_h_offset ; line_h_offset := 3pt ;
+%D numeric line_v_offset ; line_v_offset := 3pt ;
+%D enddef ;
+%D
+%D def begin_step_chart =
+%D begingroup ;
+%D initialize_step_variables ;
+%D save steps, texts, t, b ;
+%D picture cells[][] ; numeric nofcells ; nofcells := 0 ;
+%D picture texts[][][] ; numeric noftexts ; noftexts := 0 ;
+%D numeric t, b ; t := 1 ; b := 2 ;
+%D enddef ;
+%D \stoptypen
+%D
+%D We use a couple of macros to store the content. In the
+%D second (third) alternative we will directly fill the
+%D cells.
+%D
+%D \starttypen
+%D def set_step_chart_cells (expr one, two) =
+%D nofcells := nofcells + 1 ; noftexts := 0 ;
+%D cells[t][nofcells] := textext.rt(one) ;
+%D cells[b][nofcells] := textext.rt(two) ;
+%D enddef ;
+%D
+%D def set_step_chart_texts (expr one, two) =
+%D noftexts := noftexts + 1 ;
+%D texts[t][nofcells][noftexts] := textext.rt(one) ;
+%D texts[b][nofcells][noftexts] := textext.rt(two) ;
+%D enddef ;
+%D \stoptypen
+%D
+%D If you compare the building macro with the later
+%D alternative, you will notice that here we explicitly
+%D have to calculate the distances and positions.
+%D
+%D \starttypen
+%D def end_step_chart =
+%D numeric dx ; dx := 0 ; path p ;
+%D numeric n[] ; n[t] := n[b] := 0 ;
+%D numeric stepsvdistance[] ;
+%D vardef bbwidth (expr p) = (xpart (lrcorner p - llcorner p)) enddef ;
+%D vardef bbheight (expr p) = (ypart (urcorner p - lrcorner p)) enddef ;
+%D stepsvdistance[t] := stepsvdistance[b] := 0 ;
+%D for i=1 upto nofcells :
+%D % find largest bbox
+%D p := boundingbox steps
+%D [if bbwidth(cells[t][i])>bbwidth(cells[b][i]): t else: b fi][i] ;
+%D % assign largest bbox
+%D for nn = t, b :
+%D if bbwidth(cells[nn][i])>0 :
+%D setbounds cells[nn][i] to p enlarged cell_offset ;
+%D n[nn] := n[nn] + 1 ;
+%D fi ;
+%D endfor ;
+%D % determine height
+%D if n[t]>0 :
+%D stepsvdistance[t] := bbheight(cells[t][1]) + intertextdistance ;
+%D fi ;
+%D % add to row
+%D for nn = t, b :
+%D cells[nn][i] := cells[nn][i] shifted (dx,stepsvdistance[nn]) ;
+%D if bbwidth(cells[nn][i])>0 :
+%D dowithpath (boundingbox cells[nn][i],
+%D cell_line_width, cell_line_color, cell_background_color) ;
+%D fi ;
+%D endfor ;
+%D % calculate position
+%D dx := dx + interstepdistance + bbwidth(cells[b][i]) ;
+%D endfor ;
+%D boolean stacked ; stacked := false ;
+%D numeric l[][], r[][], l[][], r[][] ;
+%D pair pa, pb, pc ; path p[] ;
+%D for i=1 upto nofcells :
+%D l[t][i] := r[t][i] := l[b][i] := r[b][i] := 0 ;
+%D endfor ;
+%D % count left and right points
+%D for i=1 upto nofcells : for j=1 upto nofcells : for nn = t, b :
+%D if known texts[nn][i][j] : if bbwidth(texts[nn][i][j])>0 :
+%D l[nn][i] := l[nn][i] + 1 ;
+%D r[nn][j+i] := r[nn][j+i] + 1 ;
+%D stacked := (stacked or (j>1)) ;
+%D setbounds texts[nn][i][j] to boundingbox texts[nn][i][j] enlarged cell_offset ;
+%D fi fi ;
+%D endfor ; endfor ; endfor ;
+%D % calculate left and right points
+%D vardef do (expr nn, mm, ii, ss) =
+%D if (l[nn][ii] > 0) and (r[nn][ii] > 0) : ss else : .5 fi
+%D [ ulcorner cells[mm][ii],urcorner cells[mm][ii] ]
+%D enddef ;
+%D % draw arrow from left to right point
+%D def dodo (expr nn, ii, jj, dd) =
+%D drawarrow p[nn]
+%D withpen pencircle scaled arrow_line_width
+%D withcolor arrow_line_color ;
+%D transform tr ; tr := identity
+%D shifted point .5 along p[nn]
+%D shifted -center texts[nn][ii][jj]
+%D if not stacked : shifted (0,dd) fi ;
+%D dowithpath ((boundingbox texts[nn][ii][jj]) transformed tr,
+%D text_line_width, text_line_color, text_fill_color) ;
+%D enddef ;
+%D % draw top and bottom text boxes
+%D for i=1 upto nofcells : for j=1 upto nofcells :
+%D pickup pencircle scaled arrow_line_width ;
+%D if known texts[t][i][j] : if bbwidth(texts[t][i][j]) > 0 :
+%D pa := top do(t, if n[t]>0 : t else : b fi, i, .6) ;
+%D pb := top do(t, if n[t]>0 : t else : b fi, j+i, .4) ;
+%D pc := .5[pa,pb] shifted (0,+step_arrow_depth) ;
+%D p[t] := pa {up} .. if not stacked : pc .. fi {down} pb ;
+%D dodo(t, i, j, +intertextdistance) ;
+%D fi fi ;
+%D if known texts[b][i][j] : if bbwidth(texts[b][i][j]) > 0 :
+%D pa := (bot do(b, b, i, .6)) shifted (0,-bbheight(cells[b][i])) ;
+%D pb := (bot do(b, b, j+i, .4)) shifted (0,-bbheight(cells[b][j+i])) ;
+%D pc := .5[pa,pb] shifted (0,-step_arrow_depth) ;
+%D p[b] := pa {down} .. if not stacked : pc .. fi {up} pb ;
+%D dodo(b, i, j, -intertextdistance) ;
+%D fi fi ;
+%D endfor ; endfor ;
+%D endgroup ;
+%D enddef ;
+%D \stoptypen
+%D
+%D If you compare both methods, you will notice that the
+%D first method is the cleanest, but not the most efficient
+%D (since it needs \TEX\ runs within \METAPOST\ runs within
+%D \TEX\ runs).
diff --git a/metapost/context/mp-tool.mp b/metapost/context/mp-tool.mp
index 76c7708cf..408d56dfb 100644
--- a/metapost/context/mp-tool.mp
+++ b/metapost/context/mp-tool.mp
@@ -11,6 +11,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
+% a cleanup is needed, like using image and alike
+
%D This module is rather preliminary and subjected to
%D changes.
@@ -23,7 +25,28 @@ boolean context_tool ; context_tool := true ;
prologues := 2 ; % 1 = troff, 2 = tex
warningcheck := 0 ;
-%D A semicolor to be used in specials:
+%D Namespace handling:
+
+% let exclamationmark = ! ;
+% let questionmark = ? ;
+%
+% def unprotect =
+% let ! = relax ;
+% let ? = relax ;
+% enddef ;
+%
+% def protect =
+% let ! = exclamationmark ;
+% let ? = questionmark ;
+% enddef ;
+%
+% unprotect ;
+%
+% mp!some!module = 10 ; show mp!some!module ; show somemodule ;
+%
+% protect ;
+
+%D A semicolor to be used in specials: ? ? ?
string semicolor ; semicolor := char 59 ;
@@ -31,7 +54,8 @@ string semicolor ; semicolor := char 59 ;
%D high resolution boundingbox to the \POSTSCRIPT\ file. This
%D hack is due to John Hobby himself.
-% somehow the first one gets no HiRes.
+% When somehow the first one gets no HiRes, then make sure
+% that the format matches the mem sizes in the config file.
vardef ddecimal primary p =
" " & decimal xpart p &
@@ -352,21 +376,21 @@ enddef;
% TODO TODO TODO TODO, not yet ok
primarydef p xsized w =
- (p scaled (w/(xpart urcorner p - xpart llcorner p)))
+ (p if bbwidth(p)>0 : scaled (w/bbwidth(p)) fi)
enddef ;
primarydef p ysized h =
- (p scaled (h/(ypart urcorner p - ypart llcorner p)))
+ (p if bbheight(p)>0 : scaled (h/bbheight(p)) fi)
enddef ;
-primarydef p sized wh =
- (p xscaled (xpart wh/(xpart urcorner p - xpart llcorner p))
- yscaled (ypart wh/(ypart urcorner p - ypart llcorner p)))
+primarydef p xysized wh =
+ (p if (bbwidth(p)>0) and (bbheight(p)>0) :
+ xscaled (xpart wh/bbwidth(p)) yscaled (ypart wh/bbheight(p))
+ fi)
enddef ;
-primarydef p xysized wh =
- (p xscaled (xpart wh/(xpart urcorner p - xpart llcorner p))
- yscaled (ypart wh/(ypart urcorner p - ypart llcorner p)))
+primarydef p sized wh =
+ (p xysized wh)
enddef ;
def xscale_currentpicture(expr w) =
@@ -617,6 +641,26 @@ primarydef p ulmoved d =
((ulcorner p) shifted (-xpart paired(d),+ypart paired(d)))
enddef ;
+primarydef p leftenlarged d =
+ (llcorner p shifted (-d,0) -- lrcorner p --
+ urcorner p -- ulcorner p shifted (-d,0) -- cycle)
+enddef ;
+
+primarydef p rightenlarged d =
+ (llcorner p -- lrcorner p shifted (d,0) --
+ urcorner p shifted (d,0) -- ulcorner p -- cycle)
+enddef ;
+
+primarydef p topenlarged d =
+ (llcorner p -- lrcorner p --
+ urcorner p shifted (0,-d) -- ulcorner p shifted (0,-d) -- cycle)
+enddef ;
+
+primarydef p bottomenlarged d =
+ (llcorner p shifted (0,d) -- lrcorner p shifted (0,d) --
+ urcorner p -- ulcorner p -- cycle)
+enddef ;
+
%D Nice too:
primarydef p superellipsed s =
@@ -705,6 +749,12 @@ enddef ;
vardef leftpath expr p = leftrightpath(p,true ) enddef ;
vardef rightpath expr p = leftrightpath(p,false) enddef ;
+%D Drawoptions
+
+def saveoptions =
+ save _op_ ; def _op_ = enddef ;
+enddef ;
+
%D Tracing.
let normaldraw = draw ;
@@ -739,6 +789,16 @@ vardef drawarrowpath expr p =
drawarrow p _pth_opt_
enddef ;
+def midarrowhead expr p =
+ arrowhead p cutafter
+ (point length(p cutafter point .5 along p)+ahlength on p)
+enddef ;
+
+vardef arrowheadonpath (expr p, s) =
+ save autoarrows ; boolean autoarrows ; autoarrows := true ;
+ arrowhead p if s<1 : cutafter (point (s*arclength(p)+.5ahlength) on p) fi
+enddef ;
+
%D Points.
def drawpoint expr c =
@@ -1126,8 +1186,6 @@ vardef anglebetween (expr a, b, str) = % path path string
curve
enddef ;
-
-
% Stack
picture currentpicturestack[] ;
@@ -1337,7 +1395,11 @@ inner end ;
% real fun
-color color_map[][][] ;
+def resetcolormap =
+ color color_map[][][] ;
+enddef ;
+
+resetcolormap ;
%color_map_resolution := 1000 ;
%
@@ -1463,6 +1525,108 @@ vardef cmyk(expr c,m,y,k) =
(1-c-k,1-m-k,1-y-k)
enddef ;
+% handy
+
+vardef bbwidth (expr p) =
+ (if known p : xpart (lrcorner p - llcorner p) else : 0 fi)
+enddef ;
+
+vardef bbheight (expr p) =
+ (if known p : ypart (urcorner p - lrcorner p) else : 0 fi)
+enddef ;
+
+color nocolor ; numeric noline ; % both unknown signals
+
+def dowithpath (expr p, lw, lc, bc) =
+ if known p :
+ if known bc :
+ fill p withcolor bc ;
+ fi ;
+ if known lw and known lc :
+ draw p withpen pencircle scaled lw withcolor lc ;
+ elseif known lw :
+ draw p withpen pencircle scaled lw ;
+ elseif known lc :
+ draw p withcolor lc ;
+ fi ;
+ fi ;
+enddef ;
+
+% result from metafont discussion list (denisr/boguslawj)
+
+def ]] = ] ] enddef ; def ]]] = ] ] ] enddef ;
+def [[ = [ [ enddef ; def [[[ = [ [ [ enddef ;
+
+% not prefect, but useful since it removes redundant points.
+
+vardef dostraightened(expr sign, p) =
+ if length(p)>1 :
+ save pp ; path pp ;
+ pp := point 0 of p ;
+ for i=1 upto length(p)-1 :
+ if round(point i of p) <> round(point length(pp) of pp) :
+ pp := pp -- point i of p ;
+ fi ;
+ endfor ;
+ save n ; numeric n ;
+ n := length(pp) ;
+ for i=0 upto n : % evt hier ook round
+ if unitvector(point i of pp -
+ point if i=0 : n else : i-1 fi of pp) <>
+ sign * unitvector(point if i=n : 0 else : i+1 fi of pp -
+ point i of pp) :
+ point i of pp --
+ fi
+%
+% to test:
+%
+% if round(unitvector(point i of pp)) <>
+% sign * round(unitvector(point if i=n : 0 else : i+1 fi of pp)) :
+% point i of pp --
+% fi
+%
+ endfor
+ cycle
+ else :
+ p
+ fi
+enddef ;
+
+% simplified : remove same points as well as redundant points
+% unspiked : remove same points as well as areas with zero distance
+
+vardef simplified expr p = dostraightened(+1,p) enddef ;
+vardef unspiked expr p = dostraightened(-1,p) enddef ;
+
+% path p ;
+% p := (2cm,1cm) -- (2cm,1cm) -- (2cm,1cm) -- (3cm,1cm) --
+% (4cm,1cm) -- (4cm,2cm) -- (4cm,2.5cm) -- (4cm,3cm) --
+% (3cm,3cm) -- (2cm,3cm) -- (1cm,3cm) -- (-1cm,3cm) --
+% .5[(-1cm,3cm),(1cm,1cm)] -- (1cm,1cm) -- cycle ;
+%
+% p := unitcircle scaled 4cm ;
+%
+% drawpath p ; drawpoints p ; drawpointlabels p ;
+% p := p shifted (4cm,0) ; p := straightened p ;
+% drawpath p ; drawpoints p ; drawpointlabels p ;
+% p := p shifted (4cm,0) ; p := straightened p ;
+% drawpath p ; drawpoints p ; drawpointlabels p ;
+
+% new
+
+path originpath ; originpath := origin -- cycle ;
+
+vardef unitvector primary z =
+ if abs z = abs origin : z else : z/abs z fi
+enddef;
+
+% also new
+
+vardef anchored@#(expr p, z) =
+ p shifted (z + (labxf@#*lrcorner p + labyf@#*ulcorner p
+ + (1-labxf@#-labyf@#)*llcorner p))
+enddef ;
+
% done
endinput ;