diff options
Diffstat (limited to 'metapost')
-rw-r--r-- | metapost/context/metafun.mp | 1 | ||||
-rw-r--r-- | metapost/context/mp-char.mp | 62 | ||||
-rw-r--r-- | metapost/context/mp-core.mp | 431 | ||||
-rw-r--r-- | metapost/context/mp-shap.mp | 46 | ||||
-rw-r--r-- | metapost/context/mp-spec.mp | 352 | ||||
-rw-r--r-- | metapost/context/mp-step.mp | 320 | ||||
-rw-r--r-- | metapost/context/mp-tool.mp | 190 |
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 ; |