diff options
Diffstat (limited to 'metapost')
19 files changed, 938 insertions, 206 deletions
diff --git a/metapost/context/base/metafun.mpii b/metapost/context/base/metafun.mpii index 0de186ed2..9c55191f7 100644 --- a/metapost/context/base/metafun.mpii +++ b/metapost/context/base/metafun.mpii @@ -62,4 +62,4 @@ def end = ; message "" ; message metafunversion ; message "" ; normalend ; enddef ; -dump ; +% dump ; diff --git a/metapost/context/base/metafun.mpiv b/metapost/context/base/metafun.mpiv index 8247c121f..601b0562e 100644 --- a/metapost/context/base/metafun.mpiv +++ b/metapost/context/base/metafun.mpiv @@ -48,4 +48,4 @@ def end = ; message "" ; message metafunversion ; message "" ; normalend ; enddef ; -dump ; % obsolete in mplib +% dump ; % obsolete in mplib diff --git a/metapost/context/base/mp-base.mpii b/metapost/context/base/mp-base.mpii index 93cb5e90c..0f8104447 100644 --- a/metapost/context/base/mp-base.mpii +++ b/metapost/context/base/mp-base.mpii @@ -1,12 +1,15 @@ % This is (currently) a copy of the plain.mp file. We use a copy % because (1) we want to make sure that there are no unresolved % dependencies, and (2) we may patch this file eventually. +% +% colorpart will be overloaded later (we already had that one) +% _findarr now has a filldraw, was fill in 0.63 % This file gives the macros for plain MetaPost % It contains all the features of plain METAFONT except those specific to % font-making. (See The METAFONTbook by D.E. Knuth). % There are also a number of macros for labeling figures, etc. -string base_name, base_version; base_name="plain"; base_version="0.63"; +string base_name, base_version; base_name="plain"; base_version="1.004 for metafun ii"; message "Preloading the plain mem file, version "&base_version; @@ -115,6 +118,26 @@ green = (0,1,0); blue = (0,0,1); background = white; % The user can reset this +% color part selection for within +def colorpart primary t = + if colormodel t=7: + (cyanpart t, magentapart t, yellowpart t, blackpart t) + elseif colormodel t=5: + (redpart t, greenpart t, bluepart t) + elseif colormodel t=3: + (greypart t) + elseif colormodel t=1: + false + else: + %%% For clipping and bounding paths, etc. + if defaultcolormodel=7: (0,0,0,1) + elseif defaultcolormodel=5: black + elseif defaultcolormodel=3: 0 + else: false + fi + fi +enddef; + % picture constants picture blankpicture,evenly,withdots; blankpicture=nullpicture; % `display blankpicture...' @@ -441,8 +464,8 @@ enddef; def _findarr text t = draw _apth t; - fill arrowhead _apth withpen currentpen t; - fill arrowhead reverse _apth withpen currentpen t + filldraw arrowhead _apth withpen currentpen t; + filldraw arrowhead reverse _apth withpen currentpen t enddef; @@ -479,7 +502,6 @@ def label = draw thelabel enddef; newinternal dotlabeldiam; dotlabeldiam:=3bp; vardef dotlabel@#(expr s,z) text t_ = label@#(s,z) t_; -% label@#(s,z); interim linecap:=rounded; draw z withpen pencircle scaled dotlabeldiam t_; enddef; diff --git a/metapost/context/base/mp-base.mpiv b/metapost/context/base/mp-base.mpiv index 7b3a69bb0..2887cc462 100644 --- a/metapost/context/base/mp-base.mpiv +++ b/metapost/context/base/mp-base.mpiv @@ -13,9 +13,9 @@ string base_name, base_version ; base_name := "plain" ; -base_version := "0.63" ; +base_version := "1.004 for metafun iv" ; -message "Preloading the plain mem file, version " & base_version ; +message "loading metafun, including plain.mp version " & base_version ; delimiters () ; % this makes parentheses behave like parentheses @@ -197,6 +197,28 @@ background := white ; % obsolete let graypart = greypart ; let graycolor = greycolor ; +% color part (will be overloaded) + +def colorpart primary t = + if colormodel t=7: + (cyanpart t, magentapart t, yellowpart t, blackpart t) + elseif colormodel t = 5 : + (redpart t, greenpart t, bluepart t) + elseif colormodel t = 3 : + (greypart t) + elseif colormodel t = 1 : + false + elseif defaultcolormodel = 7 : + (0,0,0,1) + elseif defaultcolormodel = 5 : + black + elseif defaultcolormodel = 3 : + 0 + else : + false + fi +enddef ; + % picture constants picture blankpicture, evenly, withdots ; @@ -704,10 +726,10 @@ def _finarr text t = filldraw arrowhead _apth t enddef ; -def _findarr text t = +def _findarr text t = % this had fill in 0.63 (potential incompatibility) draw _apth t ; - fill arrowhead _apth withpen currentpen t ; - fill arrowhead reverse _apth withpen currentpen t ; % ; added HH + filldraw arrowhead _apth withpen currentpen t ; + filldraw arrowhead reverse _apth withpen currentpen t ; % ; added HH enddef ; %% macros for labels diff --git a/metapost/context/base/mp-grap.mpiv b/metapost/context/base/mp-grap.mpiv index a6a4e21e8..64e63b90c 100644 --- a/metapost/context/base/mp-grap.mpiv +++ b/metapost/context/base/mp-grap.mpiv @@ -41,6 +41,7 @@ fi % OUT loc value for labels relative to whole graph % gdata(file,s,text) read coords from file ; evaluate t w/ tokens s[] % auto.<x or y> default x or y tick locations (for interation) +% tick.<bot|top|..>(fmt,u) draw centered tick from given side at u w/ format % itick.<bot|top|..>(fmt,u) draw inward tick from given side at u w/ format % otick.<bot|top|..>(fmt,u) draw outward tick at coord u ; label format fmt % grid.<bot|top|..>(fmt,u) draw grid line at u with given side labeled @@ -67,37 +68,52 @@ fi input string.mp % Private version of a few marith macros, fixed for double math... +newinternal Mzero; Mzero := -16384; % Anything at least this small is treated as zero newinternal mlogten ; mlogten := mlog(10) ; +newinternal singleinfinity ; singleinfinity := 2**128 ; newinternal doubleinfinity ; doubleinfinity := 2**1024 ; % Note that we get arithmetic overflows if we set to -doubleinfinity below. +% (but "only on odd days"...) % Safely convert a number to mlog form, trapping zero. vardef graph_mlog primary x = - if unknown x: whatever elseif x=0: -.5doubleinfinity else: mlog(abs x) fi + if unknown x: whatever + elseif x=0: Mzero + else: mlog(abs x) fi enddef ; vardef graph_exp primary x = - if unknown x: whatever else: mexp(x) fi + if unknown x: whatever + elseif x<=Mzero: 0 + else: mexp(x) fi enddef ; % and add the following for utility/completeness % (replacing the definitions in mp-tool.mpiv). vardef logten primary x = - if unknown x: whatever elseif x=0: -.5doubleinfinity else: mlog(abs x)/mlog(10) fi + if unknown x: whatever + elseif x=0: Mzero + else: mlog(abs x)/mlog(10) fi enddef ; vardef ln primary x = - if unknown x: whatever elseif x=0: -.5doubleinfinity else: mlog(abs x)/256 fi + if unknown x: whatever + elseif x=0: Mzero + else: mlog(abs x)/256 fi enddef ; vardef exp primary x = - if unknown x: whatever else: (mexp 256)**x fi + if unknown x: whatever + elseif x<= Mzero: 0 + else: (mexp 256)**x fi enddef ; vardef powten primary x = - if unknown x: whatever else: 10**x fi + if unknown x: whatever + elseif x<= Mzero: 0 + else: 10**x fi enddef ; % Convert x from mlog form into a pair whose xpart gives a mantissa and whose % ypart gives a power of ten. vardef graph_Meform(expr x) = - if x<=-doubleinfinity : origin + if x<=Mzero : origin else : save e, m ; e=floor(x/mlogten)-3; m := mexp(x-e*mlogten) ; if abs m<1000 : m := m*10 ; e := e-1 ; elseif abs m>=10000 : m := m/10 ; e := e+1 ; fi @@ -118,7 +134,7 @@ enddef ; vardef graph_error(expr x,s) = interim showstopping :=0 ; - show x ; errmessage s; + show x ; errmessage s ; enddef ; %%%%%%%%%%%%%%%%%%%%%%%% Data structures, begingraph %%%%%%%%%%%%%%%%%%%%%%%% @@ -153,8 +169,12 @@ def begingraph(expr w, h) = save graph_last_drawn ; picture graph_last_drawn ; % result of last gdraw or gfill graph_last_drawn = nullpicture ; + save graph_last_path ; + path graph_last_path ; % last gdraw or gfill path in data coordinates. save graph_plot_picture ; picture graph_plot_picture ; % a picture from the `plot' option known when plot allowed + save graph_foreground ; + color graph_foreground ; % drawing color, if set. save graph_label ; picture graph_label[] ; % labels to place around the whole graph when it is done save graph_autogrid_needed ; @@ -242,12 +262,13 @@ def graph_with_pen_and_color(expr q) = fi enddef ; -% Add picture component q to picture @# and change part p to tp, where p is -% something from q that needs coordinate transformation. The type of p is pair -% or path. +% Add picture component q to picture @# and change part p to tp, +% where p is something from q that needs coordinate transformation. +% The type of p is pair or path. % Pair o is the value of p that makes tp (0,0). This implements the trick -% whereby using 1 instead of 0 for th the width or height or the setbounds path +% whereby using 1 instead of 0 for the width or height or the setbounds path % for a label picture suppresses shifting in x or y. +% %vardef graph_picture_conversion@#(expr q, o)(text tp) = % save p ; % if stroked q : @@ -259,34 +280,37 @@ enddef ; % else : % interim truecorners :=0 ; % pair p ; p=llcorner q; -% if urcorner q<>p : p :=p+graph_coordinate_multiplication(o-p,urcorner q-p) ; fi +% if urcorner q<>p : p := p + graph_coordinate_multiplication(o-p,urcorner q-p) ; fi % addto @# also q shifted ((tp)-llcorner q) ; % fi %enddef ; -% TH : new version from code found at sarovar tracker. This makes -% grdaw clip the result to the window defined with setrange +% +% This new version makes gdraw clip the result to the window defined with setrange vardef graph_picture_conversion@#(expr q, o)(text tp) = - save p, tp_geclipt ; - picture tp_geclipt ; tp_geclipt :=nullpicture; + save p ; + save do_clip, tp_clipped ; boolean do_clip ; do_clip := true ; + picture tp_clipped ; tp_clipped := nullpicture; if stroked q : path p ; p=pathpart q; - %%% --- SDV added - addto tp_geclipt doublepath tp graph_with_pen_and_color(q) dashed dashpart q ; - clip tp_geclipt to origin--(xpart Z_.graph_dimensions,0)--Z_.graph_dimensions--(0, ypart Z_.graph_dimensions)--cycle ; - addto @# also tp_geclipt ; - %%% - %%% --- SDV deleted - %%addto @# doublepath tp graph_with_pen_and_color(q) dashed dashpart q ; - %%% + addto tp_clipped doublepath tp graph_with_pen_and_color(q) dashed dashpart q ; + %draw bbox tp_clipped withcolor red ; elseif filled q : path p ; p=pathpart q; - addto @# contour tp graph_with_pen_and_color(q) ; + addto tp_clipped contour tp graph_with_pen_and_color(q) ; + %draw bbox tp_clipped withcolor green ; else : - interim truecorners :=0 ; + if (urcorner q<>llcorner q) : do_clip := false ; fi % Do not clip the axis labels; + interim truecorners := 0 ; pair p ; p=llcorner q; - if urcorner q<>p : p :=p+graph_coordinate_multiplication(o-p,urcorner q-p) ; fi - addto @# also q shifted ((tp)-llcorner q) ; + if urcorner q<>p : p := p + graph_coordinate_multiplication(o-p,urcorner q-p) ; fi + addto tp_clipped also q shifted ((tp)-llcorner q) ; + %draw bbox tp_clipped withcolor if do_clip : cyan else : blue fi ; + fi + if do_clip : + clip tp_clipped to origin--(xpart Z_.graph_dimensions,0)--Z_.graph_dimensions-- + (0,ypart Z_.graph_dimensions)--cycle ; fi + addto @# also tp_clipped ; enddef ; def graph_coordinate_multiplication(expr a,b) = (xpart a*xpart b, ypart a*ypart b) enddef ; @@ -335,7 +359,7 @@ vardef graph_set_bounds@#(expr l, h) = graph_clear_bounds@# ; if @#graph_coordinate_type>0 : @#low = if unknown l : - whatever + whatever else : if abs @#graph_coordinate_type=log : graph_mlog fi if string l : scantokens fi l fi ; @@ -345,7 +369,7 @@ vardef graph_set_bounds@#(expr l, h) = if abs @#graph_coordinate_type=log : graph_mlog fi if string h : scantokens fi h fi ; else : - -@#high = if unknown l : + -@#high = if unknown l : whatever else : if abs @#graph_coordinate_type=log : graph_mlog fi if string l : scantokens fi l @@ -479,7 +503,7 @@ enddef ; vardef augment@#(text t) = interim warningcheck := 0 ; if not path begingroup @# endgroup : - Gerr(begingroup @# endgroup, "Cannot augment--not a path") ; + graph_error(begingroup @# endgroup, "Cannot augment--not a path") ; else : def graph_comma= hide(def graph_comma=,enddef) enddef ; if known @# : @# :=@#-- else : @#= fi @@ -496,6 +520,7 @@ enddef ; % Unknown pair components are set to 0 because glabel and gdotlabel understand % unknown coordinates as `0 in absolute units'. vardef graph_unknown_pair_bbox(expr p) = + interim warningcheck:=0 ; if known p : addto graph_current_bb doublepath p ; else : save x,y ; @@ -507,19 +532,24 @@ vardef graph_unknown_pair_bbox(expr p) = graph_current_bb := image(fill llcorner graph_current_bb..urcorner graph_current_bb--cycle) ; enddef ; - % Initiate a gdraw or gfill command. This must be done before scanning the % argument, because that could invoke the `if known graph_plot_picture' test in a following % plot option . def graph_addto = + def graph_errorbar_text = enddef ; + color graph_foreground ; + path graph_last_path ; graph_last_drawn := graph_plot_picture := nullpicture ; addto graph_last_drawn enddef; % Handle the part of a Gdraw command that uses path or data file p. def graph_draw expr p = - if string p : graph_convert_user_path_to_internal graph_readpath(p) - elseif path p or pair p : graph_convert_user_path_to_internal p + if string p : hide(graph_last_path := graph_readpath(p) ;) + graph_convert_user_path_to_internal graph_last_path + elseif path p or pair p : + hide(graph_last_path := p ;) + graph_convert_user_path_to_internal p else : graph_error(p,"gdraw argument should be a data file or a path") origin fi @@ -529,8 +559,10 @@ enddef ; % Handle the part of a Gdraw command that uses path or data file p. def graph_fill expr p = - if string p : graph_convert_user_path_to_internal graph_readpath(p) --cycle - elseif cycle p : graph_convert_user_path_to_internal p + if string p : hide(graph_last_path := graph_readpath(p) --cycle ;) + graph_convert_user_path_to_internal graph_last_path + elseif cycle p : hide(graph_last_path := p ;) + graph_convert_user_path_to_internal p else : graph_error(p,"gfill argument should be a data file or a cyclic path") origin..cycle fi graph_withlist _op_ @@ -543,13 +575,81 @@ def gfill = graph_addto contour graph_fill enddef ; % This is used in graph_draw and graph_fill to allow postprocessing graph_last_drawn def graph_withlist text t_ = t_ ; graph_post_draw; enddef; +def witherrorbars(text t) text options = + hide( + def graph_errorbar_text = t enddef ; + save pic ; picture pic ; pic := image(draw origin _op_ options ;) ; + if color colorpart pic : graph_foreground := colorpart pic ; fi + ) + options +enddef ; + +picture graph_errorbar_picture ; graph_errorbar_picture := image(draw (left--right) scaled .5 ;) ; +%picture graph_xbar_picture ; graph_xbar_picture := image(draw (down--up) scaled .5 ;) ; +%picture graph_ybar_picture ; graph_ybar_picture := image(draw (left--right) scaled .5 ;) ; + +vardef graph_errorbars(text t) = + if known graph_last_path : + save n, p, q ; path p ; pair q ; + save pic ; picture pic[] ; pic0 := nullpicture ; + pic1 := if known graph_xbar_picture : graph_xbar_picture + elseif known graph_errorbar_picture : graph_errorbar_picture rotated 90 + else : nullpicture fi ; + pic2 := if known graph_ybar_picture : graph_ybar_picture + elseif known graph_errorbar_picture : graph_errorbar_picture + else : nullpicture fi ; + if length pic1>0 : + pic1 := pic1 scaled graph_shapesize ; + setbounds pic1 to origin..cycle ; + fi + if length pic2>0 : + pic2 := pic2 scaled graph_shapesize ; + setbounds pic2 to origin..cycle ; + fi + for i=0 upto length graph_last_path : + clearxy ; z = point i of graph_last_path ; + n := 1 ; + for $=t : + if known $ : + q := if path $ : if length $>i : point i of $ else : origin fi + elseif pair $ : $ elseif numeric $ : ($,$) else : origin fi ; + if q<>origin : + p := graph_convert_user_path_to_internal (( + if n=1 : + (-xpart q,0)--(ypart q,0) + else : + (0,-xpart q)--(0,ypart q) + fi ) shifted z) ; + addto pic0 doublepath p ; + if length pic[n]>0 : + if ypart q<>0 : + addto pic0 also pic[n] shifted point 1 of p ; + fi + if xpart q<>0 : + addto pic0 also pic[n] rotated 180 shifted point 0 of p ; + fi + fi + fi + fi + exitif incr n>3 ; + endfor + endfor + if length pic0>0 : + save bg, fg ; color bg, fg ; + bg := if known graph_background : graph_background else : background fi ; + fg := if known graph_foreground : graph_foreground else : black fi ; + addto graph_current_graph also pic0 withpen currentpen scaled 2 _op_ withcolor bg ; + addto graph_current_graph also pic0 withpen currentpen scaled .5 _op_ withcolor fg ; + fi + fi +enddef ; % Set graph_plot_picture so the postprocessing step will plot picture p at each path knot. % Also select nullpen to suppress stroking. def plot expr p = if known graph_plot_picture : withpen nullpen - hide (graph_plot_picture :=image( + hide (graph_plot_picture := image( if bounded p : for q within p : graph_addto_currentpicture q endfor % Save memory else : graph_addto_currentpicture p fi graph_setbounds origin..cycle)) @@ -575,6 +675,7 @@ vardef graph_post_draw = if filled graph_last_drawn or not graph_is_null(penpart graph_last_drawn) : addto graph_current_graph also graph_last_drawn ; fi + graph_errorbars(graph_errorbar_text) ; if length graph_plot_picture>0 : for i=0 upto length p if cycle p : -1 fi : addto graph_current_graph also graph_plot_picture shifted point i of p ; @@ -623,9 +724,9 @@ enddef ; % Stash the result drawing command c in the graph_label table using with list w and -% an index based on angle laboff$. +% an index based on angle mfun_laboff$. vardef graph_stash_label(suffix $)(text c) text w = - graph_label[1.5+angle laboff$ /90] = image(c(origin) w) ; + graph_label[1.5+angle mfun_laboff$ /90] = image(c(origin) w) ; enddef ; @@ -658,10 +759,13 @@ def OUT = enddef ; % location text for outside labels % Grid lines and tick marks are transformed versions of the templates below. % In the template paths, (0,0) is on the edge of the frame and inward is to % the right. -path Gtemplate.itick, Gtemplate.otick, Gtemplate.grid ; +path Gtemplate.tick, Gtemplate.itick, Gtemplate.otick, Gtemplate.grid ; +Gtemplate.tick = (-3.5bp,0)--(3.5bp,0) ; Gtemplate.itick = origin--(7bp,0) ; Gtemplate.otick = (-7bp,0)--origin ; -Gtemplate.grid = origin--(1,0) ; +Gtemplate.grid = origin--(1,0) ; + +vardef tick@#(expr f,u) text w = graph_tick_label(@#,@,false,f,u,w) ; enddef; vardef itick@#(expr f,u) text w = graph_tick_label(@#,@,false,f,u,w) ; enddef; @@ -682,7 +786,7 @@ enddef ; % Generate label positioning arguments appropriate for label suffix $ and % coordinate u. def graph_generate_label_position(suffix $)(expr u) = - if xpart laboff.$=0 : u,whatever else : whatever,u fi + if xpart mfun_laboff.$=0 : u,whatever else : whatever,u fi enddef ; @@ -696,9 +800,9 @@ vardef graph_gridline_picture@#(suffix $)(expr c, f, u)(text w) = save p ; path p; interim warningcheck :=0 ; graph_autogrid_needed :=false ; - p = Gtemplate$ zscaled -laboff@# + p = Gtemplate$ zscaled -mfun_laboff@# if c : Gxyscale fi - shifted (((.5 + laboff@# dotprod (.5,.5)) * laboff@#) Gxyscale) ; + shifted (((.5 + mfun_laboff@# dotprod (.5,.5)) * mfun_laboff@#) Gxyscale) ; image(draw p w ; label@#(if string f : format(f,u) else : f fi, point 0 of p)) fi @@ -711,7 +815,7 @@ vardef frame@# text w = graph_frame_needed :=false ; picture p_ ; p_ = image(draw - if str@#<>"" : subpath round(angle laboff@#*graph_frame_pair_a+graph_frame_pair_b) of fi + if str@#<>"" : subpath round(angle mfun_laboff@#*graph_frame_pair_a+graph_frame_pair_b) of fi unitsquare Gxyscale w) ; graph_draw_label((whatever,whatever),,draw p_ shifted) ; enddef ; @@ -999,7 +1103,7 @@ vardef format(expr f, x) = textext(strfmt(f, x)) enddef ; % unfilled outline, interior filled with different shades of the background. % This allows overlapping points on a plot to be more distinguishable. -vardef graph_shapesize = .33BodyFontSize enddef ; +vardef graph_shapesize = (.33BodyFontSize) enddef ; path graph_shape[] ; % (internal) symbol path @@ -1073,25 +1177,35 @@ def downtriangles(expr f) = plotsymbol(13,f) enddef ; def lefttriangles(expr f) = plotsymbol(33,f) enddef ; def righttriangles(expr f) = plotsymbol(23,f) enddef ; +% f (fill) is color, numeric or boolean, otherwise background. def plotsymbol(expr n, f) text t = if known graph_shape[n] : image( save bg, fg ; color bg, fg ; bg := if known graph_background : graph_background else : background fi ; save pic ; picture pic ; pic := image(draw origin _op_ t ;) ; - fg := if color colorpart pic : colorpart pic else : black fi ; + if color colorpart pic : graph_foreground := colorpart pic ; fi + fg := if known graph_foreground : graph_foreground else : black fi ; save p ; path p ; p = graph_shape[n] scaled graph_shapesize ; draw p withcolor bg withpen currentpen scaled 2 ; % halo - if cycle p : fill p withcolor - if color f and known f : - f - elseif numeric f and known f : - f[bg,fg] - else : - bg - fi ; + currentpen := currentpen scaled .5 ; + if cycle p : + fill p withcolor + if known f : + if color f : + f + elseif numeric f : + f[bg,fg] + elseif boolean f and f : + fg + else + bg + fi + else : + bg + fi ; fi - draw p withpen currentpen _op_ t ; + draw p _op_ t ; ) else : nullpicture @@ -1164,7 +1278,7 @@ enddef ; def makefunctionpath (expr f, t, n) (text func) = (for x=f step ((t-f)/(abs n)) until t : - if x<>f : .. fi + if x<>f : -- fi (x, func) endfor ) enddef ; @@ -1269,9 +1383,9 @@ numeric fit_chi_squared ; vardef polynomial_fit (suffix p, $) (expr n) (text t) = if not path p : - Gerr(p, "Cannot fit--not a path") ; + graph_error(p, "Cannot fit--not a path") ; elseif length p < n : - Gerr(p, "Cannot fit--not enough points") ; + graph_error(p, "Cannot fit--not enough points") ; else : fit_chi_squared := 0 ; % calculate sums of the data @@ -1285,7 +1399,24 @@ vardef polynomial_fit (suffix p, $) (expr n) (text t) = endfor for i=0 upto length p : clearxy ; z = point i of p ; - w := if length(t) > 0 : t else : 1 fi ; % weight + w := 1 ; % weight + if known t : + if numeric t : + w := 1 if t<>0 : /(abs t) fi ; + elseif pair t : + if t<>origin : + w := 1/(abs t) ; + fi + elseif path t : + if length t>= i: + if point i of t<>origin : + w := 1/(abs point i of t) ; + fi + else : + w := 0 ; + fi ; + fi + fi x1 := w ; for j=0 upto 2n : sumx[j] := sumx[j] + x1 ; @@ -1356,13 +1487,29 @@ vardef exponential_function (suffix $) (expr x) = $1*exp($0*x) enddef ; vardef exponential_fit (suffix p, $) (text t) = save a ; numeric a[] ; - save q ; path q ; % fit to the log of the ordinate + save q ; path q[] ; % fit to the log of the ordinate for i=0 upto length p : - if ypart(point i of p)>0 : - augment.q(xpart(point i of p),ln(ypart(point i of p))) ; + clearxy ; z = point i of p ; + if y>0 : + augment.q0(x,ln(y)) ; + augment.q1( + if known t : + if numeric t : (0,ln(t)) + elseif pair t : (xpart t,ln(ypart t)) + elseif path t : + if length t>=i : + hide(z1 = point i of t;) + (x1,ln(y1)) + else : + origin + fi + fi + else : + (0,1) + fi ) ; fi endfor - linear_fit(q,a,t) ; + linear_fit(q0,a,q1) ; save e ; e := exp(sqrt(fit_chi_squared)) ; fit_chi_squared := e * e ; $0 := a1 ; @@ -1377,13 +1524,29 @@ vardef power_law_function (suffix $) (expr x) = $1*(x**$0) enddef ; vardef power_law_fit (suffix p, $) (text t) = save a ; numeric a[] ; - save q ; path q ; % fit to the logs of the abscissae and ordinates + save q ; path q[] ; % fit to the logs of the abscissae and ordinates for i=0 upto length p : - if (xpart(point i of p)>0) and (ypart(point i of p)>0) : - augment.q(ln(xpart(point i of p)),ln(ypart(point i of p))) ; + clearxy ; z = point i of p ; + if (x>0) and (y>0) : + augment.q0(ln(x),ln(y)) ; + augment.q1( + if known t : + if numeric t : (0,ln(t)) + elseif pair t : (ln(xpart t),ln(ypart t)) + elseif path t : + if length t>=i : + hide(z1 = point i of t) + (ln(x1),ln(y1)) + else : + origin + fi + fi + else : + (0,1) + fi ) ; fi endfor - linear_fit(q,a,t) ; + linear_fit(q0,a,q1) ; save e ; e := exp(sqrt(fit_chi_squared)) ; fit_chi_squared := e * e ; $0 := a1 ; @@ -1411,13 +1574,29 @@ enddef ; vardef gaussian_fit (suffix p, $) (text t) = save a ; numeric a[] ; - save q ; path q ; % fit to the log of the ordinate + save q ; path q[] ; % fit to the log of the ordinate for i=0 upto length p : - if ypart(point i of p)>0 : - augment.q(xpart(point i of p), ln(ypart(point i of p))) ; + clearxy ; z = point i of p ; + if y>0 : + augment.q0(x,ln(y)) ; + augment.q1( + if known t : + if numeric t : (0,ln(t)) + elseif pair t : (xpart t,ln(ypart t)) + elseif path t : + if length t>=i : + hide(z1 = point i of t) + (x1,ln(y1)) + else : + origin + fi + fi + else : + (0,1) + fi ) ; fi endfor - polynomial_fit(q,a,2,if t > 0 : ln(t) else : 0 fi) ; + polynomial_fit(q0,a,2,q1) ; save e ; e := exp(sqrt(fit_chi_squared)) ; fit_chi_squared := e * e ; $1 := sqrt(-lntwo/a2) ; diff --git a/metapost/context/base/mp-mlib.mpiv b/metapost/context/base/mp-mlib.mpiv index 9a2042924..e667e4064 100644 --- a/metapost/context/base/mp-mlib.mpiv +++ b/metapost/context/base/mp-mlib.mpiv @@ -99,6 +99,8 @@ newinternal textextoffset ; textextoffset := 0 ; numeric mfun_tt_w[], mfun_tt_h[], mfun_tt_d[] ; % we can consider using colors (less hash space) numeric mfun_tt_n ; mfun_tt_n := 0 ; picture mfun_tt_p ; mfun_tt_p := nullpicture ; +picture mfun_tt_o ; mfun_tt_o := nullpicture ; +picture mfun_tt_c ; mfun_tt_c := nullpicture ; if unknown mfun_trial_run : boolean mfun_trial_run ; @@ -117,6 +119,8 @@ fi ; def mfun_reset_tex_texts = mfun_tt_n := 0 ; mfun_tt_p := nullpicture ; + mfun_tt_o := nullpicture ; % redundant + mfun_tt_c := nullpicture ; % redundant enddef ; def mfun_flush_tex_texts = @@ -131,37 +135,100 @@ extra_beginfig := extra_beginfig & "mfun_reset_tex_texts ;" ; % flush twice: once in location in order to pick up e.g. color properties, % and once at the end because we need to flush missing ones. -vardef rawtextext(expr str) = +% vardef rawtextext(expr str) = +% if str = "" : +% nullpicture +% elseif mfun_trial_run : +% mfun_tt_n := mfun_tt_n + 1 ; +% mfun_tt_o := image(draw origin) ; % save drawoptions +% addto mfun_tt_p doublepath unitsquare +% withprescript "tx_number=" & decimal mfun_tt_n +% withprescript "tx_stage=extra" +% withpostscript str ; +% image ( +% addto currentpicture doublepath unitsquare +% withprescript "tx_number=" & decimal mfun_tt_n +% withprescript "tx_stage=trial" +% withprescript "tx_color=" & colordecimals colorpart mfun_tt_o +% withpostscript str +% ; ) +% else : +% mfun_tt_n := mfun_tt_n + 1 ; +% if known mfun_tt_d[mfun_tt_n] : +% image ( +% addto currentpicture doublepath unitsquare +% xscaled mfun_tt_w[mfun_tt_n] +% yscaled (mfun_tt_h[mfun_tt_n] + mfun_tt_d[mfun_tt_n]) +% withprescript "tx_number=" & decimal mfun_tt_n +% withprescript "tx_stage=final" +% % withpostscript str ; % for tracing +% ; ) shifted (0,-mfun_tt_d[mfun_tt_n]) +% else : +% image ( +% addto currentpicture doublepath unitsquare +% ; ) +% fi +% fi +% enddef ; + +% vardef rawtextext(expr str) = % todo: avoid currentpicture +% if str = "" : +% nullpicture +% else : +% mfun_tt_n := mfun_tt_n + 1 ; +% mfun_tt_c := nullpicture ; +% if mfun_trial_run : +% mfun_tt_o := nullpicture ; +% addto mfun_tt_o doublepath origin _op_ ; % save drawoptions +% addto mfun_tt_p doublepath unitsquare +% withprescript "tx_number=" & decimal mfun_tt_n +% withprescript "tx_stage=extra" +% withpostscript str ; +% addto mfun_tt_c doublepath unitsquare +% withprescript "tx_number=" & decimal mfun_tt_n +% withprescript "tx_stage=trial" +% withprescript "tx_color=" & colordecimals colorpart mfun_tt_o +% withpostscript str ; +% elseif known mfun_tt_d[mfun_tt_n] : +% addto mfun_tt_c doublepath unitsquare +% xscaled mfun_tt_w[mfun_tt_n] +% yscaled (mfun_tt_h[mfun_tt_n] + mfun_tt_d[mfun_tt_n]) +% shifted (0,-mfun_tt_d[mfun_tt_n]) +% withprescript "tx_number=" & decimal mfun_tt_n +% withprescript "tx_stage=final" ; +% else : +% addto mfun_tt_c doublepath unitsquare ; % unitpicture +% fi ; +% mfun_tt_c +% fi +% enddef ; + +vardef rawtextext(expr str) = % todo: avoid currentpicture if str = "" : nullpicture - elseif mfun_trial_run : + else : mfun_tt_n := mfun_tt_n + 1 ; - addto mfun_tt_p doublepath unitsquare - withprescript "tx_number=" & decimal mfun_tt_n - withprescript "tx_stage=extra" - withpostscript str ; - image ( - addto currentpicture doublepath unitsquare + mfun_tt_c := nullpicture ; + if mfun_trial_run : + mfun_tt_o := nullpicture ; + addto mfun_tt_o doublepath origin _op_ ; % save drawoptions + addto mfun_tt_c doublepath unitsquare withprescript "tx_number=" & decimal mfun_tt_n withprescript "tx_stage=trial" - withpostscript str - ) - else : - mfun_tt_n := mfun_tt_n + 1 ; - if known mfun_tt_d[mfun_tt_n] : - image ( - addto currentpicture doublepath unitsquare - xscaled mfun_tt_w[mfun_tt_n] - yscaled (mfun_tt_h[mfun_tt_n] + mfun_tt_d[mfun_tt_n]) - withprescript "tx_number=" & decimal mfun_tt_n - withprescript "tx_stage=final" - ; % withpostscript str ; - ) shifted (0,-mfun_tt_d[mfun_tt_n]) + withprescript "tx_color=" & colordecimals colorpart mfun_tt_o + withpostscript str ; + addto mfun_tt_p also mfun_tt_c ; + elseif known mfun_tt_d[mfun_tt_n] : + addto mfun_tt_c doublepath unitsquare + xscaled mfun_tt_w[mfun_tt_n] + yscaled (mfun_tt_h[mfun_tt_n] + mfun_tt_d[mfun_tt_n]) + shifted (0,-mfun_tt_d[mfun_tt_n]) + withprescript "tx_number=" & decimal mfun_tt_n + withprescript "tx_stage=final" ; else : - image ( - addto currentpicture doublepath unitsquare ; - ) - fi + addto mfun_tt_c doublepath unitsquare ; % unitpicture + fi ; + mfun_tt_c fi enddef ; @@ -255,6 +322,46 @@ mfun_labtype.drt := 12 ; mfun_labtype.origin := 0 ; mfun_labtype.raw := 0 ; +% installlabel.foo ( 0, 1, 1, (.5,-1) ) ; + +vardef installlabel@# (expr type, x, y, offset) = + numeric labtype@# ; labtype@# := type ; + pair laboff @# ; laboff @# := offset ; + numeric labxf @# ; labxf @# := x ; + numeric labyf @# ; labyf @# := y ; +enddef ; + +% we save the plain variant + +vardef plain_thelabel@#(expr p,z) = + if string p : + plain_thelabel@#(rawtextext("\definedfont[" & defaultfont & "]" & p) scaled defaultscale,z) + else : + p shifted (z + labeloffset*laboff@# - (labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p)) + fi +enddef; + +def plain_label = % takes two arguments, contrary to textext that takes one + draw plain_thelabel +enddef ; + +let mfun_label = label ; +let mfun_thelabel = thelabel ; + +def useplainlabels = % somehow let doesn't work for all code + def label = plain_label enddef ; + def thelabel = plain_thelabel enddef ; +enddef ; + +def usemetafunlabels = + let label = mfun_label ; + let thelabel = mfun_thelabel ; +enddef ; + +plain_compatibility_data := plain_compatibility_data & "save label, thelabel ;" & "useplainlabels ;" ; + +% next comes own own: + vardef thetextext@#(expr p,z) = % interim labeloffset := textextoffset ; if string p : @@ -611,8 +718,8 @@ else : elseif colormodel p = 7 : withcolor (cyanpart p,magentapart p,yellowpart p,blackpart p) fi - withprescript prescript p - withpostscript postscript p + withprescript prescriptpart p + withpostscript postscriptpart p enddef ; fi ; @@ -662,3 +769,75 @@ enddef ; % draw textext.autoalign(160)("\strut oeps 2") ; % draw textext.autoalign(260)("\strut oeps 3") ; % draw textext.autoalign(360)("\strut oeps 4") ; + +% new +% +% passvariable("version","1.0") ; +% passvariable("number",123) ; +% passvariable("string","whatever") ; +% passvariable("point",(1,2)) ; +% passvariable("triplet",(1,2,3)) ; +% passvariable("quad",(1,2,3,4)) ; +% passvariable("boolean",false) ; +% passvariable("path",fullcircle scaled 1cm) ; + +vardef mfun_point_to_string(expr p,i) = + decimal xpart (point i of p) & " " & + decimal ypart (point i of p) & " " & + decimal xpart (precontrol i of p) & " " & + decimal ypart (precontrol i of p) & " " & + decimal xpart (postcontrol i of p) & " " & + decimal ypart (postcontrol i of p) +enddef ; + +vardef mfun_transform_to_string(expr t) = + decimal xxpart t & " " & % rx + decimal xypart t & " " & % sx + decimal yxpart t & " " & % sy + decimal yypart t & " " & % ry + decimal xpart t & " " & % tx + decimal ypart t % ty +enddef ; + +vardef mfun_numeric_to_string(expr n) = + decimal n +enddef ; + +vardef mfun_pair_to_string(expr p) = + decimal xpart p & " " & + decimal ypart p +enddef ; + +vardef mfun_rbgcolor_to_string(expr c) = + decimal redpart c & " " & + decimal greenpart c & " " & + decimal bluepart c +enddef ; + +vardef mfun_cmykcolor_to_string(expr c) = + decimal cyanpart c & " " & + decimal magentapart c & " " & + decimal yellowpart c & " " & + decimal blackpart c +enddef ; + +vardef mfun_path_to_string(expr p) = + mfun_point_to_string(p,0) for i=1 upto length(p) : & " " & mfun_point_to_string(p,i) endfor +enddef ; + +vardef mfun_boolean_to_string(expr b) = + if b : "true" else : "false" fi +enddef ; + +def passvariable(expr key, value) = + special + if numeric value : "1:" & key & "=" & mfun_numeric_to_string(value) + elseif pair value : "4:" & key & "=" & mfun_pair_to_string(value) + elseif rgbcolor value : "5:" & key & "=" & mfun_rgbcolor_to_string(value) + elseif cmykcolor value : "6:" & key & "=" & mfun_cmykcolor_to_string(value) + elseif boolean value : "3:" & key & "=" & mfun_boolean_to_string(value) + elseif path value : "7:" & key & "=" & mfun_path_to_string(value) + elseif transform value : "8:" & key & "=" & mfun_transform_to_string(value) + else : "2:" & key & "=" & value + fi ; +enddef ; diff --git a/metapost/context/base/mp-text.mpii b/metapost/context/base/mp-text.mpii index d529e9242..5f96f6788 100644 --- a/metapost/context/base/mp-text.mpii +++ b/metapost/context/base/mp-text.mpii @@ -109,6 +109,13 @@ pair laboff.raw ; laboff.raw = (0,0) ; % (infinity,infinity) ; laboff.origin = (0,0) ; labxf.origin := 0 ; labyf.origin := 0 ; laboff.raw = (0,0) ; labxf.raw := 0 ; labyf.raw := 0 ; +vardef installlabel@# (expr type, x, y, offset) = + numeric labtype@# ; labtype@# := type ; + pair laboff @# ; laboff @# := offset ; + numeric labxf @# ; labxf @# := x ; + numeric labyf @# ; labyf @# := y ; +enddef ; + vardef thelabel@#(expr s, z) = save p ; picture p ; p = s if not picture s : infont defaultfont scaled defaultscale fi ; diff --git a/metapost/context/base/mp-tool.mpii b/metapost/context/base/mp-tool.mpii index 8d8c9d920..f363f655e 100644 --- a/metapost/context/base/mp-tool.mpii +++ b/metapost/context/base/mp-tool.mpii @@ -98,6 +98,19 @@ vardef ddecimal primary p = decimal xpart p & " " & decimal ypart p enddef ; +%D Plain compatibility + +string plain_compatibility_data ; plain_compatibility_data := "" ; + +def startplaincompatibility = + begingroup ; + scantokens plain_compatibility_data ; +enddef ; + +def stopplaincompatibility = + endgroup ; +enddef ; + % is now built in % extra_endfig := extra_endfig @@ -2562,3 +2575,5 @@ primarydef p snapped s = fi ; ) p enddef ; + +let dump = relax ; diff --git a/metapost/context/base/mp-tool.mpiv b/metapost/context/base/mp-tool.mpiv index 5b53dcdef..672a051c2 100644 --- a/metapost/context/base/mp-tool.mpiv +++ b/metapost/context/base/mp-tool.mpiv @@ -64,6 +64,24 @@ vardef ddecimal primary p = decimal xpart p & " " & decimal ypart p enddef ; +%D Plain compatibility: + +string plain_compatibility_data ; plain_compatibility_data := "" ; + +def startplaincompatibility = + begingroup ; + scantokens plain_compatibility_data ; +enddef ; + +def stopplaincompatibility = + endgroup ; +enddef ; + +%D More neutral: + +let triplet = rgbcolor ; +let quadruplet = cmykcolor ; + %D Colors: newinternal nocolormodel ; nocolormodel := 1 ; @@ -192,32 +210,32 @@ def newpair text v = forsuffixes i=v : save i ; pair i ; endfor ; endd %D box, draw the graphics that may not count, and restore the %D bounding box. %D -%D \starttypen +%D \starttyping %D push_boundingbox currentpicture; %D pop_boundingbox currentpicture; -%D \stoptypen +%D \stoptyping %D %D The bounding box can be called with: %D -%D \starttypen +%D \starttyping %D boundingbox currentpicture %D inner_boundingbox currentpicture %D outer_boundingbox currentpicture -%D \stoptypen +%D \stoptyping %D %D Especially the latter one can be of use when we include %D the graphic in a document that is clipped to the bounding %D box. In such occasions one can use: %D -%D \starttypen +%D \starttyping %D set_outer_boundingbox currentpicture; -%D \stoptypen +%D \stoptyping %D %D Its counterpart is: %D -%D \starttypen +%D \starttyping %D set_inner_boundingbox p -%D \stoptypen +%D \stoptyping path mfun_boundingbox_stack ; numeric mfun_boundingbox_stack_depth ; @@ -313,6 +331,12 @@ vardef asinh primary x = ln(x+(x++1)) enddef ; vardef sinh primary x = save xx ; xx = exp x ; (xx-1/xx)/2 enddef ; vardef cosh primary x = save xx ; xx = exp x ; (xx+1/xx)/2 enddef ; +%D Sometimes this is handy: + +def undashed = + dashed nullpicture +enddef ; + %D We provide two macros for drawing stripes across a shape. %D The first method (with the n suffix) uses another method, %D slower in calculation, but more efficient when drawn. The @@ -321,67 +345,209 @@ vardef cosh primary x = save xx ; xx = exp x ; (xx+1/xx)/2 enddef ; %D the second argument identifier the way the shape is to be %D drawn. %D -%D \starttypen +%D \starttyping %D stripe_path_n %D (dashed evenly withcolor blue) %D (filldraw) %D fullcircle xscaled 100 yscaled 40 shifted (50,50) withpen pencircle scaled 4; -%D \stoptypen +%D \stoptyping %D %D The a (or angle) alternative supports arbitrary angles and %D is therefore more versatile. %D -%D \starttypen +%D \starttyping %D stripe_path_a %D (withpen pencircle scaled 2 withcolor red) %D (draw) %D fullcircle xscaled 100 yscaled 40 withcolor blue; -%D \stoptypen +%D \stoptyping %D -%D The first alternative obeys: +%D We have two alternatives, controlled by arguments or defaults (when arguments +%D are zero). +%D +%D The newer and nicer interface is used as follows (triggered by a question by Mari): +%D +%D \starttyping +%D draw image (draw fullcircle scaled 3cm shifted (0cm,0cm) withcolor green) numberstriped (1,10,3) withcolor red ; +%D draw image (draw fullcircle scaled 3cm shifted (3cm,0cm) withcolor green) numberstriped (2,20,3) withcolor green ; +%D draw image (draw fullcircle scaled 3cm shifted (3cm,3cm) withcolor green) numberstriped (3,10,5) withcolor blue ; +%D draw image (draw fullcircle scaled 3cm shifted (0cm,3cm) withcolor green) numberstriped (4,20,5) withcolor yellow ; +%D +%D draw image (draw fullcircle scaled 3cm shifted (6cm,0cm) withcolor green) anglestriped (1,20,2) withcolor red ; +%D draw image (draw fullcircle scaled 3cm shifted (9cm,0cm) withcolor green) anglestriped (2,40,2) withcolor green ; +%D draw image (draw fullcircle scaled 3cm shifted (9cm,3cm) withcolor green) anglestriped (3,60,2) withcolor blue ; +%D draw image (draw fullcircle scaled 3cm shifted (6cm,3cm) withcolor green) anglestriped (4,80,2) withcolor yellow ; +%D +%D draw image ( +%D draw fullcircle scaled 3cm shifted (0cm,0cm) withcolor green withpen pencircle scaled 2mm ; +%D draw fullcircle scaled 2cm shifted (0cm,1cm) withcolor blue withpen pencircle scaled 3mm ; +%D ) shifted (9cm,0cm) numberstriped (1,10,3) withcolor red ; +%D +%D draw image ( +%D draw fullcircle scaled 3cm shifted (0cm,0cm) withcolor green withpen pencircle scaled 2mm ; +%D draw fullcircle scaled 2cm shifted (0cm,1cm) withcolor blue withpen pencircle scaled 3mm ; +%D ) shifted (12cm,0cm) numberstriped (2,10,3) withcolor red ; +%D +%D draw image ( +%D draw fullcircle scaled 3cm shifted (0cm,0cm) withcolor green withpen pencircle scaled 2mm ; +%D draw fullcircle scaled 2cm shifted (0cm,1cm) withcolor blue withpen pencircle scaled 3mm ; +%D ) shifted (9cm,5cm) numberstriped (3,10,3) withcolor red ; +%D +%D draw image ( +%D draw fullcircle scaled 3cm shifted (0cm,0cm) withcolor green withpen pencircle scaled 2mm ; +%D draw fullcircle scaled 2cm shifted (0cm,1cm) withcolor blue withpen pencircle scaled 3mm ; +%D ) shifted (12cm,5cm) numberstriped (4,10,3) withcolor red ; +%D \stoptyping stripe_n := 10; stripe_slot := 3; +stripe_gap := 5; +stripe_angle := 45; -%D When no pen dimensions are passed, the slot determines -%D the spacing. -%D -%D The angle alternative is influenced by: +def mfun_tool_striped_number_action text extra = + for i = 1/used_n step 1/used_n until 1 : + draw point (1+i) of bounds -- point (3-i) of bounds withpen pencircle scaled penwidth extra ; + endfor ; + for i = 0 step 1/used_n until 1 : + draw point (3+i) of bounds -- point (1-i) of bounds withpen pencircle scaled penwidth extra ; + endfor ; +enddef ; -% to be redone: use image +def mfun_tool_striped_set_options(expr option) = + save isinner, swapped ; + boolean isinner, swapped ; + if option = 1 : + isinner := false ; + swapped := false ; + elseif option = 2 : + isinner := true ; + swapped := false ; + elseif option = 3 : + isinner := false ; + swapped := true ; + elseif option = 4 : + isinner := true ; + swapped := true ; + else : + isinner := false ; + swapped := false ; + fi ; +enddef ; -stripe_gap := 5; -stripe_angle := 45; +vardef mfun_tool_striped_number(expr option, p, s_n, s_slot) text extra = + image ( + begingroup ; + save pattern, shape, bounds, penwidth, used_n, used_slot ; + picture pattern, shape ; path bounds ; numeric used_s, used_slot ; + mfun_tool_striped_set_options(option) ; + used_slot := if s_slot = 0 : stripe_slot else : s_slot fi ; + used_n := if s_n = 0 : stripe_n else : s_n fi ; + shape := image(draw p) ; + bounds := boundingbox shape ; + penwidth := min(ypart urcorner shape - ypart llcorner shape, xpart urcorner shape - xpart llcorner shape) / (used_slot * used_n) ; + pattern := image ( + if isinner : + mfun_tool_striped_number_action extra ; + for s within shape : + if stroked s or filled s : + clip currentpicture to pathpart s ; + fi + endfor ; + else : + for s within shape : + if stroked s or filled s : + draw image ( + mfun_tool_striped_number_action extra ; + clip currentpicture to pathpart s ; + ) ; + fi ; + endfor ; + fi ; + ) ; + if swapped : + addto currentpicture also shape ; + addto currentpicture also pattern ; + else : + addto currentpicture also pattern ; + addto currentpicture also shape ; + fi ; + endgroup ; + ) +enddef ; + +def mfun_tool_striped_angle_action text extra = + for i = minimum -.5used_gap step used_gap until maximum : + draw (minimum,i) -- (maximum,i) extra ; + endfor ; + currentpicture := currentpicture rotated used_angle ; +enddef ; + +vardef mfun_tool_striped_angle(expr option, p, s_angle, s_gap) text extra = + image ( + begingroup ; + save pattern, shape, mask, maximum, minimum, centrum, used_angle, used_gap ; + picture pattern, shape, mask ; numeric maximum, minimum ; pair centrum ; numeric used_angle, used_gap ; + mfun_tool_striped_set_options(option) ; + used_angle := if s_angle = 0 : stripe_angle else : s_angle fi ; + used_gap := if s_gap = 0 : stripe_gap else : s_gap fi ; + shape := image(draw p) ; + centrum := center shape ; + shape := shape shifted - centrum ; + mask := shape rotated used_angle ; + maximum := max (xpart llcorner mask, xpart urcorner mask, ypart llcorner mask, ypart urcorner mask) ; + minimum := min (xpart llcorner mask, xpart urcorner mask, ypart llcorner mask, ypart urcorner mask) ; + pattern := image ( + if isinner : + mfun_tool_striped_angle_action extra ; + for s within shape : + if stroked s or filled s : + clip currentpicture to pathpart s ; + fi + endfor ; + else : + for s within shape : + if stroked s or filled s : + draw image ( + mfun_tool_striped_angle_action extra ; + clip currentpicture to pathpart s ; + ) ; + fi ; + endfor ; + fi ; + ) ; + if swapped : + addto currentpicture also shape ; + addto currentpicture also pattern ; + else : + addto currentpicture also pattern ; + addto currentpicture also shape ; + fi ; + currentpicture := currentpicture shifted - centrum ; + endgroup ; + ) +enddef; + +newinternal striped_normal_inner ; striped_normal_inner := 1 ; +newinternal striped_reverse_inner ; striped_reverse_inner := 2 ; +newinternal striped_normal_outer ; striped_normal_outer := 3 ; +newinternal striped_reverse_outer ; striped_reverse_outer := 4 ; + +secondarydef p anglestriped s = + mfun_tool_striped_angle(redpart s,p,greenpart s,bluepart s) +enddef ; + +secondarydef p numberstriped s = + mfun_tool_striped_number(redpart s,p,greenpart s,bluepart s) +enddef ; + +% for old times sake: def stripe_path_n (text s_spec) (text s_draw) expr s_path = do_stripe_path_n (s_spec) (s_draw) (s_path) enddef; def do_stripe_path_n (text s_spec) (text s_draw) (expr s_path) text s_text = - begingroup ; - save curpic, newpic, bb, pp, ww ; - picture curpic, newpic ; - path bb, pp ; - pp := s_path ; - curpic := currentpicture ; - currentpicture := nullpicture ; - s_draw pp s_text ; - bb := boundingbox currentpicture ; - newpic := currentpicture ; - currentpicture := nullpicture; - ww := min(ypart urcorner newpic - ypart llcorner newpic,xpart urcorner newpic - xpart llcorner newpic) ; - ww := ww/(stripe_slot*stripe_n) ; - for i=1/stripe_n step 1/stripe_n until 1 : - draw point (1+i) of bb -- point (3-i) of bb withpen pencircle scaled ww s_spec ; - endfor ; - for i=0 step 1/stripe_n until 1 : - draw point (3+i) of bb -- point (1-i) of bb withpen pencircle scaled ww s_spec; - endfor ; - clip currentpicture to pp ; - addto newpic also currentpicture ; - currentpicture := curpic ; - addto currentpicture also newpic ; - endgroup ; + draw image(s_draw s_path s_text) numberstriped(3,0,0) s_spec ; enddef ; def stripe_path_a (text s_spec) (text s_draw) expr s_path = @@ -389,33 +555,8 @@ def stripe_path_a (text s_spec) (text s_draw) expr s_path = enddef; def do_stripe_path_a (text s_spec) (text s_draw) (expr s_path) text s_text = - begingroup ; - save curpic, newpic, pp; picture curpic, newpic; path pp ; - pp := s_path ; - curpic := currentpicture ; - currentpicture := nullpicture ; - s_draw pp s_text ; - def do_stripe_rotation (expr p) = - (currentpicture rotatedaround(center p,stripe_angle)) - enddef ; - s_max := max ( - xpart llcorner do_stripe_rotation(currentpicture), - xpart urcorner do_stripe_rotation(currentpicture), - ypart llcorner do_stripe_rotation(currentpicture), - ypart urcorner do_stripe_rotation(currentpicture) - ) ; - newpic := currentpicture ; - currentpicture := nullpicture ; - for i=-s_max-.5stripe_gap step stripe_gap until s_max : - draw (-s_max,i)--(s_max,i) s_spec ; - endfor ; - currentpicture := do_stripe_rotation(newpic) ; - clip currentpicture to pp ; - addto newpic also currentpicture ; - currentpicture := curpic ; - addto currentpicture also newpic ; - endgroup ; -enddef; + draw image(s_draw s_path s_text) anglestriped(3,0,0) s_spec ; +enddef ; %D A few normalizing macros: @@ -763,32 +904,32 @@ primarydef p randomized s = ( p randomshifted s elseif cmykcolor p : if color s : - (uniformdeviate cyanpart s * cyanpart p, - uniformdeviate magentapart s * magentapart p, - uniformdeviate yellowpart s * yellowpart p, - uniformdeviate blackpart s * blackpart p) + ((uniformdeviate cyanpart s) * cyanpart p, + (uniformdeviate magentapart s) * magentapart p, + (uniformdeviate yellowpart s) * yellowpart p, + (uniformdeviate blackpart s) * blackpart p) elseif pair s : - ((xpart s + uniformdeviate (ypart s - xpart s)) * p) + ((xpart s + (uniformdeviate (ypart s - xpart s))) * p) else : - (uniformdeviate s * p) + ((uniformdeviate s) * p) fi elseif rgbcolor p : if color s : - (uniformdeviate redpart s * redpart p, - uniformdeviate greenpart s * greenpart p, - uniformdeviate bluepart s * bluepart p) + ((uniformdeviate redpart s) * redpart p, + (uniformdeviate greenpart s) * greenpart p, + (uniformdeviate bluepart s) * bluepart p) elseif pair s : - ((xpart s + uniformdeviate (ypart s - xpart s)) * p) + ((xpart s + (uniformdeviate (ypart s - xpart s))) * p) else : - (uniformdeviate s * p) + ((uniformdeviate s) * p) fi elseif color p : if color s : - (uniformdeviate greypart s * greypart p) + ((uniformdeviate greypart s) * greypart p) elseif pair s : - ((xpart s + uniformdeviate (ypart s - xpart s)) * p) + ((xpart s + (uniformdeviate (ypart s - xpart s))) * p) else : - (uniformdeviate s * p) + ((uniformdeviate s) * p) fi else : p + uniformdeviate s @@ -966,7 +1107,7 @@ def mfun_draw_pointlabels text t = pair _p_ ; _p_ := (point _i_ of _c_) ; _u_ := 12 * defaultscale * _u_ ; normaldraw thelabel ( decimal _i_, _p_ shifted if cycle _c_ and (_i_=0) : - fi _u_ ) _lab_opt_ t ; - endfor ; + endfor ; enddef; %D Bounding box. @@ -1137,12 +1278,12 @@ def _finarr text t = draw arrowhead _apth t ; enddef; -def _findarr text t = +def _finarr text t = if autoarrows : set_ahlength (t) fi ; - draw arrowpath _apth t ; - fill arrowhead _apth withpen currentpen t ; - fill arrowhead reverse _apth withpen currentpen t ; -enddef ; + draw arrowpath _apth t ; % arrowpath added + fill arrowhead _apth t ; + draw arrowhead _apth t undashed ; +enddef; %D Handy too ...... @@ -1165,10 +1306,10 @@ def centerarrow (expr pat,tim,len) = pointarrow(pat,tim,len, 0) enddef ; %D The \type {along} and \type {on} operators can be used %D as follows: %D -%D \starttypen +%D \starttyping %D drawdot point .5 along somepath ; %D drawdot point 3cm on somepath ; -%D \stoptypen +%D \stoptyping %D %D The number denotes a percentage (fraction). @@ -1225,9 +1366,9 @@ vardef freedotlabel (expr str, loc, ori) = draw thefreelabel(str,loc,ori) ; enddef ; -%D \starttypen +%D \starttyping %D drawarrow anglebetween(line_a,line_b,somelabel) ; -%D \stoptypen +%D \stoptyping newinternal angleoffset ; angleoffset := 0pt ; newinternal anglelength ; anglelength := 20pt ; @@ -2308,6 +2449,24 @@ enddef ; % ) % enddef ; +%D New helpers: + +def beginglyph(expr unicode, width, height, depth) = + beginfig(unicode) ; % the number is irrelevant + charcode := unicode ; + charwd := width ; + charht := height ; + chardp := depth ; +enddef ; + +def endglyph = + setbounds currentpicture to (boundingbox unitsquare xscaled charwd yscaled (charht + chardp) shifted (0,-chardp)) ; + if known charscale : + currentpicture := currentpicture scaled charscale ; + fi ; + endfig ; +enddef ; + %D Dimensions have bever been an issue as traditional MP can't make that large %D pictures, but with double mode we need a catch: @@ -2322,3 +2481,5 @@ def mfun_apply_max_dimensions = % not a generic helper, we want to protect this enddef; extra_endfig := extra_endfig & "mfun_apply_max_dimensions ;" ; + +let dump = relax ; diff --git a/metapost/context/fonts/bidi-symbols.mp b/metapost/context/fonts/bidi-symbols.mp new file mode 100644 index 000000000..abe48b951 --- /dev/null +++ b/metapost/context/fonts/bidi-symbols.mp @@ -0,0 +1,73 @@ +%D \module +%D [ file=bidi-symbols.mp, +%D version=2013.09.06, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=demo font, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +passvariable("fontname","bidi-symbols") ; +passvariable("fontversion","1.009") ; + +numeric font_bidi_dp ; font_bidi_dp := -6 ; +numeric font_bidi_wd ; font_bidi_wd := -12 ; + +% beginfig(1) ; % lre +% charcode := 8234 ; charwd := 0 ; charht := 0 ; chardp := 0 ; +% drawarrow (0,0) -- (0,font_bidi_dp) -- (font_bidi_wd,font_bidi_dp) withcolor red ; +% currentpicture := currentpicture scaled charscale ; +% setbounds currentpicture to boundingbox nullpicture ; +% endfig ; +% +% beginfig(2) ; % rle +% charcode := 8235 ; charwd := 0 ; charht := 0 ; chardp := 0 ; +% drawarrow (0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd,font_bidi_dp) withcolor green ; +% currentpicture := currentpicture scaled charscale ; +% setbounds currentpicture to boundingbox nullpicture ; +% endfig ; +% +% beginfig(3) ; % pdf +% charcode := 8236 ; charwd := 0 ; charht := 0 ; chardp := 0 ; +% draw (0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd/2,font_bidi_dp) -- (font_bidi_wd/2,font_bidi_dp) withcolor blue ; +% currentpicture := currentpicture scaled charscale ; +% setbounds currentpicture to boundingbox nullpicture ; +% endfig ; +% +% beginfig(4) ; % lro +% charcode := 8237 ; charwd := 0 ; charht := 0 ; chardp := 0 ; +% drawarrow reverse ((0,0) -- (0,font_bidi_dp) -- (font_bidi_wd,font_bidi_dp)) withcolor red ; +% currentpicture := currentpicture scaled charscale ; +% setbounds currentpicture to boundingbox nullpicture ; +% endfig ; +% +% beginfig(5) ; % rlo +% charcode := 8238 ; charwd := 0 ; charht := 0 ; chardp := 0 ; +% drawarrow reverse ((0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd,font_bidi_dp)) withcolor green ; +% currentpicture := currentpicture scaled charscale ; +% setbounds currentpicture to boundingbox nullpicture ; +% endfig ; + +beginglyph(8234,0,0,0) ; % lre + drawarrow (0,0) -- (0,font_bidi_dp) -- (font_bidi_wd,font_bidi_dp) withcolor red ; +endglyph ; + +beginglyph(8235,0,0,0) ; % rle + drawarrow (0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd,font_bidi_dp) withcolor green ; +endglyph ; + +beginglyph(8236,0,0,0) ; % pdf + draw (0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd/2,font_bidi_dp) -- (font_bidi_wd/2,font_bidi_dp) withcolor blue ; +endglyph ; + +beginglyph(8237,0,0,0) ; % lro + drawarrow reverse ((0,0) -- (0,font_bidi_dp) -- (font_bidi_wd,font_bidi_dp)) withcolor red ; +endglyph ; + +beginglyph(8238,0,0,0) ; % rlo + drawarrow reverse ((0,0) -- (0,font_bidi_dp) -- (-font_bidi_wd,font_bidi_dp)) withcolor green ; +endglyph ; diff --git a/metapost/context/fonts/bidi-symbols.tex b/metapost/context/fonts/bidi-symbols.tex new file mode 100644 index 000000000..800e0e4ea --- /dev/null +++ b/metapost/context/fonts/bidi-symbols.tex @@ -0,0 +1,32 @@ +% \nopdfcompression + +% At the ConTeXt 2013 meeting Taco suggested to add ActualText entries to the +% shapes. It took us a bit of experimenting and the current implementation of +% this is quite okay, but beware: some viewers will add a space when copying +% such characters. + +\starttext + + \definemetafont[bidi-symbols][bidi-symbols.mp] + + \startbuffer + xxx{\demo\char"202A}\relax xxx\quad % lre + xxx{\demo\char"202B}\relax xxx\quad % rle + xxx{\demo\char"202C}\relax xxx\quad % pdf + xxx{\demo\char"202D}\relax xxx\quad % lro + xxx{\demo\char"202E}\relax xxx\quad % rlo + \stopbuffer + + \definefont[demo][demo@bidi-symbols] + + \getbuffer \blank + + \definefont[demo][demo@bidi-symbols at \the\dimexpr3\exheight] + + \getbuffer \blank + + \definefont[demo][demo@bidi-symbols at \the\dimexpr4\exheight] + + \getbuffer \blank + +\stoptext diff --git a/metapost/context/fonts/demo-symbols.mp b/metapost/context/fonts/demo-symbols.mp new file mode 100644 index 000000000..822854c94 --- /dev/null +++ b/metapost/context/fonts/demo-symbols.mp @@ -0,0 +1,21 @@ +%D \module +%D [ file=demo-symbols.mp, +%D version=2013.09.06, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=demo font, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +passvariable("fontname","demo-symbols") ; +passvariable("fontversion","1.005") ; + +beginglyph(9754,2,4,0) ; % high voltage + interim ahlength := 1 ; + drawarrow (1,4) -- (0,2) -- (2,3) -- (1,0) withcolor darkred ; +endglyph ; + diff --git a/metapost/context/fonts/demo-symbols.tex b/metapost/context/fonts/demo-symbols.tex new file mode 100644 index 000000000..e9af4a027 --- /dev/null +++ b/metapost/context/fonts/demo-symbols.tex @@ -0,0 +1,21 @@ +\starttext + + \definemetafont[demo-symbols][demo-symbols.mp] + + \startbuffer + watch this: {\demo\char"261A} \quad \ruledhbox{\demo\char"261A} + \stopbuffer + + \definefont[demo][demo@demo-symbols] + + \getbuffer \blank + + \definefont[demo][demo@demo-symbols at \the\dimexpr3\exheight] + + \getbuffer \blank + + \definefont[demo][demo@demo-symbols at \the\dimexpr4\exheight] + + \getbuffer \blank + +\stoptext diff --git a/metapost/context/font/punkfont-bold.mp b/metapost/context/fonts/punkfont-bold.mp index 1c62963f9..1c62963f9 100644 --- a/metapost/context/font/punkfont-bold.mp +++ b/metapost/context/fonts/punkfont-bold.mp diff --git a/metapost/context/font/punkfont-boldslanted.mp b/metapost/context/fonts/punkfont-boldslanted.mp index 3e5fa1561..3e5fa1561 100644 --- a/metapost/context/font/punkfont-boldslanted.mp +++ b/metapost/context/fonts/punkfont-boldslanted.mp diff --git a/metapost/context/font/punkfont-characters.mp b/metapost/context/fonts/punkfont-characters.mp index da0015b02..da0015b02 100644 --- a/metapost/context/font/punkfont-characters.mp +++ b/metapost/context/fonts/punkfont-characters.mp diff --git a/metapost/context/font/punkfont-definitions.mp b/metapost/context/fonts/punkfont-definitions.mp index 2901a9d03..2901a9d03 100644 --- a/metapost/context/font/punkfont-definitions.mp +++ b/metapost/context/fonts/punkfont-definitions.mp diff --git a/metapost/context/font/punkfont-slanted.mp b/metapost/context/fonts/punkfont-slanted.mp index 5c1ff46b2..5c1ff46b2 100644 --- a/metapost/context/font/punkfont-slanted.mp +++ b/metapost/context/fonts/punkfont-slanted.mp diff --git a/metapost/context/font/punkfont.mp b/metapost/context/fonts/punkfont.mp index 2a03aae81..2a03aae81 100644 --- a/metapost/context/font/punkfont.mp +++ b/metapost/context/fonts/punkfont.mp |