diff options
Diffstat (limited to 'metapost')
-rw-r--r-- | metapost/context/mp-char.mp | 100 | ||||
-rw-r--r-- | metapost/context/mp-core.mp | 701 | ||||
-rw-r--r-- | metapost/context/mp-form.mp | 19 | ||||
-rw-r--r-- | metapost/context/mp-page.mp | 78 | ||||
-rw-r--r-- | metapost/context/mp-spec.mp | 139 | ||||
-rw-r--r-- | metapost/context/mp-symb.mp | 1 | ||||
-rw-r--r-- | metapost/context/mp-tool.mp | 168 |
7 files changed, 989 insertions, 217 deletions
diff --git a/metapost/context/mp-char.mp b/metapost/context/mp-char.mp index 740d36c37..9416b1349 100644 --- a/metapost/context/mp-char.mp +++ b/metapost/context/mp-char.mp @@ -146,6 +146,8 @@ def initialize_grid (expr maxx, maxy) = save i, j ; max_x := maxx ; max_y := maxy ; + dsp_x := 0 ; + dsp_y := 0 ; for x=1 upto max_x : for y=1 upto max_y : xyfree [x][y] := true ; @@ -291,13 +293,15 @@ def collapse_points = % this is now an mp-tool macro fi ; enddef ; -vardef smooth_connection (expr a,b) = % also a mp-tool macro +vardef smooth_connection (expr a,b) = sx := connection_smooth_size/grid_width ; sy := connection_smooth_size/grid_height ; if ypart a = ypart b : a shifted (if xpart a >= xpart b : - fi sx,0) +% a shifted (sx*xpart unitvector(b-a),0) else : a shifted (0,if ypart a >= ypart b : - fi sy) +% a shifted (0,sy*ypart unitvector(b-a)) fi enddef ; @@ -347,6 +351,33 @@ vardef connection_path = xypoints[xypoint]) enddef ; +% vardef connection_path = +% sx := connection_smooth_size/grid_width ; +% sy := connection_smooth_size/grid_height ; +% if reverse_connection : reverse fi +% (for i=1 upto xypoint-1 : xypoints[i] -- endfor xypoints[xypoint]) +% if smooth : cornered max(sx,sy) fi +% enddef ; +% +% primarydef p cornered c = +% if cycle p : +% ((point 0 of p) shifted (c*(unitvector(point 1 of p - point 0 of p))) -- +% for i=1 upto length(p) : +% (point i-1 of p) shifted (c*(unitvector(point i of p - point i-1 of p))) -- +% (point i of p) shifted (c*(unitvector(point i-1 of p - point i of p))) .. +% controls point i of p .. +% endfor cycle) +% else : +% ((point 0 of p) -- +% for i=1 upto length(p)-1 : +% (point i-1 of p) shifted (c*(unitvector(point i of p - point i-1 of p))) -- +% (point i of p) shifted (c*(unitvector(point i-1 of p - point i of p))) .. +% controls point i of p .. +% endfor +% (point length(p) of p)) +% fi +% enddef ; + def draw_connection = if xypoint>0 : collapse_points ; @@ -382,11 +413,11 @@ def flush_connections = endfor ; if crossing : pickup pencircle scaled 2cline[i] ; -% draw cpaths[i] withcolor chart_background_color ; -path cp ; cp := cpaths[i] ; -cp := cp cutbefore point .05 length cp of cp ; -cp := cp cutafter point .95 length cp of cp ; -draw cp withcolor chart_background_color ; + %draw cpaths[i] withcolor chart_background_color ; + path cp ; cp := cpaths[i] ; + cp := cp cutbefore point .05 length cp of cp ; + cp := cp cutafter point .95 length cp of cp ; + draw cp withcolor chart_background_color ; fi ; fi ; pickup pencircle scaled cline[i] ; @@ -482,6 +513,10 @@ vardef right_to_grid (expr a,b) = ypart xypoints[a]) enddef ; +% vardef boundingboxfraction(expr p, f) = +% ((boundingbox p) enlarged (-f*bbwidth(p),-f*bbheight(p))) +% enddef ; + vardef valid_connection (expr xfrom, yfrom, xto, yto) = begingroup ; save ok, vc, pp ; @@ -489,9 +524,9 @@ vardef valid_connection (expr xfrom, yfrom, xto, yto) = % check for slanted lines ok := true ; for i=1 upto xypoint-1 : - if not ((xpart xypoints[i]=xpart xypoints[i+1]) or - (ypart xypoints[i]=ypart xypoints[i+1])) : ok := false ; - fi ; + if not ((xpart xypoints[i]=xpart xypoints[i+1]) or + (ypart xypoints[i]=ypart xypoints[i+1])) : ok := false ; + fi ; endfor ; if not ok : %message("slanted"); @@ -516,13 +551,13 @@ vardef valid_connection (expr xfrom, yfrom, xto, yto) = xypoints[xypoint] := xylast ; for i=1 upto max_x : - for j=1 upto max_y : -if not ( ( (i,j) = (xfrom,yfrom) ) or ( (i,j) = (yfrom,yto) ) ) : - if not xyfree[i][j] : - vc := pp intersection_point xypath[i][j] ; - if intersection_found : ok := false fi ; - fi ; -fi ; + for j=1 upto max_y : % was bug: xfrom,yto + if not ( ( (i,j)=(xfrom,yfrom) ) or ( (i,j)=(xto,yto) ) ) : + if not xyfree[i][j] : + vc := pp intersection_point xypath[i][j] ; + if intersection_found : ok := false fi ; + fi ; + fi ; endfor ; endfor ; %if not ok: message("crossing") ; fi ; @@ -544,6 +579,17 @@ def connect_top_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ; xypoints[4] := xy_on_grid(3,5) ; fi ; + %%%% begin experiment + xypoints[3] := xypoints[3] shifted (dsp_x,0) ; + xypoints[4] := xypoints[4] shifted (dsp_x,0) ; + if dsp_y>0 : + xypoints[2] := xypoints[2] shifted (0,dsp_y) ; + xypoints[3] := xypoints[3] shifted (0,dsp_y) ; + elseif dsp_y<0 : + xypoints[4] := xypoints[4] shifted (0,dsp_y) ; + xypoints[5] := xypoints[5] shifted (0,dsp_y) ; + fi + %%%% end experiment draw_connection ; fi ; enddef ; @@ -621,6 +667,17 @@ def connect_right_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = if not valid_connection(xfrom,yfrom,xto,yto) : xypoints[3] := xy_on_grid(2,4) ; fi ; + %%%% begin experiment + xypoints[2] := xypoints[2] shifted (dsp_x,0) ; + xypoints[3] := xypoints[3] shifted (dsp_x,0) ; + if dsp_y>0 : + xypoints[3] := xypoints[3] shifted (0,-dsp_y) ; + xypoints[4] := xypoints[4] shifted (0,-dsp_y) ; + elseif dsp_y<0 : + xypoints[3] := xypoints[3] shifted (0,dsp_y) ; + xypoints[4] := xypoints[4] shifted (0,dsp_y) ; + fi + %%%% end experiment draw_connection ; fi ; enddef ; @@ -689,6 +746,17 @@ def connect_bottom_bottom (expr xfrom,yyfrom,zfrom) (expr xto,yyto,zto) = xypoints[3] := x_on_grid(2,xfrom,xto,zfrom) ; xypoints[4] := xy_on_grid(3,5) ; fi ; + %%%% begin experiment + xypoints[3] := xypoints[3] shifted (dsp_x,0) ; + xypoints[4] := xypoints[4] shifted (dsp_x) ; + if dsp_y<0 : + xypoints[2] := xypoints[2] shifted (0,-dsp_y) ; + xypoints[3] := xypoints[3] shifted (0,-dsp_y) ; + elseif dsp_y>0 : + xypoints[4] := xypoints[4] shifted (0,dsp_y) ; + xypoints[5] := xypoints[5] shifted (0,dsp_y) ; + fi + %%%% end experiment draw_connection ; fi ; enddef ; diff --git a/metapost/context/mp-core.mp b/metapost/context/mp-core.mp index 918838e33..80e3a8eb5 100644 --- a/metapost/context/mp-core.mp +++ b/metapost/context/mp-core.mp @@ -1,6 +1,6 @@ %D \module %D [ file=mp-core.mp, -%D version=1999.08.12, +%D version=2000.something, % 1999.08.12, %D title=\CONTEXT\ \METAPOST\ graphics, %D subtitle=core interfacing, %D author=Hans Hagen, @@ -87,6 +87,15 @@ def do_initialize_area (expr fpos, tpos) = cxy := center pxy ; enddef ; +def set_par_line_height (expr ph, pd) = + par_strut_height := + if ph>0 : ph elseif StrutHeight>0 : StrutHeight else : 8pt fi ; + par_strut_depth := + if pd>0 : pd elseif StrutDepth >0 : StrutDepth else : 3pt fi ; + par_line_height := + par_strut_height + par_strut_depth ; +enddef ; + def initialize_par (expr fn,fx,fy,fw,fh,fd, tn,tx,ty,tw,th,td, mn,mx,my,mw,mh,md, @@ -100,9 +109,7 @@ def initialize_par (expr fn,fx,fy,fw,fh,fd, numeric par_strut_height, par_strut_depth, par_line_height ; - par_strut_height := ph ; - par_strut_depth := pd ; - par_line_height := ph + pd ; + set_par_line_height (ph, pd) ; do_initialize_area (fpos, tpos) ; do_initialize_par (fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) ; @@ -119,9 +126,7 @@ def initialize_area_par (expr fn,fx,fy,fw,fh,fd, numeric par_strut_height, par_strut_depth, par_line_height ; - par_strut_height := wh ; - par_strut_depth := wd ; - par_line_height := wh + wd ; + set_par_line_height (wh, wd) ; numeric ffpos ; ffpos := 4 ; initialize_box_pos(ffpos,wn,wx,fy,0,wh,wd) ; numeric ttpos ; ttpos := 5 ; initialize_box_pos(ttpos,wn,wx+ww,ty,0,wh,wd) ; @@ -316,9 +321,9 @@ def do_initialize_par (expr fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) = enddef ; -if unknown TopSkip : TopSkip := 0 fi ; -if unknown StrutHeight : StrutHeight := 0 fi ; - +TopSkip := 0 ; % will move +StrutHeight := 0 ; % will move + pair last_multi_par_shift ; last_multi_par_shift := origin ; def relocate_multipars (expr xy) = @@ -329,16 +334,39 @@ def relocate_multipars (expr xy) = enddef ; boolean compensate_multi_par_topskip ; -compensate_multi_par_topskip := true ; - boolean span_multi_column_pars ; -span_multi_column_pars := false ; +boolean auto_multi_par_hsize ; + +compensate_multi_par_topskip := true ; +span_multi_column_pars := false ; +auto_multi_par_hsize := false ; % true ; vardef multi_par_at_top (expr i) = (round (ypart ulcorner multipars[i]) = round (ypart ulcorner (TextAreas[multirefs[i]] shifted last_multi_par_shift))) enddef ; +numeric nofmultipars ; nofmultipars := 0 ; + +boolean obey_multi_par_hang ; obey_multi_par_hang := true ; +boolean obey_multi_par_more ; obey_multi_par_more := true ; +boolean snap_multi_par_tops ; snap_multi_par_tops := true ; +boolean local_multi_par_area ; local_multi_par_area := false ; +boolean ignore_multi_par_page ; ignore_multi_par_page := false ; + +def simplify_multi_pars = % boundingbox ipv shape als optie + for i := 1 upto nofmultipars : + multipars[i] := boundingbox multipars[i] ; + endfor ; +enddef ; + +def save_multipar (expr i, l, p) = + nofmultipars := nofmultipars + 1 ; + multirefs[nofmultipars] := i ; + multilocs[nofmultipars] := l ; + multipars[nofmultipars] := unspiked (simplified p) ; +enddef ; + def prepare_multi_pars (expr fn,fx,fy,fw,fh,fd, tn,tx,ty,tw,th,td, wn,wx,wy,ww,wh,wd, @@ -346,121 +374,568 @@ def prepare_multi_pars (expr fn,fx,fy,fw,fh,fd, rw,rl,rr,rh,ra,ri) = if span_multi_column_pars : - begingroup ; - save TextAreas ; path TextAreas[] ; - save NOfTextAreas ; numeric NOfTextAreas ; - for i=1 upto NOfTextColumns : - TextAreas[i] := TextColumns[i] ; - endfor ; - NOfTextAreas := NOfTextColumns ; - fi ; + begingroup ; + save TextAreas ; path TextAreas[] ; + save NOfTextAreas ; numeric NOfTextAreas ; + for i=1 upto NOfTextColumns : + TextAreas[i] := TextColumns[i] ; + endfor ; + NOfTextAreas := NOfTextColumns ; + fi ; last_multi_par_shift := origin ; - % rh/ra/ri not yet supported - 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) ; numeric wpos ; wpos := 3 ; initialize_box_pos(wpos,wn,wx,wy,ww,wh,wd) ; numeric ppos ; ppos := 4 ; initialize_box_pos(ppos,pn,px,py,pw,ph,pd) ; +if local_multi_par_area : + RealPageNumber := fn ; + NOfTextAreas := 1 ; + NOfSavedTextAreas := 0 ; + TextAreas[1] := TextAreas[0] ; + TextColumns[1] := TextColumns[0] ; + nxy[fpos] := nxy[tpos] := nxy[wpos] := nxy[ppos] := RealPageNumber ; +elseif ignore_multi_par_page : + RealPageNumber := fn ; + nxy[fpos] := nxy[tpos] := nxy[wpos] := nxy[ppos] := RealPageNumber ; +fi ; + numeric par_strut_height, par_strut_depth, par_line_height ; - par_strut_height := ph ; - par_strut_depth := pd ; - par_line_height := ph + pd ; + set_par_line_height (ph, pd) ; + + numeric par_hang_indent, par_hang_after, par_indent, par_left_skip ; + + par_hang_indent := rh ; + par_hang_after := ra ; + par_indent := ri ; + par_left_skip := rl ; + + pair par_start_pos ; + +% par_start_pos := llxy[fpos] if par_indent<0: shifted (-par_indent,0) fi ; + + par_start_pos := llxy[fpos] + if par_indent <0: shifted (-par_indent, 0) fi + if par_left_skip<0: shifted (-par_left_skip,0) fi ; if wxy[wpos]>0 : left_skip := rl + xpart llxy[wpos] - xpart llxy[ppos] ; - right_skip := rw - left_skip - ww ; - else : - left_skip := rl ; - right_skip := rr ; + right_skip := rw - left_skip - ww ; + else : + left_skip := rl ; + right_skip := rr ; fi ; - path multipar, multipars[] ; - numeric multiref, multirefs[] ; + path multipar, multipars[] ; + numeric multiref, multirefs[] ; numeric multiloc, multilocs[] ; % 1=begin 2=between 3=end - ii := 0 ; nn := NOfTextAreas+1 ; nofmultipars := 0 ; + numeric multi_par_pages ; multi_par_pages := nxy[tpos]-nxy[fpos]+1 ; - def set_multipar (expr i) = - ((TextAreas[i] leftenlarged -left_skip) rightenlarged -right_skip) - enddef ; + ii := 0 ; nn := NOfTextAreas+1 ; nofmultipars := 0 ; - def save_multipar (expr i, l, p) = - nofmultipars := nofmultipars + 1 ; - multirefs[nofmultipars] := i ; - multilocs[nofmultipars] := l ; - multipars[nofmultipars] := unspiked simplified p ; + vardef snapped_multi_pos (expr p) = + if snap_multi_par_tops : + if abs(ypart p - ypart ulcorner multipar) < par_line_height : + (xpart p,ypart ulcorner multipar) + else : + p + fi + else : + p + fi enddef ; + % def set_multipar (expr i) = + % ((TextAreas[i] leftenlarged -left_skip) rightenlarged -right_skip) + % enddef ; + + vardef set_multipar (expr i) = + ( (TextAreas[i] leftenlarged -left_skip) rightenlarged (-right_skip + if auto_multi_par_hsize : + rw - bbwidth(TextAreas[i]) fi) ) + enddef ; + + vardef top_multi_par(expr p) = + (round(estimated_par_lines(bbheight(p)*par_line_height))=round(bbheight(p))) + enddef ; + + vardef multi_par_tsc(expr p) = + if top_multi_par(p) : TopSkipCorrection else : 0 fi + enddef ; + + vardef estimated_par_lines (expr h) = + round(h/par_line_height) + enddef ; + + vardef estimated_multi_par_height (expr n, t) = + if round(par_line_height)=0 : + 0 + else : + save ok, h ; boolean ok ; + numeric h ; h := 0 ; + ok := false ; + if (nxy[fpos]=RealPageNumber-1) : + for i := 1 upto NOfSavedTextAreas : + if (InsideSavedTextArea(i,par_start_pos)) : + ok := true ; + h := h + estimated_par_lines(ypart ulxy[fpos] - + ypart llcorner SavedTextAreas[i]) ; + elseif ok : + h := h + estimated_par_lines(bbheight(SavedTextAreas[i])) ; + fi ; + endfor ; + fi ; + if ok : + for i := 1 upto n-1 : + h := h + estimated_par_lines(bbheight(TextAreas[i])) ; + endfor ; + else : + % already: ok := false ; + for i := 1 upto n-1 : + if (InsideTextArea(i,par_start_pos)) : + ok := true ; + h := h + estimated_par_lines(ypart ulxy[fpos] - ypart llcorner TextAreas[i]) ; + elseif ok : + h := h + estimated_par_lines(bbheight(TextAreas[i])) ; + fi ; + endfor ; + fi ; + h + fi + enddef ; + + vardef left_top_hang (expr same_area) = + +par_hang_after := ra + estimated_par_lines(py-fy) ; + + if (par_hang_indent>0) and (par_hang_after<0) and obey_multi_par_hang : + pair _ul_ ; _ul_ := (xpart ulcorner multipar, ypart snapped_multi_pos(ulxy[fpos])); + pair _pa_ ; _pa_ := _ul_ shifted (0,par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llxy[tpos])) ; + fi ; +% vervalt: + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := min(0,round(par_hang_after + + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + (xpart _ul_ + par_hang_indent, ypart lrxy[fpos]) -- + (xpart _ul_ + par_hang_indent, ypart _pa_) -- + (xpart ulcorner multipar, ypart _pa_) + else : + (xpart ulcorner multipar, ypart lrxy[fpos]) + fi + enddef ; + + vardef right_top_hang (expr same_area) = + +par_hang_after := ra - estimated_par_lines(py-fy) ; + + if (par_hang_indent<0) and (par_hang_after<0) and obey_multi_par_hang : + pair _ur_ ; _ur_ := (xpart urcorner multipar, ypart snapped_multi_pos(urxy[fpos])) ; + pair _pa_ ; _pa_ := _ur_ shifted (0,par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart llcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_ -TopSkipCorrection,ypart snapped_multi_pos(ulxy[tpos]))) ; + fi ; + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := min(0,round(par_hang_after + + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + (xpart urcorner multipar, ypart _pa_) -- + (xpart _ur_ + par_hang_indent, ypart _pa_) -- + (xpart _ur_ + par_hang_indent, ypart snapped_multi_pos(urxy[fpos])) + else : + (xpart urcorner multipar, ypart snapped_multi_pos(urxy[fpos])) + fi + enddef ; + + vardef x_left_top_hang (expr i, t) = + par_hang_after := min(0,ra + estimated_multi_par_height(i,t)) ; + if (par_hang_indent>0) and (par_hang_after<0) : + pair _ul_ ; _ul_ := ulcorner multipar ; + pair _pa_ ; _pa_ := _ul_ shifted (0,par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; + +if t : + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llxy[tpos])); +fi ; +if abs(ypart _pa_-ypart llxy[tpos])<par_line_height : + _pa_ := (xpart _pa_,ypart llxy[tpos]); +fi ; +if abs(ypart _pa_-ypart llcorner multipar)<par_line_height : + _pa_ := (xpart _pa_,ypart llcorner multipar); +fi ; + + (xpart _ul_, ypart _pa_) -- + (xpart _ul_ + par_hang_indent, ypart _pa_) -- + (xpart _ul_ + par_hang_indent, ypart _ul_) + else : + ulcorner multipar + fi + enddef ; + +% here + + vardef x_right_top_hang (expr i, t) = + par_hang_after := min(0,ra + estimated_multi_par_height(i,t)) ; + if (par_hang_indent<0) and (par_hang_after<0) : + pair _ur_ ; _ur_ := urcorner multipar ; + pair _pa_ ; _pa_ := _ur_ shifted (0,par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ; +if t : + _pa_ := (xpart _pa_,max(ypart _pa_,ypart snapped_multi_pos(urxy[tpos]))) ; +fi ; + +%todo +% +%if abs(ypart _pa_-ypart llxy[tpos])<par_line_height : +% _pa_ := (xpart _pa_,ypart llxy[tpos]); +%fi ; +%if abs(ypart _pa_-ypart llcorner multipar)<par_line_height : +% _pa_ := (xpart _pa_,ypart llcorner multipar); +%fi ; + + + (xpart _ur_ + par_hang_indent, ypart _ur_) -- + (xpart _ur_ + par_hang_indent, ypart _pa_) -- + (xpart _ur_, ypart _pa_) + else : + urcorner multipar + fi + enddef ; + + vardef left_bottom_hang (expr same_area) = + pair _ll_, _sa_, _pa_ ; + _sa_ := if same_area : llxy[tpos] else : lrcorner multipar fi ; + if (par_hang_indent>0) and (par_hang_after>0) and obey_multi_par_hang : + _ll_ := (xpart ulcorner multipar, ypart snapped_multi_pos(ulxy[fpos])) ; + _pa_ := _ll_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; + fi ; + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := max(0,round(par_hang_after - + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + _pa_ -- + (xpart _pa_ + par_hang_indent,ypart _pa_) -- + (xpart _pa_ + par_hang_indent,ypart _sa_) + else : + (xpart llcorner multipar, ypart _sa_) + fi + enddef ; + + vardef right_bottom_hang (expr same_area) = + pair _lr_, _sa_, _pa_ ; + _sa_ := if same_area : snapped_multi_pos(ulxy[tpos]) else : lrcorner multipar fi ; + if (par_hang_indent<0) and (par_hang_after>0) and obey_multi_par_hang : + _lr_ := (xpart urcorner multipar, ypart snapped_multi_pos(urxy[fpos])) ; + _pa_ := _lr_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ; + if same_area : + _pa_ := (xpart _pa_,max(ypart _pa_,ypart snapped_multi_pos(ulxy[tpos]))) ; + fi ; + if obey_multi_par_more and (round(par_line_height)>0) : + par_hang_after := max(0,round(par_hang_after - + (ypart urxy[fpos]-ypart _pa_)/par_line_height)) ; + fi ; + (xpart _pa_ + par_hang_indent,ypart _sa_) -- + (xpart _pa_ + par_hang_indent,ypart _pa_) -- + _pa_ + else : + (xpart lrcorner multipar, ypart _sa_) + fi + enddef ; + + vardef x_left_bottom_hang (expr i, t) = + pair _ll_, _sa_, _pa_ ; +if t : + _sa_ := llxy[tpos] ; +else : + _sa_ := llcorner multipar ; +fi ; + if (par_hang_indent>0) and (ra>0) : + par_hang_after := max(0,ra - estimated_multi_par_height(i,t)) ; + _ll_ := ulcorner multipar ; + _pa_ := _ll_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart llcorner multipar)) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; + % we need to compensate for topskip enlarged areas + if abs(ypart _pa_ - ypart _sa_) > par_line_height : + (xpart _pa_ + par_hang_indent,ypart _sa_) -- + (xpart _pa_ + par_hang_indent,ypart _pa_) -- + fi + _pa_ + else : + (xpart llcorner multipar, ypart _sa_) + fi + enddef ; + + vardef x_right_bottom_hang (expr i, t) = + pair _lr_, _sa_, _pa_ ; +if t : + _sa_ := snapped_multi_pos(ulxy[tpos]) ; +else : + _sa_ := llcorner multipar ; +fi ; + if (par_hang_indent<0) and (ra>0) : + par_hang_after := max(0,ra - estimated_multi_par_height(i, t)) ; + _lr_ := urcorner multipar ; + _pa_ := _lr_ shifted (0,-par_hang_after*par_line_height) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart lrcorner multipar)) ; + _pa_ := (xpart _pa_,max(ypart _pa_,ypart _sa_)) ; + % we need to compensate for topskip enlarged areas + _pa_ + if abs(ypart _pa_ - ypart _sa_) > par_line_height : + -- (xpart _pa_ + par_hang_indent,ypart _pa_) + -- (xpart _pa_ + par_hang_indent,ypart _sa_) + fi + else : + (xpart lrcorner multipar, ypart _sa_) + fi + enddef ; + + def test_multipar = + multipar := + llcorner multipar -- + urcorner multipar -- + lrcorner multipar -- + ulcorner multipar -- + cycle ; + enddef ; + + % first loop + for i=1 upto NOfTextAreas : + + TopSkipCorrection := 0 ; + multipar := set_multipar(i) ; - if (nxy[fpos]=RealPageNumber) and (InsideTextArea(i,llxy[fpos])) : - % first one in chain + + % watch how we compensate for negative indentation + + if (nxy[fpos]=RealPageNumber) and (InsideTextArea(i,par_start_pos)) : + + % first one in chain + ii := i ; + if (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,llxy[tpos])) : + + % in same area + nn := i ; - if compensate_multi_par_topskip : - TopSkipCorrection := TopSkip - StrutHeight ; + if compensate_multi_par_topskip and (round(LineHeight-ph-pd)=0) : - if round(ypart ulxy[fpos] + TopSkipCorrection) = - round(ypart ulcorner TextAreas[i]) : - ulxy[fpos] := ulxy[fpos] shifted (0,TopSkipCorrection) ; - urxy[fpos] := urxy[fpos] shifted (0,TopSkipCorrection) ; - fi ; - fi ; + TopSkipCorrection := TopSkip - StrutHeight ; + + if round(ypart ulxy[fpos] + TopSkipCorrection) = + round(ypart ulcorner TextAreas[i]) : + ulxy[fpos] := ulxy[fpos] shifted (0,TopSkipCorrection) ; + urxy[fpos] := urxy[fpos] shifted (0,TopSkipCorrection) ; + else : + TopSkipCorrection := 0 ; + fi ; + + fi ; if ypart llxy[fpos] = ypart llxy[tpos] : - multipar := llxy[fpos] -- - lrxy[tpos] -- - urxy[tpos] -- - ulxy[fpos] -- - cycle ; + + multipar := + llxy[fpos] -- + lrxy[tpos] -- + %urxy[tpos] -- + snapped_multi_pos(urxy[tpos]) -- + %ulxy[fpos] -- + snapped_multi_pos(ulxy[fpos]) -- + cycle ; + + save_multipar (i,1,multipar) ; + + elseif (ypart llxy[fpos] = ypart ulxy[tpos]) and + (xpart llxy[tpos] < xpart llxy[fpos]) : + + % two loners + + multipar := if obey_multi_par_hang : + + right_bottom_hang(true) -- + right_top_hang(true) -- + snapped_multi_pos(urxy[fpos]) -- + lrxy[fpos] -- + + else : + + llxy[fpos] -- + (xpart urcorner multipar, ypart llxy[fpos]) -- + (xpart urcorner multipar, ypart ulxy[fpos]) -- + snapped_multi_pos(ulxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + multipar := set_multipar(i) ; + + multipar := if obey_multi_par_hang : + + left_bottom_hang(true) -- + llxy[tpos] -- + snapped_multi_pos(ulxy[tpos]) -- + left_top_hang(true) -- + + else : + + (xpart llcorner multipar, ypart llxy[tpos]) -- + llxy[tpos] -- + snapped_multi_pos(ulxy[tpos]) -- + (xpart llcorner multipar, ypart ulxy[tpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + else : - multipar := (xpart llcorner multipar, ypart llxy[tpos]) -- - llxy[tpos] -- - ulxy[tpos] -- - (xpart lrcorner multipar, ypart ulxy[tpos]) -- - (xpart urcorner multipar, ypart urxy[fpos]) -- - urxy[fpos] -- - lrxy[fpos] -- - (xpart ulcorner multipar, ypart lrxy[fpos])-- - cycle ; + + multipar := if obey_multi_par_hang : + + left_bottom_hang(true) -- + llxy[tpos] -- + %ulxy[tpos] -- + snapped_multi_pos(ulxy[tpos]) -- + right_bottom_hang(true) -- + right_top_hang(true) -- + %urxy[fpos] -- + snapped_multi_pos(urxy[fpos]) -- + lrxy[fpos] -- + left_top_hang(true) -- + + else : + + (xpart llcorner multipar, ypart llxy[tpos]) -- + llxy[tpos] -- + %ulxy[tpos] -- + snapped_multi_pos(ulxy[tpos]) -- + (xpart lrcorner multipar, ypart ulxy[tpos]) -- + (xpart urcorner multipar, ypart urxy[fpos]) -- + %urxy[fpos] -- + snapped_multi_pos(urxy[fpos]) -- + lrxy[fpos] -- + (xpart ulcorner multipar, ypart lrxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + fi ; + else : - multipar := llcorner multipar -- - lrcorner multipar -- - (xpart lrcorner multipar, ypart urxy[fpos]) -- - urxy[fpos] -- - lrxy[fpos] -- - (xpart ulcorner multipar, ypart lrxy[fpos])-- cycle ; + + multipar := if obey_multi_par_hang : + + left_bottom_hang(false) -- + right_bottom_hang(false) -- + right_top_hang(false) -- + %urxy[fpos] -- + snapped_multi_pos(urxy[fpos]) -- + lrxy[fpos] -- + left_top_hang(false) -- + + else : + + llcorner multipar -- + lrcorner multipar -- + (xpart urcorner multipar, ypart urxy[fpos]) -- + %urxy[fpos] -- + snapped_multi_pos(urxy[fpos]) -- + lrxy[fpos] -- + (xpart ulcorner multipar, ypart lrxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + fi ; - save_multipar (i,1,multipar) ; + elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,llxy[tpos])) : - % last one in chain + + % last one in chain + nn := i ; - multipar := ulcorner multipar -- - urcorner multipar -- - (xpart lrcorner multipar, ypart urxy[tpos]) -- - ulxy[tpos] -- - llxy[tpos] -- - (xpart llcorner multipar, ypart llxy[tpos]) -- - cycle ; - save_multipar (i,3,multipar) ; + + if obey_multi_par_hang and obey_multi_par_more : + + multipar := + x_left_top_hang(i,true) -- + x_right_top_hang(i,true) -- + x_right_bottom_hang(i,true) -- +% ulxy[tpos] -- +snapped_multi_pos(ulxy[tpos]) -- + llxy[tpos] -- + x_left_bottom_hang(i,true) -- + cycle ; + + else : + + multipar := + ulcorner multipar -- + urcorner multipar -- + (xpart lrcorner multipar, ypart urxy[tpos]) -- +% ulxy[tpos] -- +snapped_multi_pos(ulxy[tpos]) -- + llxy[tpos] -- + (xpart llcorner multipar, ypart llxy[tpos]) -- + cycle ; + + fi ; + + save_multipar (i,3,multipar) ; + + else : + + % handled later + fi ; + endfor ; + % second loop + for i=ii+1 upto nn-1 : - % rest of chain - save_multipar(i,2,set_multipar(i)) ; + + % rest of chain / todo : hang + +%if (nxy[fpos]<=RealPageNumber) and (nxy[tpos]>=RealPageNumber) : + + multipar := set_multipar(i) ; + + if obey_multi_par_hang and obey_multi_par_more : + + multipar := + x_left_top_hang(i,false) -- + x_right_top_hang(i,false) -- + x_right_bottom_hang(i,false) -- + x_left_bottom_hang(i,false) -- + cycle ; + + fi ; + + save_multipar(i,2,multipar) ; + +%fi ; + endfor ; if span_multi_column_pars : - endgroup ; - fi ; + endgroup ; + fi ; enddef ; @@ -475,22 +950,26 @@ numeric boxgridwidth ; boxgridwidth := 1pt ; numeric boxlinewidth ; boxlinewidth := 1pt ; numeric boxlineradius ; boxlineradius := 0pt ; numeric boxfilloffset ; boxfilloffset := 0pt ; +numeric boxgriddistance ; boxgriddistance := .5cm ; def draw_box = draw pxy withcolor boxlinecolor withpen pencircle scaled boxlinewidth ; draw lxy -- rxy withcolor boxlinecolor withpen pencircle scaled boxgridwidth ; enddef ; -def draw_par = % 1 2 11 - numeric distance ; distance := .5cm ; +def draw_par = % 1 2 11 12 do_draw_par(pxy) ; do_draw_par(txy) ; do_draw_par(bxy) ; for i = pxy, txy, bxy : if boxgridtype= 1 : + boxgriddirection := origin ; draw baseline_grid (i,boxgriddirection,true ) withcolor boxgridcolor ; elseif boxgridtype= 2 : + boxgriddirection := origin ; draw baseline_grid (i,boxgriddirection,false) withcolor boxgridcolor ; elseif boxgridtype=11 : - draw graphic_grid(i,distance,distance,distance/2,distance/2) ; + draw graphic_grid(i,boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; + elseif boxgridtype=12 : + draw graphic_grid(i,boxgriddistance,boxgriddistance,0,0) ; fi ; endfor ; enddef ; @@ -500,6 +979,7 @@ def do_show_par (expr p, r, c) = draw fullcircle scaled r shifted point i of p withpen pencircle scaled .5pt withcolor c ; endfor ; fi ; + draw p withpen pencircle scaled .5pt withcolor c ; enddef ; def show_par = @@ -517,11 +997,13 @@ def draw_multi_pars = for i=1 upto nofmultipars : do_draw_par(multipars[i]) ; if boxgridtype= 1 : - draw baseline_grid (multipars[i],boxgriddirection,true ) withcolor boxgridcolor ; + draw baseline_grid (multipars[i],up,true ) withcolor boxgridcolor ; elseif boxgridtype= 2 : - draw baseline_grid (multipars[i],boxgriddirection,false) withcolor boxgridcolor ; + draw baseline_grid (multipars[i],up,false) withcolor boxgridcolor ; elseif boxgridtype=11 : - draw graphic_grid(multipars[i],distance,distance,distance/2,distance/2) ; + draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; + elseif boxgridtype=12 : + draw graphic_grid(multipars[i],boxgriddistance,boxgriddistance,0,0) ; fi ; endfor ; enddef ; @@ -558,27 +1040,28 @@ enddef ; vardef baseline_grid (expr pxy, pdir, at_baseline) = if (par_line_height>0) and (bbheight(pxy)>1) and (bbwidth(pxy)>1) and (boxgridwidth>0) : - save grid, start ; picture grid ; pair start ; + save i, grid ; picture grid ; pair start ; + def _do_ (expr start) = + draw start -- start shifted (bbwidth(pxy),0) + withpen pencircle scaled boxgridwidth + withcolor boxgridcolor ; + enddef ; 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 : + if pdir=up : + for i = if at_baseline : par_strut_depth else : 0 fi + step par_line_height + until max(bbheight(pxy),par_line_height) : + _do_ (llcorner pxy shifted (0,+i)) ; + 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 ; + step par_line_height + until bbheight(pxy) : + _do_ (ulcorner pxy shifted (0,-i)) ; endfor ; - %fi ; + fi ; ) ; clip grid to pxy ; grid @@ -598,8 +1081,8 @@ vardef graphic_grid (expr pxy, dx, dy, x, y) = 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 ; + endfor ) shifted (x,y) ; + clip grid to pxy ; grid else : nullpicture diff --git a/metapost/context/mp-form.mp b/metapost/context/mp-form.mp index 15802dfbc..b5c06b11a 100644 --- a/metapost/context/mp-form.mp +++ b/metapost/context/mp-form.mp @@ -13,6 +13,8 @@ % instead of a picture, one can format a number in a for TeX % acceptable input string +boolean mant_font ; mant_font := true ; % signals graph not to load form + if known fmt_loaded : expandafter endinput fi ; boolean fmt_loaded ; fmt_loaded := true ; @@ -115,7 +117,11 @@ vardef init_numbers(expr s, m, x, sn, e) = Feraise_ := ypart llcorner p ; exitif true ; endfor - Fe_base := Fline_up_("1" infont Fmfont_ scaled Fmscale_, Femarker_) ; + if fmt_metapost : + Fe_base := Fline_up_("1" infont Fmfont_ scaled Fmscale_, Femarker_) ; + % else : + % sFe_base := Fline_up_("1", sFemarker_) ; + fi ; Fe_plus := nullpicture ; enddef ; @@ -323,14 +329,23 @@ fmt_[ASCII "G"] = "Formgen_(z Fdigs_ p)" ; % of the format letters defined above. The number should be % an integer giving the precision (default 3). +vardef isfmtseparator primary c = %%% added by HH %%% + ((c <> fmt_separator) and (c <> "%")) +enddef ; + vardef dofmt_@#(expr f, x) = %%% adapted by HH %%% + initialize_numbers ; if f = "" : if fmt_metapost : nullpicture else : "" fi else : interim warningcheck := 0 ; save k, l, s, p, z ; pair z ; z = @#(x) ; - k = 1 + cspan(f, fmt_separator <> ) ; + % the next adaption is okay + % k = 1 + cspan(f, fmt_separator <> ) ; + % but best is to support both % and fmt_separator + k = 1 + cspan(f, isfmtseparator) ; + % l-k = cspan(substring(k,infinity) of f, isdigit) ; p = if l > k : scantokens substring(k,l) of f diff --git a/metapost/context/mp-page.mp b/metapost/context/mp-page.mp index 035b65bd6..032844ce3 100644 --- a/metapost/context/mp-page.mp +++ b/metapost/context/mp-page.mp @@ -47,12 +47,14 @@ def SaveTextAreas = enddef ; def ResetTextAreas = - path TextAreas[], TextColumns[]; + path TextAreas[], TextColumns[] ; numeric NOfTextAreas ; NOfTextAreas := 0 ; numeric NOfTextColumns ; NOfTextColumns := 0 ; + numeric nofmultipars ; nofmultipars := 0 ; + TextAreas[0] := TextColumns[0] := origin -- cycle ; enddef ; -ResetTextAreas ; SaveTextAreas ; +ResetTextAreas ; SaveTextAreas ; ; def RegisterTextArea (expr x, y, w, h, d) = begingroup ; save p ; path p ; @@ -91,6 +93,18 @@ def RegisterTextArea (expr x, y, w, h, d) = endgroup ; enddef ; +%D We store a local area in slot zero. + +def RegisterLocalTextArea (expr x, y, w, h, d) = + TextAreas[0] := TextColumns[0] := unitsquare xyscaled(w,h+d) shifted (x,y-d) ; +enddef ; + +def ResetLocalTextArea = + TextAreas[0] := TextColumns[0] := origin -- cycle ; +enddef ; + +ResetLocalTextArea ; + vardef InsideTextArea (expr _i_, _xy_) = ( (round(xpart _xy_) >= round(xpart llcorner TextAreas[_i_])) and (round(xpart _xy_) <= round(xpart lrcorner TextAreas[_i_])) and @@ -181,7 +195,7 @@ PaperWidth := 597.50787pt ; PrintPaperHeight := 845.04684pt ; PrintPaperWidth := 597.50787pt ; TopSpace := 71.12546pt ; -BottomSpace := 0.0pt ; +BottomSpace := 0.0pt ; BackSpace := 71.13275pt ; CutSpace := 0.0pt ; MakeupHeight := 711.3191pt ; @@ -218,12 +232,22 @@ RightMargin := +2 ; Footer := +20 ; RightEdgeSeparator := +3 ; BottomSeparator := +30 ; RightEdge := +4 ; Bottom := +40 ; -Margin := LeftMargin ; -Edge := LeftEdge ; -InnerMargin := RightMargin ; -InnerEdge := RightEdge ; -OuterMargin := LeftMargin ; -OuterEdge := LeftEdge ; +Margin := LeftMargin ; % obsolete +Edge := LeftEdge ; % obsolete +InnerMargin := RightMargin ; % obsolete +InnerEdge := RightEdge ; % obsolete +OuterMargin := LeftMargin ; % obsolete +OuterEdge := LeftEdge ; % obsolete + +InnerMarginWidth := 0pt ; +OuterMarginWidth := 0pt ; +InnerMarginDistance := 0pt ; +OuterMarginDistance := 0pt ; + +InnerEdgeWidth := 0pt ; +OuterEdgeWidth := 0pt ; +InnerEdgeDistance := 0pt ; +OuterEdgeDistance := 0pt ; path Area [][] ; pair Location [][] ; path Field [][] ; path Page ; numeric HorPos ; numeric Hstep [] ; numeric Hsize [] ; @@ -261,6 +285,8 @@ def SwapPageState = LeftEdgeDistance := RightEdgeDistance ; RightEdgeDistance := i ; +% these are now available as ..Width and ..Distance + Margin := LeftMargin ; Edge := LeftEdge ; InnerMargin := RightMargin ; @@ -269,7 +295,7 @@ def SwapPageState = OuterEdge := LeftEdge ; else : Margin := RightMargin ; - Edge := RightEdge ; + Edge := RightEdge ; InnerMargin := LeftMargin ; InnerEdge := LeftEdge ; OuterMargin := RightMargin ; @@ -277,13 +303,8 @@ def SwapPageState = fi ; enddef ; -def StartPage = +def SetPageAreas = - if PageStateAvailable : - LoadPageState ; - SwapPageState ; - fi ; - numeric Vsize[], Hsize[], Vstep[], Hstep[] ; Vsize[Top] = TopHeight ; @@ -337,21 +358,36 @@ def StartPage = endfor ; endfor ; -% pickup pencircle scaled 0pt ; - Page := unitsquare xscaled PaperWidth yscaled PaperHeight ; - bboxmargin := 0 ; setbounds currentpicture to Page ; enddef ; -def StopPage = +def BoundPageAreas = - %pickup pencircle scaled 0pt ; + % pickup pencircle scaled 0pt ; bboxmargin := 0 ; setbounds currentpicture to Page ; enddef ; +def StartPage = + + if PageStateAvailable : + LoadPageState ; + SwapPageState ; + fi ; + + SetPageAreas ; + BoundPageAreas ; + +enddef ; + +def StopPage = + + BoundPageAreas ; + +enddef ; + def OverlayBox = (unitsquare xyscaled (OverlayWidth,OverlayHeight)) enddef ; diff --git a/metapost/context/mp-spec.mp b/metapost/context/mp-spec.mp index 05f5cecad..dca7ffdbc 100644 --- a/metapost/context/mp-spec.mp +++ b/metapost/context/mp-spec.mp @@ -11,9 +11,13 @@ %C therefore copyrighted by \PRAGMA. See licen-en.pdf for %C details. +% Spot colors are not handled by mptopdf ! + % (r,g,b) => cmyk : r=123 g= 1 b=hash -% => transparent rgb : r=123 g= 2 b=hash -% => transparent cmyk : r=123 g= 3 b=hash +% => spot : r=123 g= 2 b=hash +% => transparent rgb : r=123 g= 3 b=hash +% => transparent cmyk : r=123 g= 4 b=hash +% => transparent spot : r=123 g= 5 b=hash % => rest : r=123 g=n>10 b=whatever %D This module is rather preliminary and subjected to @@ -162,15 +166,15 @@ pair shadeoffset ; shadeoffset := origin ; vardef define_linear_shade (expr a, b, ca, cb) = flush_special(30, 15, "0 1 " & decimal shadefactor & " " & - dddecimal ca & ddecimal (a shifted shadeoffset) & - dddecimal cb & ddecimal (b shifted shadeoffset) ) ; + dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & + dddecimal cb & " " & ddecimal (b shifted shadeoffset) ) ; _special_counter_ enddef ; vardef define_circular_shade (expr a, b, ra, rb, ca, cb) = flush_special(31, 17, "0 1 " & decimal shadefactor & " " & - dddecimal ca & ddecimal (a shifted shadeoffset) & " " & decimal ra & - dddecimal cb & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + dddecimal cb & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; _special_counter_ enddef ; @@ -356,24 +360,6 @@ enddef ; resetcmykcolors ; boolean cmykcolors ; cmykcolors := false ; % true -% vardef cmyk(expr c,m,y,k) = -% if cmykcolors : -% if not known cmykcolorhash[c][m][y][k] : -% _cmyk_counter_ := _cmyk_counter_ + 1 ; -% cmykcolorhash[c][m][y][k] := _cmyk_counter_ ; -% flush_special(1, 7, -% decimal _cmyk_counter_ & " " & -% decimal c & " " & -% decimal m & " " & -% decimal y & " " & -% decimal k) ; -% fi -% (_special_signal_/1000,1/1000,cmykcolorhash[c][m][y][k]/1000) -% else : -% (1-c-k,1-m-k,1-y-k) -% fi -% enddef ; - string cmykcolorpattern[] ; % needed for transparancies vardef cmyk(expr c,m,y,k) = @@ -384,7 +370,7 @@ vardef cmyk(expr c,m,y,k) = elseif cmykcolorhash[c][m][y][k] = -1 : ok := false ; % locally defined and undefined else : - ok := true ; % globally already defined + ok := true ; % globally already defined fi ; if not ok : save s ; string s ; s := dddecimal (c,m,y) & " " & decimal k ; @@ -394,7 +380,7 @@ vardef cmyk(expr c,m,y,k) = flush_special(1, 7, decimal _cmyk_counter_ & " " & s) ; _local_specials_ := _local_specials_ & " cmykcolorhash[" & decimal c & "][" & decimal m & - "][" & decimal y & "][" & decimal k & "] := -1 ; " ; + "][" & decimal y & "][" & decimal k & "] := -1 ; " ; fi ; (_special_signal_/1000,1/1000,cmykcolorhash[c][m][y][k]/1000) else : @@ -408,6 +394,52 @@ enddef ; % truemagenta = cmyk (0,1,0,0) ; % trueyellow = cmyk (0,0,1,0) ; +%D Spot colors + +_spotcolor_counter_ := 0 ; +_spotcolor_number_ := 0 ; + +extra_endfig := " resetspotcolors ; " & extra_endfig ; + +def resetspotcolors = + numeric spotcolorhash[][] ; +enddef ; + +resetspotcolors ; boolean spotcolors ; spotcolors := false ; % true + +string spotcolorpattern[] ; % needed for transparancies + +vardef spotcolor(expr p, s) = + if spotcolors : + save ok, pc_tag ; boolean ok ; string pc_tag ; + pc_tag := "_pct_"&p ; + if not unstringed(pc_tag) : + _spotcolor_number_ := _spotcolor_number_ + 1 ; + setunstringed(pc_tag,_spotcolor_number_) ; + fi ; + pp := getunstringed(pc_tag) ; + if unknown spotcolorhash[pp][s] : + ok := false ; % not yet defined + elseif spotcolorhash[pp][s] = -1 : + ok := false ; % locally defined and undefined + else : + ok := true ; % globally already defined + fi ; + if not ok : + save ss ; string ss ; ss := p & " " & decimal s ; + _spotcolor_counter_ := _spotcolor_counter_ + 1 ; + spotcolorpattern[_spotcolor_counter_/1000] := ss ; + spotcolorhash[pp][s] := _spotcolor_counter_ ; + flush_special(2, 5, decimal _spotcolor_counter_ & " " & ss) ; + _local_specials_ := _local_specials_ & + "spotcolorhash["&decimal pp&"]["&decimal s&"]:=-1;" ; + fi ; + (_special_signal_/1000,2/1000,spotcolorhash[pp][s]/1000) + else : + (1-s,1-s,1-s) + fi +enddef ; + %D Transparency normaltransparent := 1 ; multiplytransparent := 2 ; @@ -423,8 +455,8 @@ differencetransparent := 11 ; exclusiontransparent := 12 ; % fill fullcircle scaled 10cm withcolor transparant(.8,3,color) ; vardef transparent(expr n, t, c) = - save s, ss, nn, cc, is_cmyk, ok ; - string s, ss ; numeric nn ; color cc ; boolean is_cmyk, ok ; + save s, ss, nn, cc, is_cmyk, is_spot, ok ; + string s, ss ; numeric nn ; color cc ; boolean is_cmyk, is_spot, ok ; % transparancy type if string n : if expandafter known scantokens(n&"transparent") : @@ -440,9 +472,13 @@ vardef transparent(expr n, t, c) = % check for cmyk special is_cmyk := (redpart cc = _special_signal_/1000) and (greenpart cc = 1/1000) ; + is_spot := (redpart cc = _special_signal_/1000) + and (greenpart cc = 2/1000) ; % build special string, fetch cmyk components - s := decimal nn & " " & decimal t & " " & if is_cmyk : - cmykcolorpattern[bluepart cc] else : dddecimal cc fi ; + s := decimal nn & " " & decimal t & " " & + if is_cmyk : cmykcolorpattern[bluepart cc] + elseif is_spot : spotcolorpattern[bluepart cc] + else : dddecimal cc fi ; % check if this one is already used ss := "tr_" & s ; % efficiency hack @@ -454,20 +490,24 @@ vardef transparent(expr n, t, c) = ok := true ; % globally already defined fi ; if not ok : - if is_cmyk : - flush_special(3, 8, s) ; - else : - flush_special(2, 7, s) ; + if is_spot : + flush_special(5, 6, s) ; + elseif is_cmyk : + flush_special(4, 8, s) ; + else : + flush_special(3, 7, s) ; fi ; scantokens(ss) := _special_counter_ ; _local_specials_ := _local_specials_ & "scantokens(" & ditto & ss & ditto & ") := -1 ;" ; fi ; % go ahead - if is_cmyk : - (_special_signal_/1000,3/1000,scantokens(ss)/1000) + if is_spot : + (_special_signal_/1000,5/1000,scantokens(ss)/1000) + elseif is_cmyk : + (_special_signal_/1000,4/1000,scantokens(ss)/1000) else : - (_special_signal_/1000,2/1000,scantokens(ss)/1000) + (_special_signal_/1000,3/1000,scantokens(ss)/1000) fi enddef ; @@ -482,4 +522,29 @@ def register (expr label, width, height, offset) = endgroup ; enddef ; +%D We cannot scale cmyk colors directly since this spoils +%D the trigger signal (such colors are no real colors). + +vardef scaledcmyk(expr c,m,y,k,sf) = + cmyk(sf*c,sf*m,sf*y,sf*k) +enddef ; + +vardef scaledcmykasrgb(expr c,m,y,k,sf) = + (sf*(1-c-k,1-m-k,1-y-k)) +enddef ; + +vardef scaledrgbascmyk(expr c,m,y,k,sf) = + scaledcmyk(1-c,1-m,1-y,0,sf) +enddef ; + +vardef scaledrgb(expr r,g,b,sf) = + (sf*(r,g,b)) +enddef ; + +vardef scaledgray(expr s,sf) = + (sf*(s,s,s)) +enddef ; + +% spotcolor is already scaled + endinput ; diff --git a/metapost/context/mp-symb.mp b/metapost/context/mp-symb.mp index edf2b44d3..a84c84e82 100644 --- a/metapost/context/mp-symb.mp +++ b/metapost/context/mp-symb.mp @@ -27,7 +27,6 @@ path lefttriangle, righttriangle, sublefttriangle, subrighttriangle; pair s ; s = (2wb,0) ; - x1t = x2t = 0; x3t = wt; y3t = .5h; diff --git a/metapost/context/mp-tool.mp b/metapost/context/mp-tool.mp index 1c8dc83f2..210c34632 100644 --- a/metapost/context/mp-tool.mp +++ b/metapost/context/mp-tool.mp @@ -60,27 +60,27 @@ string semicolor ; semicolor := char 59 ; % eerste " " er uit +string space ; space = char 32 ; + vardef ddecimal primary p = - " " & decimal xpart p & - " " & decimal ypart p + decimal xpart p & " " & decimal ypart p enddef ; extra_endfig := extra_endfig - & "special " + & "special " & "(" & ditto - & "%%HiResBoundingBox:" + & "%%HiResBoundingBox: " & ditto & "&ddecimal llcorner currentpicture" + & "&space" & "&ddecimal urcorner currentpicture" & ");"; %D Also handy (when we flush colors): vardef dddecimal primary c = - " " & decimal redpart c & - " " & decimal greenpart c & - " " & decimal bluepart c + decimal redpart c & " " & decimal greenpart c & " " & decimal bluepart c enddef ; %D We have standardized data file names: @@ -1343,7 +1343,7 @@ vardef anglebetween (expr a, b, str) = % path path string curve := pointa..controls middle..pointb ; middle := point .5 along curve ; fi ; - draw thefreelabel(str, middle, common) withcolor black ; + draw thefreelabel(str, middle, common) ; % withcolor black ; curve enddef ; @@ -1635,38 +1635,107 @@ def remappedcolor(expr c) = fi enddef ; -def refill suffix c = do_repath (1) (c) enddef ; -def redraw suffix c = do_repath (2) (c) enddef ; -def recolor suffix c = do_repath (0) (c) enddef ; +% def refill suffix c = do_repath (1) (c) enddef ; +% def redraw suffix c = do_repath (2) (c) enddef ; +% def recolor suffix c = do_repath (0) (c) enddef ; +% +% color refillbackground ; refillbackground := (1,1,1) ; +% +% def do_repath (expr mode) (suffix c) text t = % can it be stroked and filled at the same time ? +% begingroup ; +% if mode=0 : save withcolor ; remapcolors ; fi ; +% save _c_, _cc_, _f_, _b_ ; picture _c_, _cc_ ; color _f_ ; path _b_ ; +% _c_ := c ; _b_ := boundingbox c ; c := nullpicture ; +% for i within _c_ : +% _f_ := (redpart i, greenpart i, bluepart i) ; +% if bounded i : +% setbounds c to pathpart i ; +% elseif clipped i : +% clip c to pathpart i ; +% elseif stroked i : +% addto c doublepath pathpart i +% dashed dashpart i withpen penpart i +% withcolor _f_ % (redpart i, greenpart i, bluepart i) +% if mode=2 : t fi ; +% elseif filled i : +% addto c contour pathpart i +% withcolor _f_ +% if (mode=1) and (_f_<>refillbackground) : t fi ; +% else : +% addto c also i ; +% fi ; +% endfor ; +% setbounds c to _b_ ; +% endgroup ; +% enddef ; + +% Thanks to Jens-Uwe Morawski for pointing out that we need +% to treat bounded and clipped components as local pictures. + +def recolor suffix p = p := repathed (0,p) enddef ; +def refill suffix p = p := repathed (1,p) enddef ; +def redraw suffix p = p := repathed (2,p) enddef ; +def retext suffix p = p := repathed (3,p) enddef ; +def untext suffix p = p := repathed (4,p) enddef ; + +primarydef p recolored t = repathed(0,p) t enddef ; +primarydef p refilled t = repathed(1,p) t enddef ; +primarydef p redrawn t = repathed(2,p) t enddef ; +primarydef p retexted t = repathed(3,p) t enddef ; +primarydef p untexted t = repathed(4,p) t enddef ; color refillbackground ; refillbackground := (1,1,1) ; -def do_repath (expr mode) (suffix c) text t = % can it be stroked and filled at the same time ? +vardef repathed (expr mode, p) text t = begingroup ; if mode=0 : save withcolor ; remapcolors ; fi ; - save _c_, _f_, _b_ ; picture _c_ ; color _f_ ; path _b_ ; - _c_ := c ; _b_ := boundingbox c ; c := nullpicture ; - for i within _c_ : + save _p_, _pp_, _f_, _b_, _t_ ; + picture _p_, _pp_ ; color _f_ ; path _b_ ; transform _t_ ; + _b_ := boundingbox p ; _p_ := nullpicture ; + for i within p : _f_ := (redpart i, greenpart i, bluepart i) ; if bounded i : - setbounds c to pathpart i ; + _pp_ := repathed(mode,i) t ; + setbounds _pp_ to pathpart i ; + addto _p_ also _pp_ ; elseif clipped i : - clip c to pathpart i ; + _pp_ := repathed(mode,i) t ; + clip _pp_ to pathpart i ; + addto _p_ also _pp_ ; elseif stroked i : - addto c doublepath pathpart i + addto _p_ doublepath pathpart i dashed dashpart i withpen penpart i withcolor _f_ % (redpart i, greenpart i, bluepart i) if mode=2 : t fi ; elseif filled i : - addto c contour pathpart i + addto _p_ contour pathpart i withcolor _f_ if (mode=1) and (_f_<>refillbackground) : t fi ; + elseif textual i : % textpart i <> "" : + if mode <> 4 : + % transform _t_ ; + % (xpart _t_, xxpart _t_, xypart _t_) = (xpart i, xxpart i, xypart i) ; + % (ypart _t_, yypart _t_, yxpart _t_) = (ypart i, yypart i, yxpart i) ; + % addto _p_ also + % textpart i infont fontpart i % todo : other font + % transformed _t_ + % withpen penpart i + % withcolor _f_ + % if mode=3 : t fi ; + addto _p_ also i if mode=3 : t fi ; + fi ; + else : + addto _p_ also i ; fi ; endfor ; - setbounds c to _b_ ; - endgroup ; + setbounds _p_ to _b_ ; + _p_ + endgroup enddef ; + + + % After a question of Denis on how to erase a z variable, Jacko % suggested to assign whatever to x and y. So a clearz % variable can be defined as: @@ -1771,7 +1840,7 @@ def [[ = [ [ enddef ; def [[[ = [ [ [ enddef ; % not prefect, but useful since it removes redundant points. vardef dostraightened(expr sign, p) = - if length(p)>1 : + if length(p)>2 : % was 1, but straight lines are ok save pp ; path pp ; pp := point 0 of p ; for i=1 upto length(p)-1 : @@ -1781,15 +1850,9 @@ vardef dostraightened(expr sign, p) = endfor ; save n, ok ; numeric n ; boolean ok ; n := length(pp) ; ok := false ; +if n>2 : 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) : -%% if ok : -- else : hide ( ok := true ; ) fi point i of pp -%% fi - if unitvector(round(point i of pp - point if i=0 : n else : i-1 fi of pp)) <> sign * unitvector(round(point if i=n : 0 else : i+1 fi of pp - @@ -1799,6 +1862,9 @@ vardef dostraightened(expr sign, p) = endfor if ok and (cycle p) : -- cycle fi +else : + pp +fi else : p fi @@ -1807,8 +1873,16 @@ 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 ; +% vardef simplified expr p = dostraightened(+1,p) enddef ; +% vardef unspiked expr p = dostraightened(-1,p) enddef ; + +vardef simplified expr p = + (reverse dostraightened(+1,dostraightened(+1,reverse p))) +enddef ; + +vardef unspiked expr p = + (reverse dostraightened(-1,dostraightened(-1,reverse p))) +enddef ; % path p ; % p := (2cm,1cm) -- (2cm,1cm) -- (2cm,1cm) -- (3cm,1cm) -- @@ -1940,7 +2014,39 @@ vardef infinite expr p = shifted point length(p) of p) enddef ; +% obscure macros: create var from string and replace - and : +% (needed for process color id's) + +string _clean_ascii[] ; + +_clean_ascii[ASCII "-"] := "_" ; +_clean_ascii[ASCII ":"] := "_" ; +_clean_ascii[ASCII "."] := "_" ; + +vardef cleanstring (expr s) = + save ss ; string ss, si ; ss = "" ; + for i=0 upto length(s) : + si := substring(i,i+1) of s ; + ss := ss & if known _clean_ascii[ASCII si] : _clean_ascii[ASCII si] else : si fi ; + endfor ; + ss +enddef ; + +vardef setunstringed (expr s, v) = + scantokens(cleanstring(s)) := v ; +enddef ; + +vardef setunstringed (expr s, v) = + scantokens(cleanstring(s)) := v ; +enddef ; +vardef getunstringed (expr s) = + scantokens(cleanstring(s)) +enddef ; + +vardef unstringed (expr s) = + expandafter known scantokens(cleanstring(s)) +enddef ; % done |