summaryrefslogtreecommitdiff
path: root/metapost
diff options
context:
space:
mode:
Diffstat (limited to 'metapost')
-rw-r--r--metapost/context/mp-char.mp100
-rw-r--r--metapost/context/mp-core.mp701
-rw-r--r--metapost/context/mp-form.mp19
-rw-r--r--metapost/context/mp-page.mp78
-rw-r--r--metapost/context/mp-spec.mp139
-rw-r--r--metapost/context/mp-symb.mp1
-rw-r--r--metapost/context/mp-tool.mp168
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