From 7e78c92b74e8b01d721befd8b1668a88c4bf8319 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Mon, 5 Sep 2011 19:28:00 +0200 Subject: beta 2011.09.05 19:28 --- metapost/context/base/metafun.mp | 76 +- metapost/context/base/metafun.mpii | 64 ++ metapost/context/base/metafun.mpiv | 53 ++ metapost/context/base/mp-chem.mp | 761 ------------------- metapost/context/base/mp-chem.mpiv | 761 +++++++++++++++++++ metapost/context/base/mp-core.mp | 1421 ------------------------------------ metapost/context/base/mp-core.mpii | 1421 ++++++++++++++++++++++++++++++++++++ metapost/context/base/mp-core.mpiv | 1353 ++++++++++++++++++++++++++++++++++ metapost/context/base/mp-mlib.mp | 573 --------------- metapost/context/base/mp-spec.mp | 786 -------------------- metapost/context/base/mp-spec.mpii | 786 ++++++++++++++++++++ 11 files changed, 4441 insertions(+), 3614 deletions(-) create mode 100644 metapost/context/base/metafun.mpii create mode 100644 metapost/context/base/metafun.mpiv delete mode 100644 metapost/context/base/mp-chem.mp create mode 100644 metapost/context/base/mp-chem.mpiv delete mode 100644 metapost/context/base/mp-core.mp create mode 100644 metapost/context/base/mp-core.mpii create mode 100644 metapost/context/base/mp-core.mpiv delete mode 100644 metapost/context/base/mp-mlib.mp delete mode 100644 metapost/context/base/mp-spec.mp create mode 100644 metapost/context/base/mp-spec.mpii (limited to 'metapost') diff --git a/metapost/context/base/metafun.mp b/metapost/context/base/metafun.mp index 00011c8be..3c72356cf 100644 --- a/metapost/context/base/metafun.mp +++ b/metapost/context/base/metafun.mp @@ -1,75 +1,5 @@ -%D \module -%D [ file=metafun.mp, -%D version=2000.07.15, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=format generation file, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See mreadme.pdf for -%C details. - -%D When generating many graphics at runtime, it can save run -%D time to use a format file. We could have named this file -%D \type {context}, but this is error prone, because it forces -%D to use the progname \type {mpost} or \type {context} -%D explicitly, depending on the needs. When using the format, -%D a mismatch in the memory specification of \type {mpost} or -%D \type {context} (the \TEX\ one) could lead to lost strings -%D (and as a result in buggy boundingbox and special -%D handling). By using the name \type {metatex} we make sure -%D that we use (unless overloaded) the settings of \type -%D {mpost}. - -%D First we input John Hobby's metapost plain file. However, -%D because we want to prevent dependency problems and in the -%D end even may use a patched version, we prefer to use a -%D copy, - -if unknown ahangle : - input mp-base.mp ; % input plain.mp ; +if known mplib : + input metafun.mpiv ; else : - let dump = relax ; + input metafun.mpii ; fi ; - -input mp-tool.mp ; -input mp-spec.mp ; % will be skipped in mkiv, some day -input mp-core.mp ; -input mp-page.mp ; -input mp-text.mp ; -input mp-txts.mp ; -input mp-shap.mp ; -input mp-butt.mp ; -input mp-char.mp ; -input mp-step.mp ; -input mp-grph.mp ; -input mp-figs.mp ; - -input mp-mlib.mp ; - -if known context_mlib : input mp-chem.mp ; fi ; % only when mkiv - -% mp-form.mp ; -input mp-grid.mp ; -input mp-func.mp ; - -string metafunversion ; - -metafunversion = "metafun" & " " & - decimal year & "-" & - decimal month & "-" & - decimal day & " " & - if ((time div 60) < 10) : "0" & fi - decimal (time div 60) & ":" & - if ((time-(time div 60)*60) < 10) : "0" & fi - decimal (time-(time div 60)*60) ; - -let normalend = end ; - -def end = - ; message "" ; message metafunversion ; message "" ; normalend ; -enddef ; - -dump ; endinput . diff --git a/metapost/context/base/metafun.mpii b/metapost/context/base/metafun.mpii new file mode 100644 index 000000000..4d8dc2537 --- /dev/null +++ b/metapost/context/base/metafun.mpii @@ -0,0 +1,64 @@ +%D \module +%D [ file=metafun.mp, +%D version=2000.07.15, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=format generation file, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D When generating many graphics at runtime, it can save run +%D time to use a format file. We could have named this file +%D \type {context}, but this is error prone, because it forces +%D to use the progname \type {mpost} or \type {context} +%D explicitly, depending on the needs. When using the format, +%D a mismatch in the memory specification of \type {mpost} or +%D \type {context} (the \TEX\ one) could lead to lost strings +%D (and as a result in buggy boundingbox and special +%D handling). By using the name \type {metatex} we make sure +%D that we use (unless overloaded) the settings of \type +%D {mpost}. + +%D First we input John Hobby's metapost plain file. However, +%D because we want to prevent dependency problems and in the +%D end even may use a patched version, we prefer to use a +%D copy. + +input mp-base.mp ; +input mp-tool.mp ; +input mp-spec.mpii ; +input mp-core.mpii ; +input mp-page.mp ; +input mp-text.mp ; +input mp-txts.mp ; +input mp-shap.mp ; +input mp-butt.mp ; +input mp-char.mp ; +input mp-step.mp ; +input mp-grph.mp ; +input mp-figs.mp ; +input mp-grid.mp ; +input mp-func.mp ; + +string metafunversion ; + +metafunversion = "metafun ii" & " " & + decimal year & "-" & + decimal month & "-" & + decimal day & " " & + if ((time div 60) < 10) : "0" & fi + decimal (time div 60) & ":" & + if ((time-(time div 60)*60) < 10) : "0" & fi + decimal (time-(time div 60)*60) ; + +let normalend = end ; + +def end = + ; message "" ; message metafunversion ; message "" ; normalend ; +enddef ; + +dump ; endinput . diff --git a/metapost/context/base/metafun.mpiv b/metapost/context/base/metafun.mpiv new file mode 100644 index 000000000..59ca2c4bd --- /dev/null +++ b/metapost/context/base/metafun.mpiv @@ -0,0 +1,53 @@ +%D \module +%D [ file=metafun.mp, +%D version=2000.07.15, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=format generation file, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +%D First we input John Hobby's metapost plain file. However, +%D because we want to prevent dependency problems and in the +%D end even may use a patched version, we prefer to use a +%D copy. + +input mp-base.mp ; +input mp-tool.mp ; +input mp-core.mpiv ; +input mp-page.mp ; +input mp-text.mp ; +input mp-txts.mp ; +input mp-shap.mp ; +input mp-butt.mp ; +input mp-char.mp ; +input mp-step.mp ; +input mp-grph.mp ; +input mp-figs.mp ; +input mp-mlib.mpiv ; +input mp-chem.mpiv ; +input mp-grid.mp ; +input mp-func.mp ; + +string metafunversion ; + +metafunversion = "metafun iv" & " " & + decimal year & "-" & + decimal month & "-" & + decimal day & " " & + if ((time div 60) < 10) : "0" & fi + decimal (time div 60) & ":" & + if ((time-(time div 60)*60) < 10) : "0" & fi + decimal (time-(time div 60)*60) ; + +let normalend = end ; + +def end = + ; message "" ; message metafunversion ; message "" ; normalend ; +enddef ; + +dump ; endinput . diff --git a/metapost/context/base/mp-chem.mp b/metapost/context/base/mp-chem.mp deleted file mode 100644 index c70dafd85..000000000 --- a/metapost/context/base/mp-chem.mp +++ /dev/null @@ -1,761 +0,0 @@ -%D \module -%D [ file=mp-chem.mp, -%D version=2009.05.13, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=chemicals, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright=\PRAGMA] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See licen-en.pdf for -%C details. - -%D This module in incomplete and experimental. - -% either consistent setting or not - -if known chem_reset : endinput ; fi ; - -numeric - chem_width, chem_radical_min, chem_radical_max, chem_text_max, chem_circle_radius, - chem_rotation, chem_adjacent, chem_stack, chem_substituent, chem_direction, chem_setting_scale, - chem_setting_offset, chem_text_offset, chem_picture_offset, chem_center_offset, chem_substituent_offset, - chem_setting_l, chem_setting_r, chem_setting_t, chem_setting_b ; - -boolean - chem_setting_axis, - chem_setting_fixedwidth, chem_setting_fixedheight, - chem_doing_pb, chem_text_trace ; - -path - chem_setting_bbox ; - -pair - chem_shift, - chem_adjacent_p, chem_substituent_p, chem_direction_p, chem_move_p ; - -numeric - chem_width[], chem_angle[], chem_start[], chem_initialrot[], chem_initialmov[] ; - -pair - chem_stack_d[], - chem_b_zero[], chem_n_zero[], - chem_r_max[], chem_r_min[], - chem_r_zero[], chem_mr_zero[], chem_pr_zero[], chem_crz_zero[], - chem_rt_zero[], chem_rtt_zero[], chem_rbt_zero[], - chem_mid_zero[] ; - -path - chem_b_path[], chem_bx_path[], chem_eb_path[], chem_sr_path[], chem_br_path[], - chem_sb_path[], chem_msb_path[], chem_psb_path[], - chem_s_path[], chem_ss_path[], chem_mss_path[], chem_pss_path[], - chem_e_path[], chem_sd_path[], chem_bb_path[], chem_oe_path[], - chem_bd_path[], chem_bw_path[], - chem_ddt_path[], chem_ddb_path[], chem_ldt_path[], chem_ldb_path[], chem_rdt_path[], chem_rdb_path[], - chem_dbl_path[], chem_dbr_path[], - chem_ad_path[], chem_au_path[], - chem_r_path[], chem_rl_path[], chem_rr_path[], - chem_rb_path[], chem_prb_path[], chem_mrb_path[], - chem_srl_path[], chem_srr_path[], - chem_msr_path[], chem_psr_path[], - chem_mr_path[], chem_pr_path[], - chem_c_path[], chem_cc_path[], - chem_midt_path[], chem_midb_path[], chem_midst_path[], chem_midsb_path[] ; - -chem_setting_scale := 1 ; -chem_base_width := 40pt ; -chem_text_offset := 3pt ; -chem_center_offset := 6pt ; -chem_picture_offset := 10pt ; -chem_substituent_offset := 10pt ; -chem_radical_min := 1.25 ; -chem_radical_max := 1.50 ; -chem_text_min := 0.75 ; -chem_text_max := 1.75 ; -chem_circle_radius := 0.80 ; -chem_circle_radius := 1.10 ; -chem_rotation := 1 ; -chem_adjacent := 0 ; -chem_substituent := 0 ; -chem_direction := 0 ; -chem_stack_n := 0 ; -chem_doing_pb := false ; -chem_shift := origin ; -chem_dot_factor := 4 ; -chem_text_trace := false ; -chem_bd_n := 4 ; -chem_bw_n := 4 ; -chem_bd_angle := 4 ; -chem_bb_angle := 4 ; - -vardef chem_start_structure(expr n, l, r, t, b, scale, axis, fixedwidth, fixedheight, offset) = - chem_setting_axis := axis ; - chem_setting_l := l * scale ; - chem_setting_r := r * scale ; - chem_setting_t := t * scale ; - chem_setting_b := b * scale ; - chem_setting_fixedwidth := fixedwidth ; - chem_setting_fixedheight := fixedheight ; - chem_setting_offset := offset ; - if scale <> chem_setting_scale : - chem_setting_scale := scale ; - chem_init_all ; - fi ; - chem_rotation := 1 ; - chem_adjacent := 0 ; - chem_substituent := 0 ; - chem_direction := 0 ; - chem_stack_n := 0 ; - chem_doing_pb := false ; - chem_shift := origin ; -enddef ; - -def chem_stop_structure = - currentpicture := currentpicture shifted - chem_shift ; - % axis here - if chem_setting_fixedwidth : - chem_setting_l := - xpart llcorner currentpicture ; - chem_setting_r := xpart urcorner currentpicture ; - fi ; - if chem_setting_fixedheight : - chem_setting_t := ypart urcorner currentpicture ; - chem_setting_b := - ypart llcorner currentpicture ; - fi ; - chem_setting_bbox := - (-chem_setting_l,-chem_setting_b) -- ( chem_setting_r,-chem_setting_b) -- - ( chem_setting_r, chem_setting_t) -- (-chem_setting_l, chem_setting_t) -- cycle ; - % maybe put it behind the picture - if chem_setting_axis : - save stp ; stp := chem_base_width/ 2 * chem_setting_scale ; - save siz ; siz := chem_base_width/10 * chem_setting_scale ; - draw (-chem_setting_l,0) -- (chem_setting_r,0) withcolor blue ; - draw (0,-chem_setting_b) -- (0,chem_setting_t) withcolor blue ; - for i = 0 step stp until chem_setting_r : draw (i,-siz) -- (i,siz) withcolor blue ; endfor ; - for i = 0 step -stp until -chem_setting_l : draw (i,-siz) -- (i,siz) withcolor blue ; endfor ; - for i = 0 step stp until chem_setting_t : draw (-siz,i) -- (siz,i) withcolor blue ; endfor ; - for i = 0 step -stp until -chem_setting_b : draw (-siz,i) -- (siz,i) withcolor blue ; endfor ; - draw chem_setting_bbox withcolor blue ; - fi ; - setbounds currentpicture to chem_setting_bbox ; -enddef ; - -def chem_start_component = -enddef ; -def chem_stop_component = -enddef ; - -def chem_pb = -% draw boundingbox currentpicture withpen pencircle scaled 1mm withcolor blue ; -% draw origin withpen pencircle scaled 2mm withcolor blue ; - chem_doing_pb := true ; -enddef ; -def chem_pe = -% draw boundingbox currentpicture withpen pencircle scaled .5mm withcolor red ; -% draw origin withpen pencircle scaled 1mm withcolor red ; - currentpicture := currentpicture shifted - chem_shift ; -% draw origin withpen pencircle scaled .5mm withcolor green ; - chem_shift := origin ; - chem_doing_pb := false ; -enddef ; - -vardef chem_do (expr p) = - if chem_doing_pb : - chem_doing_pb := false ; -% save pp ; pair pp ; pp := point 1 of ((origin -- p) enlonged chem_picture_offset) ; -% currentpicture := currentpicture shifted - pp ; -% chem_shift := chem_shift - center pp ; - currentpicture := currentpicture shifted - p ; - chem_shift := chem_shift - p ; - origin % nullpicture - else : - p - fi -enddef ; - -vardef chem_b (expr n, f, t, r, c) = - chem_draw (n, chem_b_path[n], f, t, r, c) ; -enddef ; -vardef chem_sb (expr n, f, t, r, c) = - chem_draw (n, chem_sb_path[n], f, t, r, c) ; -enddef ; -vardef chem_s (expr n, f, t, r, c) = - chem_draw (n, chem_s_path[n], f, t, r, c) ; -enddef ; -vardef chem_ss (expr n, f, t, r, c) = - chem_draw (n, chem_ss_path[n], f, t, r, c) ; -enddef ; -vardef chem_mid (expr n, r, c) = - chem_draw_fixed (n, chem_midt_path[n], r, c) ; - chem_draw_fixed (n, chem_midb_path[n], r, c) ; -enddef ; -vardef chem_mids (expr n, r, c) = - chem_draw_fixed (n, chem_midst_path[n], r, c) ; - chem_draw_fixed (n, chem_midsb_path[n], r, c) ; -enddef ; -vardef chem_mss (expr n, f, t, r, c) = - chem_draw (n, chem_mss_path[n], f, t, r, c) ; -enddef ; -vardef chem_pss (expr n, f, t, r, c) = - chem_draw (n, chem_pss_path[n], f, t, r, c) ; -enddef ; -vardef chem_msb (expr n, f, t, r, c) = - chem_draw (n, chem_msb_path[n], f, t, r, c) ; -enddef ; -vardef chem_psb (expr n, f, t, r, c) = - chem_draw (n, chem_psb_path[n], f, t, r, c) ; -enddef ; -vardef chem_eb (expr n, f, t, r, c) = - chem_draw (n, chem_eb_path[n], f, t, r, c) ; -enddef ; -vardef chem_db (expr n, f, t, r, c) = - if n = 1 : - chem_draw (n, chem_msb_path [n], f, t, r, c) ; - chem_draw (n, chem_psb_path [n], f, t, r, c) ; - else : - chem_draw (n, chem_dbl_path [n], f, t, r, c) ; - chem_draw (n, chem_dbr_path [n], f, t, r, c) ; - fi ; -enddef ; -vardef chem_er (expr n, f, t, r, c) = - chem_draw (n, chem_rl_path[n], f, t, r, c) ; - chem_draw (n, chem_rr_path[n], f, t, r, c) ; -enddef ; -vardef chem_dr (expr n, f, t, r, c) = - chem_draw (n, chem_srl_path[n], f, t, r, c) ; - chem_draw (n, chem_srr_path[n], f, t, r, c) ; -enddef ; -vardef chem_ad (expr n, f, t, r, c) = - chem_draw_arrow(n, chem_ad_path[n], f, t, r, c) ; -enddef ; -vardef chem_au (expr n, f, t, r, c) = - chem_draw_arrow(n, chem_au_path[n], f, t, r, c) -enddef ; -vardef chem_r (expr n, f, t, r, c) = - if n < 0 : - chem_draw_vertical (n, chem_r_path[n], f, t, r, c) ; - else : - chem_draw (n, chem_r_path[n], f, t, r, c) ; - fi ; -enddef ; -vardef chem_rd (expr n, f, t, r, c) = - chem_dashed_normal (n, chem_r_path[n], f, t, r, c) -enddef ; -vardef chem_mrd (expr n, f, t, r, c) = - chem_dashed_normal (n, chem_mr_path[n], f, t, r, c) -enddef ; -vardef chem_prd (expr n, f, t, r, c) = - chem_dashed_normal (n, chem_pr_path[n], f, t, r, c) -enddef ; -vardef chem_br (expr n, f, t, r, c) = - chem_fill (n, chem_br_path[n], f, t, r, c ) -enddef ; -vardef chem_rb (expr n, f, t, r, c) = - chem_fill (n, chem_rb_path[n], f, t, r, c) -enddef ; -vardef chem_mrb (expr n, f, t, r, c) = - chem_fill (n, chem_mrb_path[n], f, t, r, c) -enddef ; -vardef chem_prb (expr n, f, t, r, c) = - chem_fill (n, chem_prb_path[n], f, t, r, c) -enddef ; -vardef chem_mr (expr n, f, t, r, c) = - if n < 0 : - chem_draw_vertical(n, chem_mr_path[n], f, t, r, c) - else : - chem_draw (n, chem_mr_path[n], f, t, r, c) - fi -enddef ; -vardef chem_pr (expr n, f, t, r, c) = - if n < 0 : - chem_draw_vertical(n, chem_pr_path[n], f, t, r, c) - else : - chem_draw (n, chem_pr_path[n], f, t, r, c) - fi -enddef ; -vardef chem_sr (expr n, f, t, r, c) = - chem_draw (n, chem_sr_path[n], f, t, r, c) -enddef ; -vardef chem_msr (expr n, f, t, r, c) = - chem_draw (n, chem_msr_path[n], f, t, r, c) -enddef ; -vardef chem_psr (expr n, f, t, r, c) = - chem_draw (n, chem_psr_path[n], f, t, r, c) -enddef ; -vardef chem_c (expr n, f, t, r, c) = - chem_draw (n, chem_c_path[n], f, t, r, c) -enddef ; -vardef chem_cc (expr n, f, t, r, c) = - chem_draw (n, chem_cc_path[n], f, f, r, c) -enddef ; -vardef chem_cd (expr n, f, t, r, c) = - chem_dashed_connected (n, chem_c_path[n], f, t, r, c) -enddef ; -vardef chem_ccd (expr n, f, t, r, c) = - chem_dashed_normal (n, chem_cc_path[n], f, f, r, c) -enddef ; -vardef chem_rn (expr n, i, t) = - chem_rt (n,i,t) ; -enddef ; -vardef chem_rtn (expr n, i, t) = - chem_rtt(n,i,t) ; -enddef ; -vardef chem_rbn (expr n, i, t) = - chem_rbt(n,i,t) ; -enddef ; -vardef chem_tb (expr n, f, t, r, c) = % one - chem_draw (n, chem_msb_path[n], f, t, r, c) ; - chem_draw (n, chem_sb_path [n], f, t, r, c) ; - chem_draw (n, chem_psb_path[n], f, t, r, c) ; -enddef ; -vardef chem_ep (expr n, f, t, r, c) = % one - chem_draw (n, chem_e_path[n], f, t, r, c) ; -enddef ; -vardef chem_es (expr n, f, t, r, c) = % one - chem_draw_dot (n, center chem_e_path[n], f, t, r, c) ; -enddef ; -vardef chem_ed (expr n, f, t, r, c) = % one - chem_draw_dot (n, point 0 of chem_e_path[n], f, t, r, c) ; - chem_draw_dot (n, point 1 of chem_e_path[n], f, t, r, c) ; -enddef ; -vardef chem_et (expr n, f, t, r, c) = % one - chem_draw_dot (n, point 0 of chem_e_path[n], f, t, r, c) ; - chem_draw_dot (n, center chem_e_path[n], f, t, r, c) ; - chem_draw_dot (n, point 1 of chem_e_path[n], f, t, r, c) ; -enddef ; -vardef chem_sd (expr n, f, t, r, c) = % one - chem_draw (n, chem_ddt_path[n], f, t, r, c) ; - chem_draw (n, chem_ddb_path[n], f, t, r, c) ; -enddef ; -vardef chem_rdd (expr n, f, t, r, c) = % one - chem_draw (n, chem_ldt_path[n], f, t, r, c) ; - chem_draw (n, chem_ldb_path[n], f, t, r, c) ; - chem_draw (n, chem_psb_path[n], f, t, r, c) ; -enddef ; -vardef chem_ldd (expr n, f, t, r, c) = % one - chem_draw (n, chem_msb_path[n], f, t, r, c) ; - chem_draw (n, chem_rdt_path[n], f, t, r, c) ; - chem_draw (n, chem_rdb_path[n], f, t, r, c) ; -enddef ; -vardef chem_hb (expr n, f, t, r, c) = % one - chem_draw_dot (n, point 0 of chem_sb_path[n], f, t, r, c) ; - chem_draw_dot (n, center chem_sb_path[n], f, t, r, c) ; - chem_draw_dot (n, point 1 of chem_sb_path[n], f, t, r, c) ; -enddef ; -vardef chem_bb (expr n, f, t, r, c) = % one - if n < 0 : - chem_fill (n, chem_bb_path[n], 1, 1, r, c) ; - chem_b (n, f, t, r, c) ; - else : - chem_fill (n, chem_bb_path[n], f, t, r, c) ; - fi ; -enddef ; -vardef chem_oe (expr n, f, t, r, c) = % one - chem_draw (n, chem_oe_path[n], f, t, r, c) ; -enddef ; -vardef chem_bd (expr n, f, t, r, c) = % one - for i=0 upto 5 : - chem_draw (n, subpath (2i,2i+1) of chem_bd_path[n], f, t, r, c) ; - endfor ; -enddef ; -vardef chem_bw (expr n, f, t, r, c) = % one - chem_draw (n, chem_bw_path[n], f, t, r, c) ; -enddef ; - -vardef chem_z_zero@#(text t) = - chem_text@#(t, chem_do(origin)) ; -enddef ; -vardef chem_cz_zero@#(text t) = - chem_text@#(t, chem_do(origin)) ; -enddef ; -vardef chem_z@#(expr n, p) (text t) = - if p = 0 : - chem_text@#(t, chem_do(origin)) ; - else : - chem_text@#(t, chem_do(chem_b_zero[n] rotated chem_ang(n,p))) ; - fi ; -enddef ; -vardef chem_cz@#(expr n, p) (text t) = - if n = 1 : - chem_c_text(t, chem_do(chem_crz_zero[n] rotated chem_ang(n,p))) ; - else : - chem_text@#(t, chem_do(chem_b_zero[n] rotated chem_ang(n,p))) ; - fi ; -enddef ; -vardef chem_midz@#(expr n, p) (text t) = - chem_text@#(t, chem_do(chem_mid_zero[n] rotated chem_ang(n,p))) ; -enddef ; -vardef chem_rz@#(expr n, p) (text t) = - if n < 0 : - % quite special - chem_text@#(t, chem_do(chem_r_zero[n] shifted (chem_b_zero[n] rotated chem_ang(n,p)))) ; - else : - chem_text@#(t, chem_do(chem_r_zero[n] rotated chem_ang(n,p))) ; - fi ; -enddef ; -vardef chem_crz@#(expr n, p) (text tx) = - chem_text(tx, chem_do(chem_crz_zero[n] rotated chem_ang(n,p))) ; -enddef ; -vardef chem_mrz@#(expr n, p) (text t) = - if n < 0 : - % quite special - chem_text@#(t, chem_do(chem_mr_zero[n] shifted (chem_b_zero[n] rotated chem_ang(n,p)))) ; - else : - chem_text@#(t, chem_do(chem_mr_zero[n] rotated chem_ang(n,p))) ; - fi ; -enddef ; -vardef chem_prz@#(expr n, p) (text t) = - if n < 0 : - % quite special - chem_text@#(t, chem_do(chem_pr_zero[n] shifted (chem_b_zero[n] rotated chem_ang(n,p)))) ; - else : - chem_text@#(t, chem_do(chem_pr_zero[n] rotated chem_ang(n,p))) ; - fi ; -enddef ; -vardef chem_rt@#(expr n, p) (text t) = - chem_text@#(t, chem_do(chem_rt_zero[n] rotated chem_ang(n,p))) ; -enddef ; -vardef chem_rtt@#(expr n, p) (text t) = - chem_text@#(t, chem_do(chem_rtt_zero[n] rotated chem_ang(n,p))) ; -enddef ; -vardef chem_rbt@#(expr n, p) (text t) = - chem_text@#(t, chem_do(chem_rbt_zero[n] rotated chem_ang(n,p))) ; -enddef ; -vardef chem_zt@#(expr n, p) (text t) = - if n = 1 : - chem_text@#(t, chem_do(chem_rt_zero[n] rotated chem_ang(n,p))) ; - else : - chem_text@#(t, chem_do(chem_n_zero[n] rotated chem_ang(n,p))) ; - fi ; -enddef ; -vardef chem_zn@#(expr n, p) (text t) = - if n = 1 : - chem_text@#(t, chem_do(chem_rt_zero[n] rotated chem_ang(n,p))) ; - else : - chem_text@#(t, chem_do(chem_n_zero[n] rotated chem_ang(n,p))) ; - fi ; -enddef ; -vardef chem_zbt@#(expr n, p) (text t) = - chem_text@#(t, chem_do(chem_rtt_zero[n] rotated chem_ang(n,p))) ; -enddef ; -vardef chem_zbn@#(expr n, p) (text t) = - chem_text@#(t, chem_do(chem_rtt_zero[n] rotated chem_ang(n,p))) ; -enddef ; -vardef chem_ztt@#(expr n, p) (text t) = - chem_text@#(t, chem_do(chem_rbt_zero[n] rotated chem_ang(n,p))) ; -enddef ; -vardef chem_ztn@#(expr n, p) (text t) = - chem_text@#(t, chem_do(chem_rbt_zero[n] rotated chem_ang(n,p))) ; -enddef ; - -vardef chem_symbol(expr t) = - draw textext(t) ; -enddef ; - -vardef chem_text@#(expr txt, z) = % adapted copy of thelabel@ - save p ; picture p ; - p := textext(txt) ; - p := p - if (labtype@# >= 10) : shifted (0,ypart center p) fi - shifted (z + chem_text_offset*laboff@# - (labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p)) ; - if chem_text_trace : - draw z withpen pencircle scaled 2pt withcolor red ; - draw boundingbox p withpen pencircle scaled 1pt withcolor red ; - fi ; - draw p -enddef ; - -vardef chem_c_text(expr txt, z) = % adapted copy of thelabel@ - save p ; picture p ; p := textext(txt) ; - save b ; path b ; b := (boundingbox p) shifted z ; - save a ; pair a ; a := (origin--z) intersection_point b ; - if intersection_found : - draw p shifted (z enlonged arclength(a -- center b)) ; - else : - draw p shifted z ; - fi -% draw b withcolor green ; -% draw a withcolor red ; -enddef ; - -vardef chem_ang (expr n, d) = - ((-1 * (d-1) * chem_angle[n]) + (-chem_rotation+1) * 90 + chem_start[n]) % no ; -enddef ; -vardef chem_rot (expr n, d) = - chem_rotation := d ; -enddef ; -vardef chem_adj (expr n, d) = - chem_adjacent := d ; -enddef ; -vardef chem_sub (expr n, d) = - chem_substituent := d ; -enddef ; -vardef chem_dir (expr n, d) = - if n = 1 : - chem_direction_p := (origin - 2*center(chem_b_path[n] rotated chem_ang(n,d+1))) ; - currentpicture := currentpicture shifted chem_direction_p ; - chem_shift := chem_shift + chem_direction_p ; - fi ; -enddef ; -vardef chem_mov (expr n, d) = - if d = 0 : - currentpicture := currentpicture shifted - chem_shift ; - chem_shift := origin ; - else : - chem_move_p := (origin - 2*center(chem_b_path[n] rotated chem_ang(n,d+chem_initialmov[n]))) ; - currentpicture := currentpicture shifted chem_move_p ; - chem_shift := chem_shift + chem_move_p ; - fi ; -enddef ; -vardef chem_off (expr n, d) = - if (d = 1) or (d = 2) or (d = 8) : % positive - currentpicture := currentpicture shifted (-chem_setting_offset,0) ; - chem_shift := chem_shift + (-chem_setting_offset,0) - elseif (d = 4) or (d = 5) or (d = 6) : % negative - currentpicture := currentpicture shifted ( chem_setting_offset,0) ; - chem_shift := chem_shift + ( chem_setting_offset,0) - fi ; -enddef ; - -vardef chem_set(expr n, m) = - if chem_adjacent > 0 : - chem_adjacent_d := xpart chem_b_zero[n] + xpart chem_b_zero[m] ; - if chem_adjacent = 1 : chem_adjacent_p := (-chem_adjacent_d, 0) ; - elseif chem_adjacent = 2 : chem_adjacent_p := (0, -chem_adjacent_d) ; - elseif chem_adjacent = 3 : chem_adjacent_p := ( chem_adjacent_d, 0) ; - elseif chem_adjacent = 4 : chem_adjacent_p := (0, chem_adjacent_d) ; - else : chem_adjacent_p := origin ; - fi ; - currentpicture := currentpicture shifted chem_adjacent_p ; - chem_shift := chem_shift + chem_adjacent_p ; - chem_adjacent := 0 ; - fi ; - if chem_substituent > 0 : - if m = 1 : - chem_substituent_d := xpart chem_crz_zero[n] + chem_substituent_offset ; - else : - chem_substituent_d := xpart chem_crz_zero[n] + xpart chem_b_zero[m] ; - fi ; - if chem_substituent = 1 : chem_substituent_p := (-chem_substituent_d, 0) ; % - ? - elseif chem_substituent = 2 : chem_substituent_p := (0, chem_substituent_d) ; - elseif chem_substituent = 3 : chem_substituent_p := ( chem_substituent_d, 0) ; - elseif chem_substituent = 4 : chem_substituent_p := (0, -chem_substituent_d) ; - else : chem_substituent_p := origin ; - fi ; - currentpicture := currentpicture shifted chem_substituent_p ; - chem_shift := chem_shift + chem_substituent_p ; - chem_substituent := 0 ; - fi ; - chem_rotation := chem_initialrot[m] ; -enddef ; - -vardef chem_draw (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = - for i:=from_point upto to_point: - draw (path_fragment rotated chem_ang(n,i)) withpen pencircle scaled linewidth withcolor linecolor ; - endfor ; -enddef ; -vardef chem_fill (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = - for i:=from_point upto to_point: - fill (path_fragment rotated chem_ang(n,i)) withpen pencircle scaled 0 withcolor linecolor ; - endfor ; -enddef ; - -vardef chem_dashed_normal (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = - for i:=from_point upto to_point: - draw (path_fragment rotated chem_ang(n,i)) withpen pencircle scaled linewidth withcolor linecolor dashed evenly ; - endfor ; -enddef ; -vardef chem_dashed_connected (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = - draw for i:=from_point upto to_point: - (path_fragment rotated chem_ang(n,i)) if i < to_point : -- fi - endfor withpen pencircle scaled linewidth withcolor linecolor dashed evenly ; -enddef ; -vardef chem_draw_dot (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = - for i:=from_point upto to_point: - draw (path_fragment rotated chem_ang(n,i)) withpen pencircle scaled (chem_dot_factor*linewidth) withcolor linecolor ; - endfor ; -enddef ; -vardef chem_draw_fixed (expr n, path_fragment, linewidth, linecolor) = - draw (path_fragment rotated chem_ang(n,1)) withpen pencircle scaled linewidth withcolor linecolor ; -enddef ; -vardef chem_draw_arrow (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = - for i:=from_point upto to_point: - drawarrow (path_fragment rotated chem_ang(n,i)) withpen pencircle scaled linewidth withcolor linecolor ; - endfor ; -enddef ; -vardef chem_draw_vertical (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = - % quite special - for i:=from_point upto to_point: - draw (path_fragment shifted (chem_b_zero[n] rotated chem_ang(n,i))) withpen pencircle scaled linewidth withcolor linecolor ; - endfor ; -enddef ; - -picture chem_stack_p[] ; -pair chem_stack_shift[] ; - -vardef chem_save = - chem_stack_n := chem_stack_n + 1 ; - chem_stack_p[chem_stack_n] := currentpicture ; - chem_stack_shift[chem_stack_n] := chem_shift ; - chem_shift := origin ; -% chem_adjacent := 0 ; -% chem_substituent := 0 ; -% chem_rotation := 1 ; - currentpicture := nullpicture ; -enddef ; -vardef chem_restore = - if chem_stack_n > 0 : - currentpicture := currentpicture shifted - chem_shift ; - addto chem_stack_p[chem_stack_n] also currentpicture ; - currentpicture := chem_stack_p[chem_stack_n] ; - chem_stack_p[chem_stack_n] := nullpicture ; - chem_shift := chem_stack_shift[chem_stack_n] ; - chem_stack_n := chem_stack_n - 1 ; - fi ; -enddef ; - -def chem_init_some(expr n, ratio, start, initialrot, initialmov) = - chem_width [n] := ratio * chem_base_width * chem_setting_scale ; - chem_angle [n] := 360/abs(n) ; - chem_start [n] := start ; - chem_initialrot[n] := initialrot ; - chem_initialmov[n] := initialmov ; - chem_b_zero [n] := (chem_width[n],0) rotated (chem_angle[n]/2) ; - chem_n_zero [n] := (chem_text_min*chem_width[n],0) rotated (chem_angle[n]/2) ; - chem_r_max [n] := chem_radical_max*chem_b_zero[n] ; - chem_r_path [n] := chem_b_zero[n] -- chem_r_max[n] ; - chem_mr_path [n] := chem_r_path [n] rotatedaround(chem_b_zero[n], (180-chem_angle[n])/2) ; - chem_pr_path [n] := chem_r_path [n] rotatedaround(chem_b_zero[n],-(180-chem_angle[n])/2) ; - chem_r_zero [n] := point 1 of chem_r_path [n] ; - chem_mr_zero [n] := point 1 of chem_mr_path[n] ; - chem_pr_zero [n] := point 1 of chem_pr_path[n] ; - chem_crz_zero [n] := point 1 of (chem_r_path[n] enlonged chem_center_offset) ; - chem_au_path [n] := subpath (0.2,0.8) of (chem_r_max[n] -- (chem_r_max[n] rotated chem_angle[n])) ; - chem_ad_path [n] := reverse(chem_au_path[n]) ; - chem_rt_zero [n] := (((chem_radical_max+chem_radical_min)/2)*chem_width[n],0) rotated (chem_angle[n]/2) ; - chem_rtt_zero [n] := chem_rt_zero[n] rotated + 10 ; - chem_rbt_zero [n] := chem_rt_zero[n] rotated - 10 ; - chem_b_path [n] := reverse(chem_b_zero[n] -- (chem_b_zero[n] rotated -chem_angle[n])) ; - chem_bx_path [n] := reverse(chem_b_zero[n] -- (chem_b_zero[n] rotated -chem_angle[n])) ; % ? - chem_sb_path [n] := subpath (0.25,0.75) of chem_b_path[n] ; - chem_s_path [n] := point 0 of chem_b_path[n] -- point 0 of (chem_b_path[n] rotated (2chem_angle[n])) ; - chem_ss_path [n] := subpath (0.25,0.75) of (chem_s_path[n]) ; - chem_pss_path [n] := subpath (0.00,0.75) of (chem_s_path[n]) ; - chem_mss_path [n] := subpath (0.25,1.00) of (chem_s_path[n]) ; - chem_mid_zero [n] := origin shifted (-.25chem_width[n],0) ; - chem_midst_path[n] := chem_mid_zero[n] -- (chem_width[n],0) rotated ( chem_angle[n] + chem_angle[n]/2) ; - chem_midsb_path[n] := chem_mid_zero[n] -- (chem_width[n],0) rotated (-chem_angle[n] - chem_angle[n]/2) ; - chem_midt_path [n] := subpath (0.25,1.00) of chem_midst_path [n] ; - chem_midb_path [n] := subpath (0.25,1.00) of chem_midsb_path [n] ; - chem_msb_path [n] := subpath (0.00,0.75) of chem_b_path[n] ; - chem_psb_path [n] := subpath (0.25,1.00) of chem_b_path[n] ; - chem_dbl_path [n] := chem_sb_path[n] shifted - (0.05[origin,center chem_sb_path[n]]) ; % parallel - chem_dbr_path [n] := chem_sb_path[n] shifted + (0.05[origin,center chem_sb_path[n]]) ; - chem_eb_path [n] := chem_sb_path[n] shifted - (0.25[origin,center chem_sb_path[n]]) ; - chem_sr_path [n] := chem_radical_min*chem_b_zero[n] -- chem_r_max[n] ; - chem_rl_path [n] := chem_r_path[n] paralleled (chem_base_width/20) ; - chem_rr_path [n] := chem_r_path[n] paralleled -(chem_base_width/20) ; - chem_srl_path [n] := chem_sr_path[n] paralleled (chem_base_width/20) ; - chem_srr_path [n] := chem_sr_path[n] paralleled -(chem_base_width/20) ; - chem_br_path [n] := point 1 of chem_sb_path[n] -- - point 0 of chem_sb_path[n] rotatedaround(point 1 of chem_sb_path[n], -4) -- - point 0 of chem_sb_path[n] rotatedaround(point 1 of chem_sb_path[n], 4) -- cycle ; - chem_rb_path [n] := chem_b_zero[n] -- chem_r_max[n] rotated -2 -- chem_r_max[n] -- chem_r_max[n] rotated 2 -- cycle ; - chem_mrb_path [n] := chem_rb_path[n] rotatedaround(chem_b_zero[n], (180-chem_angle[n])/2) ; - chem_prb_path [n] := chem_rb_path[n] rotatedaround(chem_b_zero[n],-(180-chem_angle[n])/2) ; - chem_msr_path [n] := chem_sr_path[n] rotatedaround(chem_b_zero[n], (180-chem_angle[n])/2) ; - chem_psr_path [n] := chem_sr_path[n] rotatedaround(chem_b_zero[n],-(180-chem_angle[n])/2) ; - % not yet ok: -% chem_c_path [n] := subpath (30/45, -30/45) of (fullcircle scaled (1.25*chem_circle_radius*chem_width[n])); -% chem_cc_path [n] := subpath (30/45,8-30/45) of (fullcircle rotated 90 scaled (1.25*chem_circle_radius*chem_width[n])); - chem_c_path [n] := subpath (30/45, -30/45) of (fullcircle scaled (chem_width[n])); - chem_cc_path [n] := subpath (30/45,8-30/45) of (fullcircle rotated 90 scaled (chem_width[n])); -enddef ; - -def chem_init_three = chem_init_some(3,30/52 ,-60,1,2) ; enddef ; % 60 -def chem_init_four = chem_init_some(4,30/42.5, 0,1,0) ; enddef ; % 45 -def chem_init_five = chem_init_some(5,30/35 , 0,1,0) ; enddef ; % 36 -def chem_init_six = chem_init_some(6, 1 , 0,1,0) ; enddef ; % 30 -def chem_init_eight = chem_init_some(8,30/22.5, 0,1,0) ; enddef ; % 22.5 - -% bb R -R R Z -RZ +RZ - -def chem_init_some_front(expr n, ratio, start, initialrot, initialmov) = - chem_init_some(n, ratio, start, initialrot, initialmov) ; - chem_bb_path [n] := chem_b_path[n] rotated -chem_angle[n] -- chem_b_path[n] -- chem_b_path[n] rotated chem_angle[n] -- - (reverse(chem_b_path[n] shortened (chem_base_width/20))) paralleled (chem_base_width/20) -- - cycle ; - chem_r_max [n] := chem_radical_max*chem_b_zero[n] ; - chem_mr_path [n] := origin -- origin shifted (0,-.25chem_base_width) ; - chem_pr_path [n] := origin -- origin shifted (0, .25*chem_base_width) ; - chem_r_path [n] := point 1 of chem_mr_path[n] -- point 1 of chem_pr_path[n] ; - chem_mr_zero [n] := point 1 of chem_mr_path[n] ; - chem_pr_zero [n] := point 1 of chem_pr_path[n] ; -enddef ; - -def chem_init_five_front = chem_init_some_front(-5,30/35,0,2,0) ; enddef ; % 36 -def chem_init_six_front = chem_init_some_front(-6, 1 ,0,2,0) ; enddef ; % 30 - -vardef chem_init_one = - chem_width [1] := .75 * chem_base_width * chem_setting_scale ; - chem_angle [1] := 360/8 ; - chem_start [1] := 0 ; - chem_initialrot[1] := 1 ; - chem_initialmov[1] := 1 ; - chem_b_zero [1] := (1.75*chem_width[1],0) ; - chem_r_min [1] := chem_radical_min*chem_b_zero[1] ; - chem_r_max [1] := chem_radical_max*chem_b_zero[1] ; - chem_r_path [1] := (.5*chem_width[1],0) -- (1.25*chem_width[1],0) ; - chem_r_zero [1] := point 1 of chem_r_path [1] ; - chem_b_path [1] := chem_r_path[1] rotated + (chem_angle[1]) ; % used for move here - chem_b_zero [1] := chem_r_zero[1] ; - chem_crz_zero [1] := chem_r_zero[1] enlonged chem_center_offset ; - chem_e_path [1] := (.5*chem_width[1],-.25*chem_width[1]) -- (.5*chem_width[1],.25*chem_width[1]) ; - chem_sb_path [1] := chem_r_path [1] ; - chem_msb_path [1] := chem_r_path [1] shifted (0,-.1chem_width[1]) ; - chem_psb_path [1] := chem_r_path [1] shifted (0, .1chem_width[1]) ; - chem_ddt_path [1] := subpath(0,.4) of chem_r_path [1] ; - chem_ddb_path [1] := subpath(.6,1) of chem_r_path [1] ; - chem_ldt_path [1] := chem_ddt_path [1] shifted (0,-.1chem_width[1]) ; % parallel - chem_ldb_path [1] := chem_ddb_path [1] shifted (0,-.1chem_width[1]) ; - chem_rdt_path [1] := chem_ddt_path [1] shifted (0, .1chem_width[1]) ; - chem_rdb_path [1] := chem_ddb_path [1] shifted (0, .1chem_width[1]) ; - save pr ; pair pr[] ; - pr0 := point 0 of chem_r_path[1] ; - pr1 := point 1 of chem_r_path[1] ; - chem_bb_path [1] := pr0 -- (pr1 rotatedaround(pr0,-chem_bb_angle)) -- (pr1 rotatedaround(pr0,chem_bb_angle)) -- cycle ; - chem_oe_path [1] := ((-20,0)--(10,0){up}..(20,10)..(30,0)..(40,-10)..(50.0,0)..(60,10)..(70,0)..(80,-10)..{up}(90,0)--(120,0)) - xsized (.75*chem_width[1]) shifted pr0 ; - chem_rt_zero [1] := point .5 of chem_r_path[1] ; - chem_rtt_zero [1] := chem_rt_zero[1] rotated + (chem_angle[1]/2) ; - chem_rbt_zero [1] := chem_rt_zero[1] rotated - (chem_angle[1]/2) ; - % added by Alan Braslau (adapted to use shared variables): - save p ; pair p[] ; - p0 := pr1 rotatedaround(pr0, -chem_bd_angle) ; - p1 := pr1 rotatedaround(pr0, +chem_bd_angle) ; - p2 := p0 shifted - pr1 ; - p3 := p1 shifted - pr1 ; - chem_bd_path [1] := - p0 -- p1 for i=chem_bd_n downto 0 : - -- p2 shifted (i/chem_bd_n)[pr1,pr0] - -- p3 shifted (i/chem_bd_n)[pr1,pr0] - endfor ; - chem_bw_path [1] := - for i=0 upto chem_bw_n - 1 : - ((i) /chem_bw_n)[pr0,pr1] .. ((i+.25)/chem_bw_n)[pr0,pr1] shifted p2 .. - ((i+.50)/chem_bw_n)[pr0,pr1] .. ((i+.75)/chem_bw_n)[pr0,pr1] shifted -p2 .. - endfor pr1 ; -enddef ; - -def chem_init_all = - chem_init_one ; - chem_init_three ; - chem_init_four ; - chem_init_five ; - chem_init_six ; - chem_init_eight ; - chem_init_five_front ; - chem_init_six_front ; -enddef ; - -chem_init_all ; diff --git a/metapost/context/base/mp-chem.mpiv b/metapost/context/base/mp-chem.mpiv new file mode 100644 index 000000000..c70dafd85 --- /dev/null +++ b/metapost/context/base/mp-chem.mpiv @@ -0,0 +1,761 @@ +%D \module +%D [ file=mp-chem.mp, +%D version=2009.05.13, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=chemicals, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=\PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +%D This module in incomplete and experimental. + +% either consistent setting or not + +if known chem_reset : endinput ; fi ; + +numeric + chem_width, chem_radical_min, chem_radical_max, chem_text_max, chem_circle_radius, + chem_rotation, chem_adjacent, chem_stack, chem_substituent, chem_direction, chem_setting_scale, + chem_setting_offset, chem_text_offset, chem_picture_offset, chem_center_offset, chem_substituent_offset, + chem_setting_l, chem_setting_r, chem_setting_t, chem_setting_b ; + +boolean + chem_setting_axis, + chem_setting_fixedwidth, chem_setting_fixedheight, + chem_doing_pb, chem_text_trace ; + +path + chem_setting_bbox ; + +pair + chem_shift, + chem_adjacent_p, chem_substituent_p, chem_direction_p, chem_move_p ; + +numeric + chem_width[], chem_angle[], chem_start[], chem_initialrot[], chem_initialmov[] ; + +pair + chem_stack_d[], + chem_b_zero[], chem_n_zero[], + chem_r_max[], chem_r_min[], + chem_r_zero[], chem_mr_zero[], chem_pr_zero[], chem_crz_zero[], + chem_rt_zero[], chem_rtt_zero[], chem_rbt_zero[], + chem_mid_zero[] ; + +path + chem_b_path[], chem_bx_path[], chem_eb_path[], chem_sr_path[], chem_br_path[], + chem_sb_path[], chem_msb_path[], chem_psb_path[], + chem_s_path[], chem_ss_path[], chem_mss_path[], chem_pss_path[], + chem_e_path[], chem_sd_path[], chem_bb_path[], chem_oe_path[], + chem_bd_path[], chem_bw_path[], + chem_ddt_path[], chem_ddb_path[], chem_ldt_path[], chem_ldb_path[], chem_rdt_path[], chem_rdb_path[], + chem_dbl_path[], chem_dbr_path[], + chem_ad_path[], chem_au_path[], + chem_r_path[], chem_rl_path[], chem_rr_path[], + chem_rb_path[], chem_prb_path[], chem_mrb_path[], + chem_srl_path[], chem_srr_path[], + chem_msr_path[], chem_psr_path[], + chem_mr_path[], chem_pr_path[], + chem_c_path[], chem_cc_path[], + chem_midt_path[], chem_midb_path[], chem_midst_path[], chem_midsb_path[] ; + +chem_setting_scale := 1 ; +chem_base_width := 40pt ; +chem_text_offset := 3pt ; +chem_center_offset := 6pt ; +chem_picture_offset := 10pt ; +chem_substituent_offset := 10pt ; +chem_radical_min := 1.25 ; +chem_radical_max := 1.50 ; +chem_text_min := 0.75 ; +chem_text_max := 1.75 ; +chem_circle_radius := 0.80 ; +chem_circle_radius := 1.10 ; +chem_rotation := 1 ; +chem_adjacent := 0 ; +chem_substituent := 0 ; +chem_direction := 0 ; +chem_stack_n := 0 ; +chem_doing_pb := false ; +chem_shift := origin ; +chem_dot_factor := 4 ; +chem_text_trace := false ; +chem_bd_n := 4 ; +chem_bw_n := 4 ; +chem_bd_angle := 4 ; +chem_bb_angle := 4 ; + +vardef chem_start_structure(expr n, l, r, t, b, scale, axis, fixedwidth, fixedheight, offset) = + chem_setting_axis := axis ; + chem_setting_l := l * scale ; + chem_setting_r := r * scale ; + chem_setting_t := t * scale ; + chem_setting_b := b * scale ; + chem_setting_fixedwidth := fixedwidth ; + chem_setting_fixedheight := fixedheight ; + chem_setting_offset := offset ; + if scale <> chem_setting_scale : + chem_setting_scale := scale ; + chem_init_all ; + fi ; + chem_rotation := 1 ; + chem_adjacent := 0 ; + chem_substituent := 0 ; + chem_direction := 0 ; + chem_stack_n := 0 ; + chem_doing_pb := false ; + chem_shift := origin ; +enddef ; + +def chem_stop_structure = + currentpicture := currentpicture shifted - chem_shift ; + % axis here + if chem_setting_fixedwidth : + chem_setting_l := - xpart llcorner currentpicture ; + chem_setting_r := xpart urcorner currentpicture ; + fi ; + if chem_setting_fixedheight : + chem_setting_t := ypart urcorner currentpicture ; + chem_setting_b := - ypart llcorner currentpicture ; + fi ; + chem_setting_bbox := + (-chem_setting_l,-chem_setting_b) -- ( chem_setting_r,-chem_setting_b) -- + ( chem_setting_r, chem_setting_t) -- (-chem_setting_l, chem_setting_t) -- cycle ; + % maybe put it behind the picture + if chem_setting_axis : + save stp ; stp := chem_base_width/ 2 * chem_setting_scale ; + save siz ; siz := chem_base_width/10 * chem_setting_scale ; + draw (-chem_setting_l,0) -- (chem_setting_r,0) withcolor blue ; + draw (0,-chem_setting_b) -- (0,chem_setting_t) withcolor blue ; + for i = 0 step stp until chem_setting_r : draw (i,-siz) -- (i,siz) withcolor blue ; endfor ; + for i = 0 step -stp until -chem_setting_l : draw (i,-siz) -- (i,siz) withcolor blue ; endfor ; + for i = 0 step stp until chem_setting_t : draw (-siz,i) -- (siz,i) withcolor blue ; endfor ; + for i = 0 step -stp until -chem_setting_b : draw (-siz,i) -- (siz,i) withcolor blue ; endfor ; + draw chem_setting_bbox withcolor blue ; + fi ; + setbounds currentpicture to chem_setting_bbox ; +enddef ; + +def chem_start_component = +enddef ; +def chem_stop_component = +enddef ; + +def chem_pb = +% draw boundingbox currentpicture withpen pencircle scaled 1mm withcolor blue ; +% draw origin withpen pencircle scaled 2mm withcolor blue ; + chem_doing_pb := true ; +enddef ; +def chem_pe = +% draw boundingbox currentpicture withpen pencircle scaled .5mm withcolor red ; +% draw origin withpen pencircle scaled 1mm withcolor red ; + currentpicture := currentpicture shifted - chem_shift ; +% draw origin withpen pencircle scaled .5mm withcolor green ; + chem_shift := origin ; + chem_doing_pb := false ; +enddef ; + +vardef chem_do (expr p) = + if chem_doing_pb : + chem_doing_pb := false ; +% save pp ; pair pp ; pp := point 1 of ((origin -- p) enlonged chem_picture_offset) ; +% currentpicture := currentpicture shifted - pp ; +% chem_shift := chem_shift - center pp ; + currentpicture := currentpicture shifted - p ; + chem_shift := chem_shift - p ; + origin % nullpicture + else : + p + fi +enddef ; + +vardef chem_b (expr n, f, t, r, c) = + chem_draw (n, chem_b_path[n], f, t, r, c) ; +enddef ; +vardef chem_sb (expr n, f, t, r, c) = + chem_draw (n, chem_sb_path[n], f, t, r, c) ; +enddef ; +vardef chem_s (expr n, f, t, r, c) = + chem_draw (n, chem_s_path[n], f, t, r, c) ; +enddef ; +vardef chem_ss (expr n, f, t, r, c) = + chem_draw (n, chem_ss_path[n], f, t, r, c) ; +enddef ; +vardef chem_mid (expr n, r, c) = + chem_draw_fixed (n, chem_midt_path[n], r, c) ; + chem_draw_fixed (n, chem_midb_path[n], r, c) ; +enddef ; +vardef chem_mids (expr n, r, c) = + chem_draw_fixed (n, chem_midst_path[n], r, c) ; + chem_draw_fixed (n, chem_midsb_path[n], r, c) ; +enddef ; +vardef chem_mss (expr n, f, t, r, c) = + chem_draw (n, chem_mss_path[n], f, t, r, c) ; +enddef ; +vardef chem_pss (expr n, f, t, r, c) = + chem_draw (n, chem_pss_path[n], f, t, r, c) ; +enddef ; +vardef chem_msb (expr n, f, t, r, c) = + chem_draw (n, chem_msb_path[n], f, t, r, c) ; +enddef ; +vardef chem_psb (expr n, f, t, r, c) = + chem_draw (n, chem_psb_path[n], f, t, r, c) ; +enddef ; +vardef chem_eb (expr n, f, t, r, c) = + chem_draw (n, chem_eb_path[n], f, t, r, c) ; +enddef ; +vardef chem_db (expr n, f, t, r, c) = + if n = 1 : + chem_draw (n, chem_msb_path [n], f, t, r, c) ; + chem_draw (n, chem_psb_path [n], f, t, r, c) ; + else : + chem_draw (n, chem_dbl_path [n], f, t, r, c) ; + chem_draw (n, chem_dbr_path [n], f, t, r, c) ; + fi ; +enddef ; +vardef chem_er (expr n, f, t, r, c) = + chem_draw (n, chem_rl_path[n], f, t, r, c) ; + chem_draw (n, chem_rr_path[n], f, t, r, c) ; +enddef ; +vardef chem_dr (expr n, f, t, r, c) = + chem_draw (n, chem_srl_path[n], f, t, r, c) ; + chem_draw (n, chem_srr_path[n], f, t, r, c) ; +enddef ; +vardef chem_ad (expr n, f, t, r, c) = + chem_draw_arrow(n, chem_ad_path[n], f, t, r, c) ; +enddef ; +vardef chem_au (expr n, f, t, r, c) = + chem_draw_arrow(n, chem_au_path[n], f, t, r, c) +enddef ; +vardef chem_r (expr n, f, t, r, c) = + if n < 0 : + chem_draw_vertical (n, chem_r_path[n], f, t, r, c) ; + else : + chem_draw (n, chem_r_path[n], f, t, r, c) ; + fi ; +enddef ; +vardef chem_rd (expr n, f, t, r, c) = + chem_dashed_normal (n, chem_r_path[n], f, t, r, c) +enddef ; +vardef chem_mrd (expr n, f, t, r, c) = + chem_dashed_normal (n, chem_mr_path[n], f, t, r, c) +enddef ; +vardef chem_prd (expr n, f, t, r, c) = + chem_dashed_normal (n, chem_pr_path[n], f, t, r, c) +enddef ; +vardef chem_br (expr n, f, t, r, c) = + chem_fill (n, chem_br_path[n], f, t, r, c ) +enddef ; +vardef chem_rb (expr n, f, t, r, c) = + chem_fill (n, chem_rb_path[n], f, t, r, c) +enddef ; +vardef chem_mrb (expr n, f, t, r, c) = + chem_fill (n, chem_mrb_path[n], f, t, r, c) +enddef ; +vardef chem_prb (expr n, f, t, r, c) = + chem_fill (n, chem_prb_path[n], f, t, r, c) +enddef ; +vardef chem_mr (expr n, f, t, r, c) = + if n < 0 : + chem_draw_vertical(n, chem_mr_path[n], f, t, r, c) + else : + chem_draw (n, chem_mr_path[n], f, t, r, c) + fi +enddef ; +vardef chem_pr (expr n, f, t, r, c) = + if n < 0 : + chem_draw_vertical(n, chem_pr_path[n], f, t, r, c) + else : + chem_draw (n, chem_pr_path[n], f, t, r, c) + fi +enddef ; +vardef chem_sr (expr n, f, t, r, c) = + chem_draw (n, chem_sr_path[n], f, t, r, c) +enddef ; +vardef chem_msr (expr n, f, t, r, c) = + chem_draw (n, chem_msr_path[n], f, t, r, c) +enddef ; +vardef chem_psr (expr n, f, t, r, c) = + chem_draw (n, chem_psr_path[n], f, t, r, c) +enddef ; +vardef chem_c (expr n, f, t, r, c) = + chem_draw (n, chem_c_path[n], f, t, r, c) +enddef ; +vardef chem_cc (expr n, f, t, r, c) = + chem_draw (n, chem_cc_path[n], f, f, r, c) +enddef ; +vardef chem_cd (expr n, f, t, r, c) = + chem_dashed_connected (n, chem_c_path[n], f, t, r, c) +enddef ; +vardef chem_ccd (expr n, f, t, r, c) = + chem_dashed_normal (n, chem_cc_path[n], f, f, r, c) +enddef ; +vardef chem_rn (expr n, i, t) = + chem_rt (n,i,t) ; +enddef ; +vardef chem_rtn (expr n, i, t) = + chem_rtt(n,i,t) ; +enddef ; +vardef chem_rbn (expr n, i, t) = + chem_rbt(n,i,t) ; +enddef ; +vardef chem_tb (expr n, f, t, r, c) = % one + chem_draw (n, chem_msb_path[n], f, t, r, c) ; + chem_draw (n, chem_sb_path [n], f, t, r, c) ; + chem_draw (n, chem_psb_path[n], f, t, r, c) ; +enddef ; +vardef chem_ep (expr n, f, t, r, c) = % one + chem_draw (n, chem_e_path[n], f, t, r, c) ; +enddef ; +vardef chem_es (expr n, f, t, r, c) = % one + chem_draw_dot (n, center chem_e_path[n], f, t, r, c) ; +enddef ; +vardef chem_ed (expr n, f, t, r, c) = % one + chem_draw_dot (n, point 0 of chem_e_path[n], f, t, r, c) ; + chem_draw_dot (n, point 1 of chem_e_path[n], f, t, r, c) ; +enddef ; +vardef chem_et (expr n, f, t, r, c) = % one + chem_draw_dot (n, point 0 of chem_e_path[n], f, t, r, c) ; + chem_draw_dot (n, center chem_e_path[n], f, t, r, c) ; + chem_draw_dot (n, point 1 of chem_e_path[n], f, t, r, c) ; +enddef ; +vardef chem_sd (expr n, f, t, r, c) = % one + chem_draw (n, chem_ddt_path[n], f, t, r, c) ; + chem_draw (n, chem_ddb_path[n], f, t, r, c) ; +enddef ; +vardef chem_rdd (expr n, f, t, r, c) = % one + chem_draw (n, chem_ldt_path[n], f, t, r, c) ; + chem_draw (n, chem_ldb_path[n], f, t, r, c) ; + chem_draw (n, chem_psb_path[n], f, t, r, c) ; +enddef ; +vardef chem_ldd (expr n, f, t, r, c) = % one + chem_draw (n, chem_msb_path[n], f, t, r, c) ; + chem_draw (n, chem_rdt_path[n], f, t, r, c) ; + chem_draw (n, chem_rdb_path[n], f, t, r, c) ; +enddef ; +vardef chem_hb (expr n, f, t, r, c) = % one + chem_draw_dot (n, point 0 of chem_sb_path[n], f, t, r, c) ; + chem_draw_dot (n, center chem_sb_path[n], f, t, r, c) ; + chem_draw_dot (n, point 1 of chem_sb_path[n], f, t, r, c) ; +enddef ; +vardef chem_bb (expr n, f, t, r, c) = % one + if n < 0 : + chem_fill (n, chem_bb_path[n], 1, 1, r, c) ; + chem_b (n, f, t, r, c) ; + else : + chem_fill (n, chem_bb_path[n], f, t, r, c) ; + fi ; +enddef ; +vardef chem_oe (expr n, f, t, r, c) = % one + chem_draw (n, chem_oe_path[n], f, t, r, c) ; +enddef ; +vardef chem_bd (expr n, f, t, r, c) = % one + for i=0 upto 5 : + chem_draw (n, subpath (2i,2i+1) of chem_bd_path[n], f, t, r, c) ; + endfor ; +enddef ; +vardef chem_bw (expr n, f, t, r, c) = % one + chem_draw (n, chem_bw_path[n], f, t, r, c) ; +enddef ; + +vardef chem_z_zero@#(text t) = + chem_text@#(t, chem_do(origin)) ; +enddef ; +vardef chem_cz_zero@#(text t) = + chem_text@#(t, chem_do(origin)) ; +enddef ; +vardef chem_z@#(expr n, p) (text t) = + if p = 0 : + chem_text@#(t, chem_do(origin)) ; + else : + chem_text@#(t, chem_do(chem_b_zero[n] rotated chem_ang(n,p))) ; + fi ; +enddef ; +vardef chem_cz@#(expr n, p) (text t) = + if n = 1 : + chem_c_text(t, chem_do(chem_crz_zero[n] rotated chem_ang(n,p))) ; + else : + chem_text@#(t, chem_do(chem_b_zero[n] rotated chem_ang(n,p))) ; + fi ; +enddef ; +vardef chem_midz@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_mid_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_rz@#(expr n, p) (text t) = + if n < 0 : + % quite special + chem_text@#(t, chem_do(chem_r_zero[n] shifted (chem_b_zero[n] rotated chem_ang(n,p)))) ; + else : + chem_text@#(t, chem_do(chem_r_zero[n] rotated chem_ang(n,p))) ; + fi ; +enddef ; +vardef chem_crz@#(expr n, p) (text tx) = + chem_text(tx, chem_do(chem_crz_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_mrz@#(expr n, p) (text t) = + if n < 0 : + % quite special + chem_text@#(t, chem_do(chem_mr_zero[n] shifted (chem_b_zero[n] rotated chem_ang(n,p)))) ; + else : + chem_text@#(t, chem_do(chem_mr_zero[n] rotated chem_ang(n,p))) ; + fi ; +enddef ; +vardef chem_prz@#(expr n, p) (text t) = + if n < 0 : + % quite special + chem_text@#(t, chem_do(chem_pr_zero[n] shifted (chem_b_zero[n] rotated chem_ang(n,p)))) ; + else : + chem_text@#(t, chem_do(chem_pr_zero[n] rotated chem_ang(n,p))) ; + fi ; +enddef ; +vardef chem_rt@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_rt_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_rtt@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_rtt_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_rbt@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_rbt_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_zt@#(expr n, p) (text t) = + if n = 1 : + chem_text@#(t, chem_do(chem_rt_zero[n] rotated chem_ang(n,p))) ; + else : + chem_text@#(t, chem_do(chem_n_zero[n] rotated chem_ang(n,p))) ; + fi ; +enddef ; +vardef chem_zn@#(expr n, p) (text t) = + if n = 1 : + chem_text@#(t, chem_do(chem_rt_zero[n] rotated chem_ang(n,p))) ; + else : + chem_text@#(t, chem_do(chem_n_zero[n] rotated chem_ang(n,p))) ; + fi ; +enddef ; +vardef chem_zbt@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_rtt_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_zbn@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_rtt_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_ztt@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_rbt_zero[n] rotated chem_ang(n,p))) ; +enddef ; +vardef chem_ztn@#(expr n, p) (text t) = + chem_text@#(t, chem_do(chem_rbt_zero[n] rotated chem_ang(n,p))) ; +enddef ; + +vardef chem_symbol(expr t) = + draw textext(t) ; +enddef ; + +vardef chem_text@#(expr txt, z) = % adapted copy of thelabel@ + save p ; picture p ; + p := textext(txt) ; + p := p + if (labtype@# >= 10) : shifted (0,ypart center p) fi + shifted (z + chem_text_offset*laboff@# - (labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p)) ; + if chem_text_trace : + draw z withpen pencircle scaled 2pt withcolor red ; + draw boundingbox p withpen pencircle scaled 1pt withcolor red ; + fi ; + draw p +enddef ; + +vardef chem_c_text(expr txt, z) = % adapted copy of thelabel@ + save p ; picture p ; p := textext(txt) ; + save b ; path b ; b := (boundingbox p) shifted z ; + save a ; pair a ; a := (origin--z) intersection_point b ; + if intersection_found : + draw p shifted (z enlonged arclength(a -- center b)) ; + else : + draw p shifted z ; + fi +% draw b withcolor green ; +% draw a withcolor red ; +enddef ; + +vardef chem_ang (expr n, d) = + ((-1 * (d-1) * chem_angle[n]) + (-chem_rotation+1) * 90 + chem_start[n]) % no ; +enddef ; +vardef chem_rot (expr n, d) = + chem_rotation := d ; +enddef ; +vardef chem_adj (expr n, d) = + chem_adjacent := d ; +enddef ; +vardef chem_sub (expr n, d) = + chem_substituent := d ; +enddef ; +vardef chem_dir (expr n, d) = + if n = 1 : + chem_direction_p := (origin - 2*center(chem_b_path[n] rotated chem_ang(n,d+1))) ; + currentpicture := currentpicture shifted chem_direction_p ; + chem_shift := chem_shift + chem_direction_p ; + fi ; +enddef ; +vardef chem_mov (expr n, d) = + if d = 0 : + currentpicture := currentpicture shifted - chem_shift ; + chem_shift := origin ; + else : + chem_move_p := (origin - 2*center(chem_b_path[n] rotated chem_ang(n,d+chem_initialmov[n]))) ; + currentpicture := currentpicture shifted chem_move_p ; + chem_shift := chem_shift + chem_move_p ; + fi ; +enddef ; +vardef chem_off (expr n, d) = + if (d = 1) or (d = 2) or (d = 8) : % positive + currentpicture := currentpicture shifted (-chem_setting_offset,0) ; + chem_shift := chem_shift + (-chem_setting_offset,0) + elseif (d = 4) or (d = 5) or (d = 6) : % negative + currentpicture := currentpicture shifted ( chem_setting_offset,0) ; + chem_shift := chem_shift + ( chem_setting_offset,0) + fi ; +enddef ; + +vardef chem_set(expr n, m) = + if chem_adjacent > 0 : + chem_adjacent_d := xpart chem_b_zero[n] + xpart chem_b_zero[m] ; + if chem_adjacent = 1 : chem_adjacent_p := (-chem_adjacent_d, 0) ; + elseif chem_adjacent = 2 : chem_adjacent_p := (0, -chem_adjacent_d) ; + elseif chem_adjacent = 3 : chem_adjacent_p := ( chem_adjacent_d, 0) ; + elseif chem_adjacent = 4 : chem_adjacent_p := (0, chem_adjacent_d) ; + else : chem_adjacent_p := origin ; + fi ; + currentpicture := currentpicture shifted chem_adjacent_p ; + chem_shift := chem_shift + chem_adjacent_p ; + chem_adjacent := 0 ; + fi ; + if chem_substituent > 0 : + if m = 1 : + chem_substituent_d := xpart chem_crz_zero[n] + chem_substituent_offset ; + else : + chem_substituent_d := xpart chem_crz_zero[n] + xpart chem_b_zero[m] ; + fi ; + if chem_substituent = 1 : chem_substituent_p := (-chem_substituent_d, 0) ; % - ? + elseif chem_substituent = 2 : chem_substituent_p := (0, chem_substituent_d) ; + elseif chem_substituent = 3 : chem_substituent_p := ( chem_substituent_d, 0) ; + elseif chem_substituent = 4 : chem_substituent_p := (0, -chem_substituent_d) ; + else : chem_substituent_p := origin ; + fi ; + currentpicture := currentpicture shifted chem_substituent_p ; + chem_shift := chem_shift + chem_substituent_p ; + chem_substituent := 0 ; + fi ; + chem_rotation := chem_initialrot[m] ; +enddef ; + +vardef chem_draw (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = + for i:=from_point upto to_point: + draw (path_fragment rotated chem_ang(n,i)) withpen pencircle scaled linewidth withcolor linecolor ; + endfor ; +enddef ; +vardef chem_fill (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = + for i:=from_point upto to_point: + fill (path_fragment rotated chem_ang(n,i)) withpen pencircle scaled 0 withcolor linecolor ; + endfor ; +enddef ; + +vardef chem_dashed_normal (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = + for i:=from_point upto to_point: + draw (path_fragment rotated chem_ang(n,i)) withpen pencircle scaled linewidth withcolor linecolor dashed evenly ; + endfor ; +enddef ; +vardef chem_dashed_connected (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = + draw for i:=from_point upto to_point: + (path_fragment rotated chem_ang(n,i)) if i < to_point : -- fi + endfor withpen pencircle scaled linewidth withcolor linecolor dashed evenly ; +enddef ; +vardef chem_draw_dot (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = + for i:=from_point upto to_point: + draw (path_fragment rotated chem_ang(n,i)) withpen pencircle scaled (chem_dot_factor*linewidth) withcolor linecolor ; + endfor ; +enddef ; +vardef chem_draw_fixed (expr n, path_fragment, linewidth, linecolor) = + draw (path_fragment rotated chem_ang(n,1)) withpen pencircle scaled linewidth withcolor linecolor ; +enddef ; +vardef chem_draw_arrow (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = + for i:=from_point upto to_point: + drawarrow (path_fragment rotated chem_ang(n,i)) withpen pencircle scaled linewidth withcolor linecolor ; + endfor ; +enddef ; +vardef chem_draw_vertical (expr n, path_fragment, from_point, to_point, linewidth, linecolor) = + % quite special + for i:=from_point upto to_point: + draw (path_fragment shifted (chem_b_zero[n] rotated chem_ang(n,i))) withpen pencircle scaled linewidth withcolor linecolor ; + endfor ; +enddef ; + +picture chem_stack_p[] ; +pair chem_stack_shift[] ; + +vardef chem_save = + chem_stack_n := chem_stack_n + 1 ; + chem_stack_p[chem_stack_n] := currentpicture ; + chem_stack_shift[chem_stack_n] := chem_shift ; + chem_shift := origin ; +% chem_adjacent := 0 ; +% chem_substituent := 0 ; +% chem_rotation := 1 ; + currentpicture := nullpicture ; +enddef ; +vardef chem_restore = + if chem_stack_n > 0 : + currentpicture := currentpicture shifted - chem_shift ; + addto chem_stack_p[chem_stack_n] also currentpicture ; + currentpicture := chem_stack_p[chem_stack_n] ; + chem_stack_p[chem_stack_n] := nullpicture ; + chem_shift := chem_stack_shift[chem_stack_n] ; + chem_stack_n := chem_stack_n - 1 ; + fi ; +enddef ; + +def chem_init_some(expr n, ratio, start, initialrot, initialmov) = + chem_width [n] := ratio * chem_base_width * chem_setting_scale ; + chem_angle [n] := 360/abs(n) ; + chem_start [n] := start ; + chem_initialrot[n] := initialrot ; + chem_initialmov[n] := initialmov ; + chem_b_zero [n] := (chem_width[n],0) rotated (chem_angle[n]/2) ; + chem_n_zero [n] := (chem_text_min*chem_width[n],0) rotated (chem_angle[n]/2) ; + chem_r_max [n] := chem_radical_max*chem_b_zero[n] ; + chem_r_path [n] := chem_b_zero[n] -- chem_r_max[n] ; + chem_mr_path [n] := chem_r_path [n] rotatedaround(chem_b_zero[n], (180-chem_angle[n])/2) ; + chem_pr_path [n] := chem_r_path [n] rotatedaround(chem_b_zero[n],-(180-chem_angle[n])/2) ; + chem_r_zero [n] := point 1 of chem_r_path [n] ; + chem_mr_zero [n] := point 1 of chem_mr_path[n] ; + chem_pr_zero [n] := point 1 of chem_pr_path[n] ; + chem_crz_zero [n] := point 1 of (chem_r_path[n] enlonged chem_center_offset) ; + chem_au_path [n] := subpath (0.2,0.8) of (chem_r_max[n] -- (chem_r_max[n] rotated chem_angle[n])) ; + chem_ad_path [n] := reverse(chem_au_path[n]) ; + chem_rt_zero [n] := (((chem_radical_max+chem_radical_min)/2)*chem_width[n],0) rotated (chem_angle[n]/2) ; + chem_rtt_zero [n] := chem_rt_zero[n] rotated + 10 ; + chem_rbt_zero [n] := chem_rt_zero[n] rotated - 10 ; + chem_b_path [n] := reverse(chem_b_zero[n] -- (chem_b_zero[n] rotated -chem_angle[n])) ; + chem_bx_path [n] := reverse(chem_b_zero[n] -- (chem_b_zero[n] rotated -chem_angle[n])) ; % ? + chem_sb_path [n] := subpath (0.25,0.75) of chem_b_path[n] ; + chem_s_path [n] := point 0 of chem_b_path[n] -- point 0 of (chem_b_path[n] rotated (2chem_angle[n])) ; + chem_ss_path [n] := subpath (0.25,0.75) of (chem_s_path[n]) ; + chem_pss_path [n] := subpath (0.00,0.75) of (chem_s_path[n]) ; + chem_mss_path [n] := subpath (0.25,1.00) of (chem_s_path[n]) ; + chem_mid_zero [n] := origin shifted (-.25chem_width[n],0) ; + chem_midst_path[n] := chem_mid_zero[n] -- (chem_width[n],0) rotated ( chem_angle[n] + chem_angle[n]/2) ; + chem_midsb_path[n] := chem_mid_zero[n] -- (chem_width[n],0) rotated (-chem_angle[n] - chem_angle[n]/2) ; + chem_midt_path [n] := subpath (0.25,1.00) of chem_midst_path [n] ; + chem_midb_path [n] := subpath (0.25,1.00) of chem_midsb_path [n] ; + chem_msb_path [n] := subpath (0.00,0.75) of chem_b_path[n] ; + chem_psb_path [n] := subpath (0.25,1.00) of chem_b_path[n] ; + chem_dbl_path [n] := chem_sb_path[n] shifted - (0.05[origin,center chem_sb_path[n]]) ; % parallel + chem_dbr_path [n] := chem_sb_path[n] shifted + (0.05[origin,center chem_sb_path[n]]) ; + chem_eb_path [n] := chem_sb_path[n] shifted - (0.25[origin,center chem_sb_path[n]]) ; + chem_sr_path [n] := chem_radical_min*chem_b_zero[n] -- chem_r_max[n] ; + chem_rl_path [n] := chem_r_path[n] paralleled (chem_base_width/20) ; + chem_rr_path [n] := chem_r_path[n] paralleled -(chem_base_width/20) ; + chem_srl_path [n] := chem_sr_path[n] paralleled (chem_base_width/20) ; + chem_srr_path [n] := chem_sr_path[n] paralleled -(chem_base_width/20) ; + chem_br_path [n] := point 1 of chem_sb_path[n] -- + point 0 of chem_sb_path[n] rotatedaround(point 1 of chem_sb_path[n], -4) -- + point 0 of chem_sb_path[n] rotatedaround(point 1 of chem_sb_path[n], 4) -- cycle ; + chem_rb_path [n] := chem_b_zero[n] -- chem_r_max[n] rotated -2 -- chem_r_max[n] -- chem_r_max[n] rotated 2 -- cycle ; + chem_mrb_path [n] := chem_rb_path[n] rotatedaround(chem_b_zero[n], (180-chem_angle[n])/2) ; + chem_prb_path [n] := chem_rb_path[n] rotatedaround(chem_b_zero[n],-(180-chem_angle[n])/2) ; + chem_msr_path [n] := chem_sr_path[n] rotatedaround(chem_b_zero[n], (180-chem_angle[n])/2) ; + chem_psr_path [n] := chem_sr_path[n] rotatedaround(chem_b_zero[n],-(180-chem_angle[n])/2) ; + % not yet ok: +% chem_c_path [n] := subpath (30/45, -30/45) of (fullcircle scaled (1.25*chem_circle_radius*chem_width[n])); +% chem_cc_path [n] := subpath (30/45,8-30/45) of (fullcircle rotated 90 scaled (1.25*chem_circle_radius*chem_width[n])); + chem_c_path [n] := subpath (30/45, -30/45) of (fullcircle scaled (chem_width[n])); + chem_cc_path [n] := subpath (30/45,8-30/45) of (fullcircle rotated 90 scaled (chem_width[n])); +enddef ; + +def chem_init_three = chem_init_some(3,30/52 ,-60,1,2) ; enddef ; % 60 +def chem_init_four = chem_init_some(4,30/42.5, 0,1,0) ; enddef ; % 45 +def chem_init_five = chem_init_some(5,30/35 , 0,1,0) ; enddef ; % 36 +def chem_init_six = chem_init_some(6, 1 , 0,1,0) ; enddef ; % 30 +def chem_init_eight = chem_init_some(8,30/22.5, 0,1,0) ; enddef ; % 22.5 + +% bb R -R R Z -RZ +RZ + +def chem_init_some_front(expr n, ratio, start, initialrot, initialmov) = + chem_init_some(n, ratio, start, initialrot, initialmov) ; + chem_bb_path [n] := chem_b_path[n] rotated -chem_angle[n] -- chem_b_path[n] -- chem_b_path[n] rotated chem_angle[n] -- + (reverse(chem_b_path[n] shortened (chem_base_width/20))) paralleled (chem_base_width/20) -- + cycle ; + chem_r_max [n] := chem_radical_max*chem_b_zero[n] ; + chem_mr_path [n] := origin -- origin shifted (0,-.25chem_base_width) ; + chem_pr_path [n] := origin -- origin shifted (0, .25*chem_base_width) ; + chem_r_path [n] := point 1 of chem_mr_path[n] -- point 1 of chem_pr_path[n] ; + chem_mr_zero [n] := point 1 of chem_mr_path[n] ; + chem_pr_zero [n] := point 1 of chem_pr_path[n] ; +enddef ; + +def chem_init_five_front = chem_init_some_front(-5,30/35,0,2,0) ; enddef ; % 36 +def chem_init_six_front = chem_init_some_front(-6, 1 ,0,2,0) ; enddef ; % 30 + +vardef chem_init_one = + chem_width [1] := .75 * chem_base_width * chem_setting_scale ; + chem_angle [1] := 360/8 ; + chem_start [1] := 0 ; + chem_initialrot[1] := 1 ; + chem_initialmov[1] := 1 ; + chem_b_zero [1] := (1.75*chem_width[1],0) ; + chem_r_min [1] := chem_radical_min*chem_b_zero[1] ; + chem_r_max [1] := chem_radical_max*chem_b_zero[1] ; + chem_r_path [1] := (.5*chem_width[1],0) -- (1.25*chem_width[1],0) ; + chem_r_zero [1] := point 1 of chem_r_path [1] ; + chem_b_path [1] := chem_r_path[1] rotated + (chem_angle[1]) ; % used for move here + chem_b_zero [1] := chem_r_zero[1] ; + chem_crz_zero [1] := chem_r_zero[1] enlonged chem_center_offset ; + chem_e_path [1] := (.5*chem_width[1],-.25*chem_width[1]) -- (.5*chem_width[1],.25*chem_width[1]) ; + chem_sb_path [1] := chem_r_path [1] ; + chem_msb_path [1] := chem_r_path [1] shifted (0,-.1chem_width[1]) ; + chem_psb_path [1] := chem_r_path [1] shifted (0, .1chem_width[1]) ; + chem_ddt_path [1] := subpath(0,.4) of chem_r_path [1] ; + chem_ddb_path [1] := subpath(.6,1) of chem_r_path [1] ; + chem_ldt_path [1] := chem_ddt_path [1] shifted (0,-.1chem_width[1]) ; % parallel + chem_ldb_path [1] := chem_ddb_path [1] shifted (0,-.1chem_width[1]) ; + chem_rdt_path [1] := chem_ddt_path [1] shifted (0, .1chem_width[1]) ; + chem_rdb_path [1] := chem_ddb_path [1] shifted (0, .1chem_width[1]) ; + save pr ; pair pr[] ; + pr0 := point 0 of chem_r_path[1] ; + pr1 := point 1 of chem_r_path[1] ; + chem_bb_path [1] := pr0 -- (pr1 rotatedaround(pr0,-chem_bb_angle)) -- (pr1 rotatedaround(pr0,chem_bb_angle)) -- cycle ; + chem_oe_path [1] := ((-20,0)--(10,0){up}..(20,10)..(30,0)..(40,-10)..(50.0,0)..(60,10)..(70,0)..(80,-10)..{up}(90,0)--(120,0)) + xsized (.75*chem_width[1]) shifted pr0 ; + chem_rt_zero [1] := point .5 of chem_r_path[1] ; + chem_rtt_zero [1] := chem_rt_zero[1] rotated + (chem_angle[1]/2) ; + chem_rbt_zero [1] := chem_rt_zero[1] rotated - (chem_angle[1]/2) ; + % added by Alan Braslau (adapted to use shared variables): + save p ; pair p[] ; + p0 := pr1 rotatedaround(pr0, -chem_bd_angle) ; + p1 := pr1 rotatedaround(pr0, +chem_bd_angle) ; + p2 := p0 shifted - pr1 ; + p3 := p1 shifted - pr1 ; + chem_bd_path [1] := + p0 -- p1 for i=chem_bd_n downto 0 : + -- p2 shifted (i/chem_bd_n)[pr1,pr0] + -- p3 shifted (i/chem_bd_n)[pr1,pr0] + endfor ; + chem_bw_path [1] := + for i=0 upto chem_bw_n - 1 : + ((i) /chem_bw_n)[pr0,pr1] .. ((i+.25)/chem_bw_n)[pr0,pr1] shifted p2 .. + ((i+.50)/chem_bw_n)[pr0,pr1] .. ((i+.75)/chem_bw_n)[pr0,pr1] shifted -p2 .. + endfor pr1 ; +enddef ; + +def chem_init_all = + chem_init_one ; + chem_init_three ; + chem_init_four ; + chem_init_five ; + chem_init_six ; + chem_init_eight ; + chem_init_five_front ; + chem_init_six_front ; +enddef ; + +chem_init_all ; diff --git a/metapost/context/base/mp-core.mp b/metapost/context/base/mp-core.mp deleted file mode 100644 index 2ccdad22c..000000000 --- a/metapost/context/base/mp-core.mp +++ /dev/null @@ -1,1421 +0,0 @@ - -if unknown context_tool : input mp-tool ; fi ; -if known context_core : endinput ; fi ; - -boolean context_core ; context_core := true ; - -pair lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ; -path pxy[] ; -numeric hxy[], wxy[], dxy[], nxy[] ; - -def box_found (expr n,x,y,w,h,d) = - not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0)) -enddef ; - -def initialize_box_pos (expr pos,n,x,y,w,h,d) = - pair lxy, rxy, cxy, llxy, lrxy, ulxy, urxy ; - path pxy ; numeric hxy, wxy, dxy, nxy; - lxy := (x,y) ; - llxy := (x,y-d) ; - lrxy := (x+w,y-d) ; - urxy := (x+w,y+h) ; - ulxy := (x,y+h) ; - wxy := w ; - hxy := h ; - dxy := d ; - rxy := lxy shifted (wxy,0) ; - pxy := llxy--lrxy--urxy--ulxy--cycle ; - cxy := center pxy ; - nxy := n ; - freeze_box(pos) ; -enddef ; - -def freeze_box (expr pos) = - lxy[pos] := lxy ; - llxy[pos] := llxy ; - lrxy[pos] := lrxy ; - urxy[pos] := urxy ; - ulxy[pos] := ulxy ; - wxy[pos] := wxy ; - hxy[pos] := hxy ; - dxy[pos] := dxy ; - rxy[pos] := rxy ; - pxy[pos] := pxy ; - cxy[pos] := cxy ; - nxy[pos] := nxy ; -enddef ; - -def initialize_box (expr n,x,y,w,h,d) = - - numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ; - -enddef ; - -def initialize_area (expr fn,fx,fy,fw,fh,fd, - tn,tx,ty,tw,th,td) = - - numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; - numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; - - do_initialize_area (fpos, tpos) ; - -enddef ; - -def do_initialize_area (expr fpos, tpos) = - lxy := lxy[fpos] ; - llxy := (xpart llxy[fpos], ypart llxy[tpos]) ; - lrxy := lrxy[tpos] ; - urxy := (xpart urxy[tpos], ypart urxy[fpos]) ; - ulxy := ulxy[fpos] ; - wxy := xpart lrxy - xpart llxy ; - hxy := hxy[fpos] ; - dxy := dxy[tpos] ; - rxy := lxy shifted (wxy,0) ; - pxy := llxy--lrxy--urxy--ulxy--cycle ; - 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, - pn,px,py,pw,ph,pd, - rw,rl,rr,rh,ra,ri) = - - numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; - numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; - numeric mpos ; mpos := 3 ; initialize_box_pos(mpos,mn,mx,my,mw,mh,md) ; - numeric ppos ; ppos := 4 ; initialize_box_pos(ppos,pn,px,py,pw,ph,pd) ; - - numeric par_strut_height, par_strut_depth, par_line_height ; - - set_par_line_height (ph, pd) ; - - do_initialize_area (fpos, tpos) ; - do_initialize_par (fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) ; - -enddef ; - -def initialize_area_par (expr fn,fx,fy,fw,fh,fd, - tn,tx,ty,tw,th,td, - wn,wx,wy,ww,wh,wd) = - - 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 par_strut_height, par_strut_depth, par_line_height ; - - 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) ; - - do_initialize_area (ffpos, ttpos) ; - - numeric mpos ; mpos := 6 ; freeze_box(mpos) ; - - do_initialize_par (fpos, tpos, mpos, ffpos, 0,0,0,0,0,0) ; - -enddef ; - -def do_initialize_par (expr fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) = - - pair lref, rref, pref, lhref, rhref ; - - % clip the page area to the left and right skips - - llxy[mpos] := llxy[mpos] shifted (+rl,0) ; - lrxy[mpos] := lrxy[mpos] shifted (-rr,0) ; - urxy[mpos] := urxy[mpos] shifted (-rr,0) ; - ulxy[mpos] := ulxy[mpos] shifted (+rl,0) ; - - % fixate the leftskip, rightskip and hanging indentation - - lref := (xpart llxy[mpos],ypart ulxy[ppos]) ; lhref := lref shifted (rh,0) ; - rref := (xpart lrxy[mpos],ypart urxy[ppos]) ; rhref := rref shifted (rh,0) ; - - pref := lxy[ppos] ; - - if nxy[tpos] > nxy[fpos] : - if nxy[fpos] = nxy[mpos] : - % first of multiple pages - llxy[tpos] := llxy[mpos] ; - lrxy[tpos] := lrxy[mpos] ; - urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; - ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; - boxgriddirection := down ; - elseif nxy[tpos] = nxy[mpos] : - % last of multiple pages - llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; - lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; - urxy[fpos] := urxy[mpos] ; - ulxy[fpos] := ulxy[mpos] ; - boxgriddirection := up ; - else : - % middle of multiple pages - llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; - lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; - urxy[fpos] := urxy[mpos] ; - ulxy[fpos] := ulxy[mpos] ; - llxy[tpos] := llxy[mpos] ; - lrxy[tpos] := lrxy[mpos] ; - urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; - ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; - boxgriddirection := up ; - fi ; - else : - % just one page - boxgriddirection := up ; - fi ; - - path txy, bxy, pxy, mxy ; - - txy := originpath ; % top - bxy := originpath ; % bottom - pxy := originpath ; % composed - - boolean lefthang, righthang, somehang ; - - % we only hang on the first of a multiple page background - - if nxy[mpos] > nxy[fpos] : - lefthang := righthang := somehang := false ; - else : - lefthang := (rh>0) ; righthang := (rh<0) ; somehang := false ; - fi ; - - if lefthang : - mxy := boundingbox (lref -- lref shifted (rh,ra*par_line_height)) ; - elseif righthang : - mxy := boundingbox (rref -- rref shifted (rh,ra*par_line_height)) ; - else : - mxy := originpath ; - fi ; - - if round(ypart llxy[fpos]) = round(ypart llxy[tpos]) : - - % We have a one-liner. Watch how er use the bottom pos for - % determining the height. - - llxy[fpos] := (xpart llxy[fpos], ypart llxy[tpos]) ; - ulxy[fpos] := (xpart ulxy[fpos], ypart ulxy[tpos]) ; - - else : - - % We have a multi-liner. For convenience we now correct the - % begin and end points for indentation. - - if lefthang and (round(ypart llxy[tpos]) >= round(ypart lrcorner mxy)) : - llxy[tpos] := (xpart lhref, ypart llxy[tpos]) ; - ulxy[tpos] := (xpart lhref, ypart ulxy[tpos]) ; - else : - llxy[tpos] := (xpart lref, ypart llxy[tpos]) ; - ulxy[tpos] := (xpart lref, ypart ulxy[tpos]) ; - fi ; - - if righthang and (round(ypart lrxy[fpos]) >= round(ypart llcorner mxy)) : - lrxy[fpos] := (xpart rhref, ypart lrxy[fpos]) ; - urxy[fpos] := (xpart rhref, ypart urxy[fpos]) ; - else : - lrxy[fpos] := (xpart rref, ypart lrxy[fpos]) ; - urxy[fpos] := (xpart rref, ypart urxy[fpos]) ; - fi ; - - fi ; - - somehang := (ypart ulxy[fpos]>ypart llcorner mxy) and - (ypart llxy[tpos]0 : - left_skip := rl + xpart llxy[wpos] - xpart llxy[ppos] ; - right_skip := rw - left_skip - ww ; - else : - left_skip := rl ; - right_skip := rr ; - fi ; - - path multipar, multipars[] ; - numeric multiref, multirefs[] ; - numeric multiloc, multilocs[] ; % 1=begin 2=between 3=end - - numeric multi_par_pages ; multi_par_pages := nxy[tpos]-nxy[fpos]+1 ; - - % locals .. why can't i move these outside? - -vardef _pmp_set_multipar_ (expr i) = - ( (TextAreas[i] leftenlarged -left_skip) rightenlarged (-right_skip - if auto_multi_par_hsize : + rw - bbwidth(TextAreas[i]) fi) ) -enddef ; - -vardef _pmp_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 ; - -vardef _pmp_estimated_par_lines_ (expr h) = - round(h/par_line_height) -enddef ; - -vardef _pmp_top_multi_par_(expr p) = - (round(_pmp_estimated_par_lines_(bbheight(p)*par_line_height))=round(bbheight(p))) -enddef ; - -vardef _pmp_multi_par_tsc_(expr p) = - if _pmp_top_multi_par_(p) : TopSkipCorrection else : 0 fi -enddef ; - -vardef _pmp_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 + _pmp_estimated_par_lines_(ypart ulxy[fpos] - - ypart llcorner SavedTextAreas[i]) ; - elseif ok : - h := h + _pmp_estimated_par_lines_(bbheight(SavedTextAreas[i])) ; - fi ; - endfor ; - fi ; - if ok : - for i := 1 upto n-1 : - h := h + _pmp_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 + _pmp_estimated_par_lines_(ypart ulxy[fpos] - ypart llcorner TextAreas[i]) ; - elseif ok : - h := h + _pmp_estimated_par_lines_(bbheight(TextAreas[i])) ; - fi ; - endfor ; - fi ; - h - fi -enddef ; - -vardef _pmp_left_top_hang_ (expr same_area) = - - par_hang_after := ra + _pmp_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 _pmp_snapped_multi_pos_(ulxy[fpos])); - pair _pa_ ; _pa_ := _ul_ 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 llxy[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 _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 _pmp_right_top_hang_ (expr same_area) = - - par_hang_after := ra + _pmp_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 _pmp_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 _pmp_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 _pmp_snapped_multi_pos_(urxy[fpos])) - else : - (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) - fi -enddef ; - -vardef _pmp_x_left_top_hang_ (expr i, t) = - par_hang_after := min(0,ra + _pmp_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])0) and (par_hang_after>0) and obey_multi_par_hang : - _ll_ := (xpart ulcorner multipar, ypart _pmp_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 _pmp_right_bottom_hang_ (expr same_area) = - pair _lr_, _sa_, _pa_ ; - _sa_ := if same_area : _pmp_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 _pmp_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 _pmp_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 _pmp_x_left_bottom_hang_ (expr i, t) = - pair _ll_, _sa_, _pa_ ; - _sa_ := if t : llxy[tpos] else : llcorner multipar fi ; - if (par_hang_indent>0) and (ra>0) : - par_hang_after := max(0,ra - _pmp_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 _pmp_x_right_bottom_hang_ (expr i, t) = - pair _lr_, _sa_, _pa_ ; - _sa_ := if t : _pmp_snapped_multi_pos_(ulxy[tpos]) else : llcorner multipar fi ; - if (par_hang_indent<0) and (ra>0) : - par_hang_after := max(0,ra - _pmp_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 _pmp_test_multipar_ = -% multipar := boundingbox multipar ; -% enddef ; - - % first loop - - ii := 0 ; nn := NOfTextAreas+1 ; nofmultipars := 0 ; - - if enable_multi_par_fallback and - (nxy[fpos]=RealPageNumber) and - (nxy[tpos]=RealPageNumber) and not - (InsideSomeTextArea(lxy[fpos]) and - InsideSomeTextArea(rxy[tpos])) : - - % fallback - - % multipar := - % llxy[fpos] -- - % lrxy[tpos] -- - % urxy[tpos] -- - % ulxy[fpos] -- cycle ; - % - % save_multipar (1,1,multipar) ; - - % we need to take the boundingbox because there can be - % more lines and we want a proper rectange - - multipar := - ulxy[fpos] -- - urxy[tpos] -- - lrxy[fpos] -- - llxy[tpos] -- cycle ; - - save_multipar (1,1,boundingbox(multipar)) ; - - else : - - % normal - - for i=1 upto NOfTextAreas : - - TopSkipCorrection := 0 ; - - multipar := _pmp_set_multipar_(i) ; - - % 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])) : - if (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) : - - % in same area - - nn := i ; - - if compensate_multi_par_topskip and (round(LineHeight-ph-pd)=0) : - - 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] -- - _pmp_snapped_multi_pos_(urxy[tpos]) -- - %ulxy[fpos] -- - _pmp_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 : - - _pmp_right_bottom_hang_(true) -- - _pmp_right_top_hang_(true) -- - _pmp_snapped_multi_pos_(urxy[fpos]) -- - lrxy[fpos] -- - - else : - - llxy[fpos] -- - (xpart urcorner multipar, ypart llxy[fpos]) -- - (xpart urcorner multipar, ypart ulxy[fpos]) -- - _pmp_snapped_multi_pos_(ulxy[fpos]) -- - - fi cycle ; - - save_multipar (i,1,multipar) ; - - multipar := _pmp_set_multipar_(i) ; - - multipar := if obey_multi_par_hang : - - _pmp_left_bottom_hang_(true) -- - llxy[tpos] -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - _pmp_left_top_hang_(true) -- - - else : - - (xpart llcorner multipar, ypart llxy[tpos]) -- - llxy[tpos] -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - (xpart llcorner multipar, ypart ulxy[tpos]) -- - - fi cycle ; - - save_multipar (i,1,multipar) ; - - else : - - multipar := if obey_multi_par_hang : - - _pmp_left_bottom_hang_(true) -- - llxy[tpos] -- - %ulxy[tpos] -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - _pmp_right_bottom_hang_(true) -- - _pmp_right_top_hang_(true) -- - %urxy[fpos] -- - _pmp_snapped_multi_pos_(urxy[fpos]) -- - lrxy[fpos] -- - _pmp_left_top_hang_(true) -- - - else : - - (xpart llcorner multipar, ypart llxy[tpos]) -- - llxy[tpos] -- - %ulxy[tpos] -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - (xpart lrcorner multipar, ypart ulxy[tpos]) -- - (xpart urcorner multipar, ypart urxy[fpos]) -- - %urxy[fpos] -- - _pmp_snapped_multi_pos_(urxy[fpos]) -- - lrxy[fpos] -- - (xpart ulcorner multipar, ypart lrxy[fpos]) -- - - fi cycle ; - - save_multipar (i,1,multipar) ; - - fi ; - - else : - - multipar := if obey_multi_par_hang : - - _pmp_left_bottom_hang_(false) -- - _pmp_right_bottom_hang_(false) -- - _pmp_right_top_hang_(false) -- - %urxy[fpos] -- - _pmp_snapped_multi_pos_(urxy[fpos]) -- - lrxy[fpos] -- - _pmp_left_top_hang_(false) -- - - else : - - llcorner multipar -- - lrcorner multipar -- - (xpart urcorner multipar, ypart urxy[fpos]) -- - %urxy[fpos] -- - _pmp_snapped_multi_pos_(urxy[fpos]) -- - lrxy[fpos] -- - (xpart ulcorner multipar, ypart lrxy[fpos]) -- - - fi cycle ; - - save_multipar (i,1,multipar) ; - - fi ; - -% elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,llxy[tpos])) : - elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) : - - % last one in chain - - nn := i ; - - if obey_multi_par_hang and obey_multi_par_more : - - multipar := - _pmp_x_left_top_hang_(i,true) -- - _pmp_x_right_top_hang_(i,true) -- - _pmp_x_right_bottom_hang_(i,true) -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - llxy[tpos] -- - _pmp_x_left_bottom_hang_(i,true) -- - cycle ; - - else : - - multipar := - ulcorner multipar -- - urcorner multipar -- - (xpart lrcorner multipar, ypart urxy[tpos]) -- - _pmp_snapped_multi_pos_(ulxy[tpos]) -- - llxy[tpos] -- - (xpart llcorner multipar, ypart llxy[tpos]) -- - cycle ; - - fi ; - - save_multipar (i,3,multipar) ; - - elseif multi_column_first_page_hack and ((nxy[fpos]=RealPageNumber) and (nxy[tpos]>=RealPageNumber) and (NOfTextColumns>1)) : - - save_multipar (i,2,multipar) ; - - else : - % handled later - fi ; - - endfor ; - - % second loop - - if force_multi_par_chain or (ii > 1) : - - for i=ii+1 upto nn-1 : - - % rest of chain / todo : hang - -% hm, the second+ column in column sets now gets lost in a NOfTextColumns - - if (not check_multi_par_chain) or - ((nxy[fpos]RealPageNumber)) - : - - multipar := _pmp_set_multipar_(i) ; - - if obey_multi_par_hang and obey_multi_par_more : - - multipar := - _pmp_x_left_top_hang_(i,false) -- - _pmp_x_right_top_hang_(i,false) -- - _pmp_x_right_bottom_hang_(i,false) -- - _pmp_x_left_bottom_hang_(i,false) -- - cycle ; - - fi ; - - save_multipar(i,2,multipar) ; - - fi ; - - endfor ; - - fi ; - - % end of normal/fallback - -fi ; - - if span_multi_column_pars : - endgroup ; - fi ; - - % potential safeguard: - - % for i=1 upto nofmultipars : - % if length p <= 4 : - % multipars[i] := boundingbox(multipars[i]) ; - % fi ; - % end ; - - % quick hack for gb: - - one_piece_multi_par := (nofmultipars=1) and (pn=tn) ; - -enddef ; - -color boxgridcolor ; boxgridcolor := .8red ; -color boxlinecolor ; boxlinecolor := .8blue ; -color boxfillcolor ; boxfillcolor := .8white ; -numeric boxgridtype ; boxgridtype := 0 ; -numeric boxlinetype ; boxlinetype := 1 ; -numeric boxfilltype ; boxfilltype := 1 ; -numeric boxdashtype ; boxdashtype := 0 ; -pair boxgriddirection ; boxgriddirection := up ; -numeric boxgridwidth ; boxgridwidth := 1pt ; -numeric boxlinewidth ; boxlinewidth := 1pt ; -numeric boxlineradius ; boxlineradius := 0pt ; -numeric boxfilloffset ; boxfilloffset := 0pt ; -numeric boxgriddistance ; boxgriddistance := .5cm ; -numeric boxgridshift ; boxgridshift := 0pt ; - -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 3 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 = 3 : - boxgriddirection := origin ; - draw baseline_grid (i,boxgriddirection,true ) withcolor boxgridcolor ; - draw baseline_grid (i,boxgriddirection,true ) - shifted (0,ExHeight) withcolor boxgridcolor ; - elseif boxgridtype = 4 : - boxgriddirection := origin ; - draw baseline_grid (i,boxgriddirection,true ) - shifted (0,ExHeight/2) withcolor boxgridcolor ; - elseif boxgridtype = 11 : - draw graphic_grid(i,boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; - elseif boxgridtype = 12 : - draw graphic_grid(i,boxgriddistance,boxgriddistance,0,0) ; - fi ; - endfor ; -enddef ; - -def do_show_par (expr p, r, c) = - if length(p) > 2 : for i=0 upto length(p) : - draw fullcircle scaled r shifted point i of p - withpen pencircle scaled .5pt withcolor c ; - endfor ; fi ; - draw p withpen pencircle scaled .5pt withcolor c ; -enddef ; - -def show_par = - if length(mxy) > 2 : - draw mxy dashed evenly - withpen pencircle scaled .5pt withcolor .5white ; - fi ; - do_show_par(txy, 4pt, .5green) ; - do_show_par(bxy, 6pt, .5blue ) ; - do_show_par(pxy, 8pt, .5red ) ; - draw pref withpen pencircle scaled 2pt ; -enddef ; - -def sort_multi_pars = - if nofmultipars>1 : - begingroup ; save _p_, _n_ ; path _p_ ; numeric _n_ ; - for i := 1 upto nofmultipars : - if multilocs[i] = 3 : - _p_ := multipars[nofmultipars] ; - multipars[nofmultipars] := multipars[i] ; - multipars[i] := _p_ ; - _n_ := multirefs[nofmultipars] ; - multirefs[nofmultipars] := multirefs[i] ; - multirefs[i] := _n_ ; - _n_ := multilocs[nofmultipars] ; - multilocs[nofmultipars] := multilocs[i] ; - multilocs[i] := _n_ ; - fi ; - endfor ; - endgroup ; - fi ; -enddef ; - - -def collapse_multi_pars = - if nofmultipars>1 : - begingroup ; save _nofmultipars_ ; numeric _nofmultipars_ ; - _nofmultipars_ := 1 ; - sort_multi_pars ; % block not in order: 1, 3, 2.... - for i:=1 upto nofmultipars-1 : - if (round(xpart(llcorner multipars[i]-llcorner multipars[i+1]))=0) and - (round(xpart(lrcorner multipars[i]-lrcorner multipars[i+1]))=0) : -multilocs[_nofmultipars_] := multilocs[i+1] ; -multirefs[_nofmultipars_] := multirefs[i+1] ; - multipars[_nofmultipars_] := - ulcorner multipars[_nofmultipars_] -- - urcorner multipars[_nofmultipars_] -- - lrcorner multipars[i+1] -- - llcorner multipars[i+1] -- cycle ; - else : - _nofmultipars_ := _nofmultipars_ + 1 ; - multipars[_nofmultipars_] := multipars[i+1] ; - multilocs[_nofmultipars_] := multilocs[i+1] ; - multirefs[_nofmultipars_] := multirefs[i+1] ; - fi ; - endfor ; - nofmultipars := _nofmultipars_ ; - endgroup ; - fi ; -enddef ; - -% def draw_multi_pars = -% for i=1 upto nofmultipars : -% do_draw_par(multipars[i]) ; -% if boxgridtype= 1 : -% draw baseline_grid (multipars[i],up,true ) ; % withcolor boxgridcolor ; -% elseif boxgridtype= 2 : -% draw baseline_grid (multipars[i],up,false) ; % withcolor boxgridcolor ; -% elseif boxgridtype= 3 : -% draw baseline_grid (multipars[i],up,true ) ; % withcolor boxgridcolor ; -% draw baseline_grid (multipars[i],up,true ) -% shifted (0,ExHeight) ; % withcolor boxgridcolor ; -% elseif boxgridtype= 4 : -% draw baseline_grid (multipars[i],up,true ) -% shifted (0,ExHeight/2) ; % withcolor boxgridcolor ; -% elseif boxgridtype=11 : -% 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 ; - -def draw_multi_pars = - for i=1 upto nofmultipars : - do_draw_par(multipars[i]) ; - if boxgridtype= 1 : - draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; % withcolor boxgridcolor ; - elseif boxgridtype= 2 : - draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,false) ; % withcolor boxgridcolor ; - elseif boxgridtype= 3 : - draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; % withcolor boxgridcolor ; - draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight) ; % withcolor boxgridcolor ; - elseif boxgridtype= 4 : - draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight/2) ; % withcolor boxgridcolor ; - elseif boxgridtype=11 : - 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 ; - -def show_multi_pars = - for i=1 upto nofmultipars : - do_show_par(multipars[i], 6pt, .5blue) ; - endfor ; -enddef ; - -vardef do_draw_par (expr p) = - if (length p>2) and (bbwidth(p)>1) and (bbheight(p)>1) : - save pp ; path pp ; - if (boxlineradius>0) and (boxlinetype=2) : - pp := p cornered boxlineradius ; - else : - pp := p ; - fi ; - if boxfilltype>0 : - if boxfilloffset>0 : - % temporary hack - begingroup ; interim linejoin := mitered ; - filldraw pp withcolor boxfillcolor withpen pencircle scaled (2*boxfilloffset) ; - endgroup ; - else : - fill pp withcolor boxfillcolor ; - fi ; - fi ; - if boxlinetype>0 : - draw pp withcolor boxlinecolor withpen pencircle scaled boxlinewidth ; - fi ; - fi ; -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 i, grid, bb ; picture grid ; pair start ; path bb ; - def _do_ (expr start) = - % 1 = normal, 2 = with background (i.e. no shine-through) - if boxdashtype = 2 : - draw start -- start shifted (bbwidth(pxy),0) - withpen pencircle scaled boxgridwidth - withcolor boxfillcolor ; - fi ; - draw start -- start shifted (bbwidth(pxy),0) - if boxdashtype > 0 : dashed evenly fi - 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 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) : - _do_ (ulcorner pxy shifted (0,-i)) ; - endfor ; - fi ; - ) ; - clip grid to pxy ; - bb := boundingbox grid ; - grid := grid shifted (0,boxgridshift) ; - setbounds grid to bb ; - grid - else : - nullpicture - fi -enddef ; - -vardef graphic_grid (expr pxy, dx, dy, x, y) = - if (bbheight(pxy)>dy) and (bbwidth(pxy)>dx) and (boxgridwidth>0) : - save grid ; picture grid ; - grid := image - ( for i = xpart llcorner pxy step dx until xpart lrcorner pxy : - draw (i,ypart llcorner pxy) -- (i,ypart ulcorner pxy) - withpen pencircle scaled boxgridwidth ; - endfor ; - for i = ypart llcorner pxy step dy until ypart ulcorner pxy : - draw (xpart llcorner pxy,i) -- (xpart lrcorner pxy,i) - withpen pencircle scaled boxgridwidth ; - endfor ) shifted (x,y) ; - clip grid to pxy ; - grid - else : - nullpicture - fi -enddef ; - -def anchor_box (expr n,x,y,w,h,d) = - currentpicture := currentpicture shifted (-x,-y) ; -enddef ; - -let draw_area = draw_box ; -let anchor_area = anchor_box ; -let anchor_par = anchor_box ; - - -numeric sync_n[], sync_p[][], sync_w[][], sync_h[][], sync_d[][], sync_t[][] ; -pair sync_xy[][] ; color sync_c[][] ; - -def ResetSyncTasks = - path SyncPaths[] ; numeric SyncTasks[], NOfSyncPaths, CurrentSyncClass ; - NOfSyncPaths := CurrentSyncClass := 0 ; - if unknown SyncLeftOffset : numeric SyncLeftOffset ; SyncLeftOffset := 0 ; fi ; - if unknown SyncWidth : numeric SyncWidth ; SyncWidth := 0 ; fi ; - if unknown SyncThreshold : numeric SyncThreshold ; SyncThreshold := LineHeight ; fi ; - if unknown SyncColor : color SyncColor ; SyncColor := .5white ; fi ; - if (SyncLeftOffset = 0) and (SyncWidth = 0) : - SyncWidth := if known TextWidth : TextWidth else : -1cm fi ; - fi ; -enddef ; - -ResetSyncTasks ; - -vardef SyncBox(expr n, i, leftoffset, width, topoffset, bottomoffset) = - save o ; pair o ; o := (xpart llcorner PlainTextArea,ypart sync_xy[n][i]) ; - o shifted (leftoffset,sync_h[n][i]+topoffset) -- - o shifted (width+leftoffset,sync_h[n][i]+topoffset) -- - o shifted (width+leftoffset,bottomoffset) -- - o shifted (leftoffset,bottomoffset) -- cycle -enddef ; - -def SetSyncColor(expr n, i, c) = - sync_c[n][i] := c ; -enddef ; - -def SetSyncThreshold(expr n, i, th) = - sync_th[n][i] := th ; -enddef ; - -vardef TheSyncColor(expr n, i) = - if known sync_c[n][i] : sync_c[n][i] else : SyncColor fi -enddef ; - -vardef TheSyncThreshold(expr n, i) = - if known sync_th[n][i] : sync_th[n][i] else : SyncThreshold fi -enddef ; - -vardef PrepareSyncTasks(expr n, collapse, extendtop, prestartnext) = - ResetSyncTasks ; - if known sync_n[n] : - CurrentSyncClass := n ; - save ok, l, d ; boolean ok ; ok := false ; NOfSyncPaths := l := 0 ; - for i=1 upto sync_n[n] : - if RealPageNumber > sync_p[n][i] : - l := i ; - elseif RealPageNumber = sync_p[n][i] : - NOfSyncPaths := NOfSyncPaths + 1 ; - if not ok : - if i>1 : - if sync_t[n][i-1] = sync_t[n][i] : - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - else : - SyncPaths[NOfSyncPaths] := SyncBox(n, i-1, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i-1 ; - NOfSyncPaths := NOfSyncPaths + 1 ; - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - fi ; - else : - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - fi ; - else : - SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := i ; - fi ; - ok := true ; - fi ; - endfor ; - if (NOfSyncPaths = 0) and (l > 0) : - NOfSyncPaths := 1 ; - SyncPaths[NOfSyncPaths] := SyncBox(n, l, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; - SyncTasks[NOfSyncPaths] := l ; - fi ; - if NOfSyncPaths > 0 : - for i = 1 upto NOfSyncPaths-1 : - SyncPaths[i] := topboundary SyncPaths[i] -- reverse topboundary SyncPaths[i+1] -- cycle ; - endfor ; - if unknown SyncThresholdMethod : - numeric SyncThresholdMethod ; SyncThresholdMethod := 2 ; - fi ; - if extendtop : - if SyncThresholdMethod = 1 : - if NOfSyncPaths>1 : - d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[2]]) ; - if (SyncTasks[2]>1) and (d > 0pt) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[2]])) and (sync_p[n][SyncTasks[2]] = RealPageNumber) : - SyncPaths[2] := SyncPaths[2] topenlarged PaperHeight ; - fi ; - fi ; - else : - for i = 1 upto NOfSyncPaths : - d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[i]]) ; - if (d > 0) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[i]] = RealPageNumber) : - SyncPaths[i] := SyncPaths[i] topenlarged PaperHeight ; - fi ; - endfor ; - fi ; - fi ; - if prestartnext : - if NOfSyncPaths>1 : - if SyncTasks[NOfSyncPaths] < sync_n[n] : % there is a next one - d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[NOfSyncPaths]+1]) ; - if (d > 0) and (d <= TheSyncThreshold(n, sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[NOfSyncPaths]+1] = RealPageNumber+1) : - SyncPaths[NOfSyncPaths+1] := - (xpart ulcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- - (xpart urcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- - lrcorner SyncPaths[NOfSyncPaths] -- - llcorner SyncPaths[NOfSyncPaths] -- cycle ; - SyncTasks[NOfSyncPaths+1] := SyncTasks[NOfSyncPaths]+1 ; - NOfSyncPaths := NOfSyncPaths + 1 ; - fi ; - fi ; - fi ; - else : - if NOfSyncPaths>1 : - d := ypart (sync_xy[n][SyncTasks[NOfSyncPaths]] - llcorner PlainTextArea) ; - if (d < TheSyncThreshold(n, SyncTasks[NOfSyncPaths])) : - NOfSyncPaths := NOfSyncPaths - 1 ; - SyncPaths[NOfSyncPaths] := SyncPaths[NOfSyncPaths] bottomenlarged PaperHeight ; - fi ; - fi ; - fi ; - if (NOfSyncPaths>1) and collapse : - save j ; numeric j ; j := 1 ; - for i = 2 upto NOfSyncPaths : - if sync_t[n][SyncTasks[i]] = sync_t[n][SyncTasks[j]] : - SyncPaths[j] := boundingbox image (draw SyncPaths[i] ; draw SyncPaths[j] ; ) ; - SyncTasks[j] := SyncTasks[i] ; - else : - j := j + 1 ; - SyncPaths[j] := SyncPaths[i] ; - SyncTasks[j] := SyncTasks[i] ; - fi ; - endfor ; - NOfSyncPaths := j ; - fi ; - fi ; - fi ; -enddef ; - -def SyncTask(expr n) = - if known SyncTasks[n] : SyncTasks[n] else : 0 fi -enddef ; - -def FlushSyncTasks = - for i = 1 upto NOfSyncPaths : - ProcessSyncTask(SyncPaths[i], TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]])) ; - endfor ; -enddef ; - -def ProcessSyncTask(expr p, c) = - fill p withcolor c ; -enddef ; - -endinput ; - -end - -% for Jelle Huisman -% -% \setupcolors[state=start] -% \dontcomplain -% \definecolumnset[example][n=3,distance=5mm] -% \startMPextensions -% multi_column_first_page_hack := true ; -% \stopMPextensions -% \startuseMPgraphic{mpos:par:trick} -% for i=1 upto nofmultipars-1 : draw (rightboundary multipars[i]) shifted (2.5mm, 0) ; endfor ; -% \stopuseMPgraphic -% \definetextbackground[test][mp=mpos:par:trick,method=mpos:par:columnset] -% \starttext -% \definecolumnsetspan[chapter][n=3] -% \startcolumnset[example] -% \startcolumnsetspan[chapter] -% \chapter{Chapter One} -% \stopcolumnsetspan -% \starttextbackground[test] \dorecurse {3}{\input knuth } \stoptextbackground -% \stopcolumnset -% \startcolumnset[example] -% \startcolumnsetspan[chapter] -% \chapter{Chapter One} -% \stopcolumnsetspan -% \starttextbackground[test] \dorecurse {10}{\input knuth } \stoptextbackground -% \stopcolumnset -% \stoptext -% -% fast variant: -% -% \startuseMPgraphic{whatever} -% for i=1 upto NOfTextColumns-1 : -% draw (rightboundary TextColumns[i]) shifted (2.5mm,0) shifted -\MPxy\textanchor ; -% endfor ; -% setbounds currentpicture to OverlayBox ; -% \stopuseMPgraphic -% \defineoverlay[whatever][\useMPgraphic{whatever}] -% \setupbackgrounds[text][background=whatever] diff --git a/metapost/context/base/mp-core.mpii b/metapost/context/base/mp-core.mpii new file mode 100644 index 000000000..2ccdad22c --- /dev/null +++ b/metapost/context/base/mp-core.mpii @@ -0,0 +1,1421 @@ + +if unknown context_tool : input mp-tool ; fi ; +if known context_core : endinput ; fi ; + +boolean context_core ; context_core := true ; + +pair lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ; +path pxy[] ; +numeric hxy[], wxy[], dxy[], nxy[] ; + +def box_found (expr n,x,y,w,h,d) = + not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0)) +enddef ; + +def initialize_box_pos (expr pos,n,x,y,w,h,d) = + pair lxy, rxy, cxy, llxy, lrxy, ulxy, urxy ; + path pxy ; numeric hxy, wxy, dxy, nxy; + lxy := (x,y) ; + llxy := (x,y-d) ; + lrxy := (x+w,y-d) ; + urxy := (x+w,y+h) ; + ulxy := (x,y+h) ; + wxy := w ; + hxy := h ; + dxy := d ; + rxy := lxy shifted (wxy,0) ; + pxy := llxy--lrxy--urxy--ulxy--cycle ; + cxy := center pxy ; + nxy := n ; + freeze_box(pos) ; +enddef ; + +def freeze_box (expr pos) = + lxy[pos] := lxy ; + llxy[pos] := llxy ; + lrxy[pos] := lrxy ; + urxy[pos] := urxy ; + ulxy[pos] := ulxy ; + wxy[pos] := wxy ; + hxy[pos] := hxy ; + dxy[pos] := dxy ; + rxy[pos] := rxy ; + pxy[pos] := pxy ; + cxy[pos] := cxy ; + nxy[pos] := nxy ; +enddef ; + +def initialize_box (expr n,x,y,w,h,d) = + + numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ; + +enddef ; + +def initialize_area (expr fn,fx,fy,fw,fh,fd, + tn,tx,ty,tw,th,td) = + + numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; + numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; + + do_initialize_area (fpos, tpos) ; + +enddef ; + +def do_initialize_area (expr fpos, tpos) = + lxy := lxy[fpos] ; + llxy := (xpart llxy[fpos], ypart llxy[tpos]) ; + lrxy := lrxy[tpos] ; + urxy := (xpart urxy[tpos], ypart urxy[fpos]) ; + ulxy := ulxy[fpos] ; + wxy := xpart lrxy - xpart llxy ; + hxy := hxy[fpos] ; + dxy := dxy[tpos] ; + rxy := lxy shifted (wxy,0) ; + pxy := llxy--lrxy--urxy--ulxy--cycle ; + 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, + pn,px,py,pw,ph,pd, + rw,rl,rr,rh,ra,ri) = + + numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; + numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; + numeric mpos ; mpos := 3 ; initialize_box_pos(mpos,mn,mx,my,mw,mh,md) ; + numeric ppos ; ppos := 4 ; initialize_box_pos(ppos,pn,px,py,pw,ph,pd) ; + + numeric par_strut_height, par_strut_depth, par_line_height ; + + set_par_line_height (ph, pd) ; + + do_initialize_area (fpos, tpos) ; + do_initialize_par (fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) ; + +enddef ; + +def initialize_area_par (expr fn,fx,fy,fw,fh,fd, + tn,tx,ty,tw,th,td, + wn,wx,wy,ww,wh,wd) = + + 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 par_strut_height, par_strut_depth, par_line_height ; + + 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) ; + + do_initialize_area (ffpos, ttpos) ; + + numeric mpos ; mpos := 6 ; freeze_box(mpos) ; + + do_initialize_par (fpos, tpos, mpos, ffpos, 0,0,0,0,0,0) ; + +enddef ; + +def do_initialize_par (expr fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) = + + pair lref, rref, pref, lhref, rhref ; + + % clip the page area to the left and right skips + + llxy[mpos] := llxy[mpos] shifted (+rl,0) ; + lrxy[mpos] := lrxy[mpos] shifted (-rr,0) ; + urxy[mpos] := urxy[mpos] shifted (-rr,0) ; + ulxy[mpos] := ulxy[mpos] shifted (+rl,0) ; + + % fixate the leftskip, rightskip and hanging indentation + + lref := (xpart llxy[mpos],ypart ulxy[ppos]) ; lhref := lref shifted (rh,0) ; + rref := (xpart lrxy[mpos],ypart urxy[ppos]) ; rhref := rref shifted (rh,0) ; + + pref := lxy[ppos] ; + + if nxy[tpos] > nxy[fpos] : + if nxy[fpos] = nxy[mpos] : + % first of multiple pages + llxy[tpos] := llxy[mpos] ; + lrxy[tpos] := lrxy[mpos] ; + urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; + ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; + boxgriddirection := down ; + elseif nxy[tpos] = nxy[mpos] : + % last of multiple pages + llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; + lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; + urxy[fpos] := urxy[mpos] ; + ulxy[fpos] := ulxy[mpos] ; + boxgriddirection := up ; + else : + % middle of multiple pages + llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; + lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; + urxy[fpos] := urxy[mpos] ; + ulxy[fpos] := ulxy[mpos] ; + llxy[tpos] := llxy[mpos] ; + lrxy[tpos] := lrxy[mpos] ; + urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; + ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; + boxgriddirection := up ; + fi ; + else : + % just one page + boxgriddirection := up ; + fi ; + + path txy, bxy, pxy, mxy ; + + txy := originpath ; % top + bxy := originpath ; % bottom + pxy := originpath ; % composed + + boolean lefthang, righthang, somehang ; + + % we only hang on the first of a multiple page background + + if nxy[mpos] > nxy[fpos] : + lefthang := righthang := somehang := false ; + else : + lefthang := (rh>0) ; righthang := (rh<0) ; somehang := false ; + fi ; + + if lefthang : + mxy := boundingbox (lref -- lref shifted (rh,ra*par_line_height)) ; + elseif righthang : + mxy := boundingbox (rref -- rref shifted (rh,ra*par_line_height)) ; + else : + mxy := originpath ; + fi ; + + if round(ypart llxy[fpos]) = round(ypart llxy[tpos]) : + + % We have a one-liner. Watch how er use the bottom pos for + % determining the height. + + llxy[fpos] := (xpart llxy[fpos], ypart llxy[tpos]) ; + ulxy[fpos] := (xpart ulxy[fpos], ypart ulxy[tpos]) ; + + else : + + % We have a multi-liner. For convenience we now correct the + % begin and end points for indentation. + + if lefthang and (round(ypart llxy[tpos]) >= round(ypart lrcorner mxy)) : + llxy[tpos] := (xpart lhref, ypart llxy[tpos]) ; + ulxy[tpos] := (xpart lhref, ypart ulxy[tpos]) ; + else : + llxy[tpos] := (xpart lref, ypart llxy[tpos]) ; + ulxy[tpos] := (xpart lref, ypart ulxy[tpos]) ; + fi ; + + if righthang and (round(ypart lrxy[fpos]) >= round(ypart llcorner mxy)) : + lrxy[fpos] := (xpart rhref, ypart lrxy[fpos]) ; + urxy[fpos] := (xpart rhref, ypart urxy[fpos]) ; + else : + lrxy[fpos] := (xpart rref, ypart lrxy[fpos]) ; + urxy[fpos] := (xpart rref, ypart urxy[fpos]) ; + fi ; + + fi ; + + somehang := (ypart ulxy[fpos]>ypart llcorner mxy) and + (ypart llxy[tpos]0 : + left_skip := rl + xpart llxy[wpos] - xpart llxy[ppos] ; + right_skip := rw - left_skip - ww ; + else : + left_skip := rl ; + right_skip := rr ; + fi ; + + path multipar, multipars[] ; + numeric multiref, multirefs[] ; + numeric multiloc, multilocs[] ; % 1=begin 2=between 3=end + + numeric multi_par_pages ; multi_par_pages := nxy[tpos]-nxy[fpos]+1 ; + + % locals .. why can't i move these outside? + +vardef _pmp_set_multipar_ (expr i) = + ( (TextAreas[i] leftenlarged -left_skip) rightenlarged (-right_skip + if auto_multi_par_hsize : + rw - bbwidth(TextAreas[i]) fi) ) +enddef ; + +vardef _pmp_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 ; + +vardef _pmp_estimated_par_lines_ (expr h) = + round(h/par_line_height) +enddef ; + +vardef _pmp_top_multi_par_(expr p) = + (round(_pmp_estimated_par_lines_(bbheight(p)*par_line_height))=round(bbheight(p))) +enddef ; + +vardef _pmp_multi_par_tsc_(expr p) = + if _pmp_top_multi_par_(p) : TopSkipCorrection else : 0 fi +enddef ; + +vardef _pmp_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 + _pmp_estimated_par_lines_(ypart ulxy[fpos] - + ypart llcorner SavedTextAreas[i]) ; + elseif ok : + h := h + _pmp_estimated_par_lines_(bbheight(SavedTextAreas[i])) ; + fi ; + endfor ; + fi ; + if ok : + for i := 1 upto n-1 : + h := h + _pmp_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 + _pmp_estimated_par_lines_(ypart ulxy[fpos] - ypart llcorner TextAreas[i]) ; + elseif ok : + h := h + _pmp_estimated_par_lines_(bbheight(TextAreas[i])) ; + fi ; + endfor ; + fi ; + h + fi +enddef ; + +vardef _pmp_left_top_hang_ (expr same_area) = + + par_hang_after := ra + _pmp_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 _pmp_snapped_multi_pos_(ulxy[fpos])); + pair _pa_ ; _pa_ := _ul_ 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 llxy[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 _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 _pmp_right_top_hang_ (expr same_area) = + + par_hang_after := ra + _pmp_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 _pmp_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 _pmp_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 _pmp_snapped_multi_pos_(urxy[fpos])) + else : + (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) + fi +enddef ; + +vardef _pmp_x_left_top_hang_ (expr i, t) = + par_hang_after := min(0,ra + _pmp_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])0) and (par_hang_after>0) and obey_multi_par_hang : + _ll_ := (xpart ulcorner multipar, ypart _pmp_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 _pmp_right_bottom_hang_ (expr same_area) = + pair _lr_, _sa_, _pa_ ; + _sa_ := if same_area : _pmp_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 _pmp_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 _pmp_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 _pmp_x_left_bottom_hang_ (expr i, t) = + pair _ll_, _sa_, _pa_ ; + _sa_ := if t : llxy[tpos] else : llcorner multipar fi ; + if (par_hang_indent>0) and (ra>0) : + par_hang_after := max(0,ra - _pmp_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 _pmp_x_right_bottom_hang_ (expr i, t) = + pair _lr_, _sa_, _pa_ ; + _sa_ := if t : _pmp_snapped_multi_pos_(ulxy[tpos]) else : llcorner multipar fi ; + if (par_hang_indent<0) and (ra>0) : + par_hang_after := max(0,ra - _pmp_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 _pmp_test_multipar_ = +% multipar := boundingbox multipar ; +% enddef ; + + % first loop + + ii := 0 ; nn := NOfTextAreas+1 ; nofmultipars := 0 ; + + if enable_multi_par_fallback and + (nxy[fpos]=RealPageNumber) and + (nxy[tpos]=RealPageNumber) and not + (InsideSomeTextArea(lxy[fpos]) and + InsideSomeTextArea(rxy[tpos])) : + + % fallback + + % multipar := + % llxy[fpos] -- + % lrxy[tpos] -- + % urxy[tpos] -- + % ulxy[fpos] -- cycle ; + % + % save_multipar (1,1,multipar) ; + + % we need to take the boundingbox because there can be + % more lines and we want a proper rectange + + multipar := + ulxy[fpos] -- + urxy[tpos] -- + lrxy[fpos] -- + llxy[tpos] -- cycle ; + + save_multipar (1,1,boundingbox(multipar)) ; + + else : + + % normal + + for i=1 upto NOfTextAreas : + + TopSkipCorrection := 0 ; + + multipar := _pmp_set_multipar_(i) ; + + % 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])) : + if (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) : + + % in same area + + nn := i ; + + if compensate_multi_par_topskip and (round(LineHeight-ph-pd)=0) : + + 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] -- + _pmp_snapped_multi_pos_(urxy[tpos]) -- + %ulxy[fpos] -- + _pmp_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 : + + _pmp_right_bottom_hang_(true) -- + _pmp_right_top_hang_(true) -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + + else : + + llxy[fpos] -- + (xpart urcorner multipar, ypart llxy[fpos]) -- + (xpart urcorner multipar, ypart ulxy[fpos]) -- + _pmp_snapped_multi_pos_(ulxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + multipar := _pmp_set_multipar_(i) ; + + multipar := if obey_multi_par_hang : + + _pmp_left_bottom_hang_(true) -- + llxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + _pmp_left_top_hang_(true) -- + + else : + + (xpart llcorner multipar, ypart llxy[tpos]) -- + llxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + (xpart llcorner multipar, ypart ulxy[tpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + else : + + multipar := if obey_multi_par_hang : + + _pmp_left_bottom_hang_(true) -- + llxy[tpos] -- + %ulxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + _pmp_right_bottom_hang_(true) -- + _pmp_right_top_hang_(true) -- + %urxy[fpos] -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + _pmp_left_top_hang_(true) -- + + else : + + (xpart llcorner multipar, ypart llxy[tpos]) -- + llxy[tpos] -- + %ulxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + (xpart lrcorner multipar, ypart ulxy[tpos]) -- + (xpart urcorner multipar, ypart urxy[fpos]) -- + %urxy[fpos] -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + (xpart ulcorner multipar, ypart lrxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + fi ; + + else : + + multipar := if obey_multi_par_hang : + + _pmp_left_bottom_hang_(false) -- + _pmp_right_bottom_hang_(false) -- + _pmp_right_top_hang_(false) -- + %urxy[fpos] -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + _pmp_left_top_hang_(false) -- + + else : + + llcorner multipar -- + lrcorner multipar -- + (xpart urcorner multipar, ypart urxy[fpos]) -- + %urxy[fpos] -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + (xpart ulcorner multipar, ypart lrxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + fi ; + +% elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,llxy[tpos])) : + elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) : + + % last one in chain + + nn := i ; + + if obey_multi_par_hang and obey_multi_par_more : + + multipar := + _pmp_x_left_top_hang_(i,true) -- + _pmp_x_right_top_hang_(i,true) -- + _pmp_x_right_bottom_hang_(i,true) -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + llxy[tpos] -- + _pmp_x_left_bottom_hang_(i,true) -- + cycle ; + + else : + + multipar := + ulcorner multipar -- + urcorner multipar -- + (xpart lrcorner multipar, ypart urxy[tpos]) -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + llxy[tpos] -- + (xpart llcorner multipar, ypart llxy[tpos]) -- + cycle ; + + fi ; + + save_multipar (i,3,multipar) ; + + elseif multi_column_first_page_hack and ((nxy[fpos]=RealPageNumber) and (nxy[tpos]>=RealPageNumber) and (NOfTextColumns>1)) : + + save_multipar (i,2,multipar) ; + + else : + % handled later + fi ; + + endfor ; + + % second loop + + if force_multi_par_chain or (ii > 1) : + + for i=ii+1 upto nn-1 : + + % rest of chain / todo : hang + +% hm, the second+ column in column sets now gets lost in a NOfTextColumns + + if (not check_multi_par_chain) or + ((nxy[fpos]RealPageNumber)) + : + + multipar := _pmp_set_multipar_(i) ; + + if obey_multi_par_hang and obey_multi_par_more : + + multipar := + _pmp_x_left_top_hang_(i,false) -- + _pmp_x_right_top_hang_(i,false) -- + _pmp_x_right_bottom_hang_(i,false) -- + _pmp_x_left_bottom_hang_(i,false) -- + cycle ; + + fi ; + + save_multipar(i,2,multipar) ; + + fi ; + + endfor ; + + fi ; + + % end of normal/fallback + +fi ; + + if span_multi_column_pars : + endgroup ; + fi ; + + % potential safeguard: + + % for i=1 upto nofmultipars : + % if length p <= 4 : + % multipars[i] := boundingbox(multipars[i]) ; + % fi ; + % end ; + + % quick hack for gb: + + one_piece_multi_par := (nofmultipars=1) and (pn=tn) ; + +enddef ; + +color boxgridcolor ; boxgridcolor := .8red ; +color boxlinecolor ; boxlinecolor := .8blue ; +color boxfillcolor ; boxfillcolor := .8white ; +numeric boxgridtype ; boxgridtype := 0 ; +numeric boxlinetype ; boxlinetype := 1 ; +numeric boxfilltype ; boxfilltype := 1 ; +numeric boxdashtype ; boxdashtype := 0 ; +pair boxgriddirection ; boxgriddirection := up ; +numeric boxgridwidth ; boxgridwidth := 1pt ; +numeric boxlinewidth ; boxlinewidth := 1pt ; +numeric boxlineradius ; boxlineradius := 0pt ; +numeric boxfilloffset ; boxfilloffset := 0pt ; +numeric boxgriddistance ; boxgriddistance := .5cm ; +numeric boxgridshift ; boxgridshift := 0pt ; + +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 3 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 = 3 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,true ) withcolor boxgridcolor ; + draw baseline_grid (i,boxgriddirection,true ) + shifted (0,ExHeight) withcolor boxgridcolor ; + elseif boxgridtype = 4 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,true ) + shifted (0,ExHeight/2) withcolor boxgridcolor ; + elseif boxgridtype = 11 : + draw graphic_grid(i,boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; + elseif boxgridtype = 12 : + draw graphic_grid(i,boxgriddistance,boxgriddistance,0,0) ; + fi ; + endfor ; +enddef ; + +def do_show_par (expr p, r, c) = + if length(p) > 2 : for i=0 upto length(p) : + draw fullcircle scaled r shifted point i of p + withpen pencircle scaled .5pt withcolor c ; + endfor ; fi ; + draw p withpen pencircle scaled .5pt withcolor c ; +enddef ; + +def show_par = + if length(mxy) > 2 : + draw mxy dashed evenly + withpen pencircle scaled .5pt withcolor .5white ; + fi ; + do_show_par(txy, 4pt, .5green) ; + do_show_par(bxy, 6pt, .5blue ) ; + do_show_par(pxy, 8pt, .5red ) ; + draw pref withpen pencircle scaled 2pt ; +enddef ; + +def sort_multi_pars = + if nofmultipars>1 : + begingroup ; save _p_, _n_ ; path _p_ ; numeric _n_ ; + for i := 1 upto nofmultipars : + if multilocs[i] = 3 : + _p_ := multipars[nofmultipars] ; + multipars[nofmultipars] := multipars[i] ; + multipars[i] := _p_ ; + _n_ := multirefs[nofmultipars] ; + multirefs[nofmultipars] := multirefs[i] ; + multirefs[i] := _n_ ; + _n_ := multilocs[nofmultipars] ; + multilocs[nofmultipars] := multilocs[i] ; + multilocs[i] := _n_ ; + fi ; + endfor ; + endgroup ; + fi ; +enddef ; + + +def collapse_multi_pars = + if nofmultipars>1 : + begingroup ; save _nofmultipars_ ; numeric _nofmultipars_ ; + _nofmultipars_ := 1 ; + sort_multi_pars ; % block not in order: 1, 3, 2.... + for i:=1 upto nofmultipars-1 : + if (round(xpart(llcorner multipars[i]-llcorner multipars[i+1]))=0) and + (round(xpart(lrcorner multipars[i]-lrcorner multipars[i+1]))=0) : +multilocs[_nofmultipars_] := multilocs[i+1] ; +multirefs[_nofmultipars_] := multirefs[i+1] ; + multipars[_nofmultipars_] := + ulcorner multipars[_nofmultipars_] -- + urcorner multipars[_nofmultipars_] -- + lrcorner multipars[i+1] -- + llcorner multipars[i+1] -- cycle ; + else : + _nofmultipars_ := _nofmultipars_ + 1 ; + multipars[_nofmultipars_] := multipars[i+1] ; + multilocs[_nofmultipars_] := multilocs[i+1] ; + multirefs[_nofmultipars_] := multirefs[i+1] ; + fi ; + endfor ; + nofmultipars := _nofmultipars_ ; + endgroup ; + fi ; +enddef ; + +% def draw_multi_pars = +% for i=1 upto nofmultipars : +% do_draw_par(multipars[i]) ; +% if boxgridtype= 1 : +% draw baseline_grid (multipars[i],up,true ) ; % withcolor boxgridcolor ; +% elseif boxgridtype= 2 : +% draw baseline_grid (multipars[i],up,false) ; % withcolor boxgridcolor ; +% elseif boxgridtype= 3 : +% draw baseline_grid (multipars[i],up,true ) ; % withcolor boxgridcolor ; +% draw baseline_grid (multipars[i],up,true ) +% shifted (0,ExHeight) ; % withcolor boxgridcolor ; +% elseif boxgridtype= 4 : +% draw baseline_grid (multipars[i],up,true ) +% shifted (0,ExHeight/2) ; % withcolor boxgridcolor ; +% elseif boxgridtype=11 : +% 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 ; + +def draw_multi_pars = + for i=1 upto nofmultipars : + do_draw_par(multipars[i]) ; + if boxgridtype= 1 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; % withcolor boxgridcolor ; + elseif boxgridtype= 2 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,false) ; % withcolor boxgridcolor ; + elseif boxgridtype= 3 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; % withcolor boxgridcolor ; + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight) ; % withcolor boxgridcolor ; + elseif boxgridtype= 4 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight/2) ; % withcolor boxgridcolor ; + elseif boxgridtype=11 : + 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 ; + +def show_multi_pars = + for i=1 upto nofmultipars : + do_show_par(multipars[i], 6pt, .5blue) ; + endfor ; +enddef ; + +vardef do_draw_par (expr p) = + if (length p>2) and (bbwidth(p)>1) and (bbheight(p)>1) : + save pp ; path pp ; + if (boxlineradius>0) and (boxlinetype=2) : + pp := p cornered boxlineradius ; + else : + pp := p ; + fi ; + if boxfilltype>0 : + if boxfilloffset>0 : + % temporary hack + begingroup ; interim linejoin := mitered ; + filldraw pp withcolor boxfillcolor withpen pencircle scaled (2*boxfilloffset) ; + endgroup ; + else : + fill pp withcolor boxfillcolor ; + fi ; + fi ; + if boxlinetype>0 : + draw pp withcolor boxlinecolor withpen pencircle scaled boxlinewidth ; + fi ; + fi ; +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 i, grid, bb ; picture grid ; pair start ; path bb ; + def _do_ (expr start) = + % 1 = normal, 2 = with background (i.e. no shine-through) + if boxdashtype = 2 : + draw start -- start shifted (bbwidth(pxy),0) + withpen pencircle scaled boxgridwidth + withcolor boxfillcolor ; + fi ; + draw start -- start shifted (bbwidth(pxy),0) + if boxdashtype > 0 : dashed evenly fi + 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 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) : + _do_ (ulcorner pxy shifted (0,-i)) ; + endfor ; + fi ; + ) ; + clip grid to pxy ; + bb := boundingbox grid ; + grid := grid shifted (0,boxgridshift) ; + setbounds grid to bb ; + grid + else : + nullpicture + fi +enddef ; + +vardef graphic_grid (expr pxy, dx, dy, x, y) = + if (bbheight(pxy)>dy) and (bbwidth(pxy)>dx) and (boxgridwidth>0) : + save grid ; picture grid ; + grid := image + ( for i = xpart llcorner pxy step dx until xpart lrcorner pxy : + draw (i,ypart llcorner pxy) -- (i,ypart ulcorner pxy) + withpen pencircle scaled boxgridwidth ; + endfor ; + for i = ypart llcorner pxy step dy until ypart ulcorner pxy : + draw (xpart llcorner pxy,i) -- (xpart lrcorner pxy,i) + withpen pencircle scaled boxgridwidth ; + endfor ) shifted (x,y) ; + clip grid to pxy ; + grid + else : + nullpicture + fi +enddef ; + +def anchor_box (expr n,x,y,w,h,d) = + currentpicture := currentpicture shifted (-x,-y) ; +enddef ; + +let draw_area = draw_box ; +let anchor_area = anchor_box ; +let anchor_par = anchor_box ; + + +numeric sync_n[], sync_p[][], sync_w[][], sync_h[][], sync_d[][], sync_t[][] ; +pair sync_xy[][] ; color sync_c[][] ; + +def ResetSyncTasks = + path SyncPaths[] ; numeric SyncTasks[], NOfSyncPaths, CurrentSyncClass ; + NOfSyncPaths := CurrentSyncClass := 0 ; + if unknown SyncLeftOffset : numeric SyncLeftOffset ; SyncLeftOffset := 0 ; fi ; + if unknown SyncWidth : numeric SyncWidth ; SyncWidth := 0 ; fi ; + if unknown SyncThreshold : numeric SyncThreshold ; SyncThreshold := LineHeight ; fi ; + if unknown SyncColor : color SyncColor ; SyncColor := .5white ; fi ; + if (SyncLeftOffset = 0) and (SyncWidth = 0) : + SyncWidth := if known TextWidth : TextWidth else : -1cm fi ; + fi ; +enddef ; + +ResetSyncTasks ; + +vardef SyncBox(expr n, i, leftoffset, width, topoffset, bottomoffset) = + save o ; pair o ; o := (xpart llcorner PlainTextArea,ypart sync_xy[n][i]) ; + o shifted (leftoffset,sync_h[n][i]+topoffset) -- + o shifted (width+leftoffset,sync_h[n][i]+topoffset) -- + o shifted (width+leftoffset,bottomoffset) -- + o shifted (leftoffset,bottomoffset) -- cycle +enddef ; + +def SetSyncColor(expr n, i, c) = + sync_c[n][i] := c ; +enddef ; + +def SetSyncThreshold(expr n, i, th) = + sync_th[n][i] := th ; +enddef ; + +vardef TheSyncColor(expr n, i) = + if known sync_c[n][i] : sync_c[n][i] else : SyncColor fi +enddef ; + +vardef TheSyncThreshold(expr n, i) = + if known sync_th[n][i] : sync_th[n][i] else : SyncThreshold fi +enddef ; + +vardef PrepareSyncTasks(expr n, collapse, extendtop, prestartnext) = + ResetSyncTasks ; + if known sync_n[n] : + CurrentSyncClass := n ; + save ok, l, d ; boolean ok ; ok := false ; NOfSyncPaths := l := 0 ; + for i=1 upto sync_n[n] : + if RealPageNumber > sync_p[n][i] : + l := i ; + elseif RealPageNumber = sync_p[n][i] : + NOfSyncPaths := NOfSyncPaths + 1 ; + if not ok : + if i>1 : + if sync_t[n][i-1] = sync_t[n][i] : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i-1, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i-1 ; + NOfSyncPaths := NOfSyncPaths + 1 ; + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + ok := true ; + fi ; + endfor ; + if (NOfSyncPaths = 0) and (l > 0) : + NOfSyncPaths := 1 ; + SyncPaths[NOfSyncPaths] := SyncBox(n, l, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := l ; + fi ; + if NOfSyncPaths > 0 : + for i = 1 upto NOfSyncPaths-1 : + SyncPaths[i] := topboundary SyncPaths[i] -- reverse topboundary SyncPaths[i+1] -- cycle ; + endfor ; + if unknown SyncThresholdMethod : + numeric SyncThresholdMethod ; SyncThresholdMethod := 2 ; + fi ; + if extendtop : + if SyncThresholdMethod = 1 : + if NOfSyncPaths>1 : + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[2]]) ; + if (SyncTasks[2]>1) and (d > 0pt) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[2]])) and (sync_p[n][SyncTasks[2]] = RealPageNumber) : + SyncPaths[2] := SyncPaths[2] topenlarged PaperHeight ; + fi ; + fi ; + else : + for i = 1 upto NOfSyncPaths : + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[i]]) ; + if (d > 0) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[i]] = RealPageNumber) : + SyncPaths[i] := SyncPaths[i] topenlarged PaperHeight ; + fi ; + endfor ; + fi ; + fi ; + if prestartnext : + if NOfSyncPaths>1 : + if SyncTasks[NOfSyncPaths] < sync_n[n] : % there is a next one + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[NOfSyncPaths]+1]) ; + if (d > 0) and (d <= TheSyncThreshold(n, sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[NOfSyncPaths]+1] = RealPageNumber+1) : + SyncPaths[NOfSyncPaths+1] := + (xpart ulcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- + (xpart urcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- + lrcorner SyncPaths[NOfSyncPaths] -- + llcorner SyncPaths[NOfSyncPaths] -- cycle ; + SyncTasks[NOfSyncPaths+1] := SyncTasks[NOfSyncPaths]+1 ; + NOfSyncPaths := NOfSyncPaths + 1 ; + fi ; + fi ; + fi ; + else : + if NOfSyncPaths>1 : + d := ypart (sync_xy[n][SyncTasks[NOfSyncPaths]] - llcorner PlainTextArea) ; + if (d < TheSyncThreshold(n, SyncTasks[NOfSyncPaths])) : + NOfSyncPaths := NOfSyncPaths - 1 ; + SyncPaths[NOfSyncPaths] := SyncPaths[NOfSyncPaths] bottomenlarged PaperHeight ; + fi ; + fi ; + fi ; + if (NOfSyncPaths>1) and collapse : + save j ; numeric j ; j := 1 ; + for i = 2 upto NOfSyncPaths : + if sync_t[n][SyncTasks[i]] = sync_t[n][SyncTasks[j]] : + SyncPaths[j] := boundingbox image (draw SyncPaths[i] ; draw SyncPaths[j] ; ) ; + SyncTasks[j] := SyncTasks[i] ; + else : + j := j + 1 ; + SyncPaths[j] := SyncPaths[i] ; + SyncTasks[j] := SyncTasks[i] ; + fi ; + endfor ; + NOfSyncPaths := j ; + fi ; + fi ; + fi ; +enddef ; + +def SyncTask(expr n) = + if known SyncTasks[n] : SyncTasks[n] else : 0 fi +enddef ; + +def FlushSyncTasks = + for i = 1 upto NOfSyncPaths : + ProcessSyncTask(SyncPaths[i], TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]])) ; + endfor ; +enddef ; + +def ProcessSyncTask(expr p, c) = + fill p withcolor c ; +enddef ; + +endinput ; + +end + +% for Jelle Huisman +% +% \setupcolors[state=start] +% \dontcomplain +% \definecolumnset[example][n=3,distance=5mm] +% \startMPextensions +% multi_column_first_page_hack := true ; +% \stopMPextensions +% \startuseMPgraphic{mpos:par:trick} +% for i=1 upto nofmultipars-1 : draw (rightboundary multipars[i]) shifted (2.5mm, 0) ; endfor ; +% \stopuseMPgraphic +% \definetextbackground[test][mp=mpos:par:trick,method=mpos:par:columnset] +% \starttext +% \definecolumnsetspan[chapter][n=3] +% \startcolumnset[example] +% \startcolumnsetspan[chapter] +% \chapter{Chapter One} +% \stopcolumnsetspan +% \starttextbackground[test] \dorecurse {3}{\input knuth } \stoptextbackground +% \stopcolumnset +% \startcolumnset[example] +% \startcolumnsetspan[chapter] +% \chapter{Chapter One} +% \stopcolumnsetspan +% \starttextbackground[test] \dorecurse {10}{\input knuth } \stoptextbackground +% \stopcolumnset +% \stoptext +% +% fast variant: +% +% \startuseMPgraphic{whatever} +% for i=1 upto NOfTextColumns-1 : +% draw (rightboundary TextColumns[i]) shifted (2.5mm,0) shifted -\MPxy\textanchor ; +% endfor ; +% setbounds currentpicture to OverlayBox ; +% \stopuseMPgraphic +% \defineoverlay[whatever][\useMPgraphic{whatever}] +% \setupbackgrounds[text][background=whatever] diff --git a/metapost/context/base/mp-core.mpiv b/metapost/context/base/mp-core.mpiv new file mode 100644 index 000000000..8fc32c420 --- /dev/null +++ b/metapost/context/base/mp-core.mpiv @@ -0,0 +1,1353 @@ +if unknown context_tool : input mp-tool ; fi ; +if known context_core : endinput ; fi ; + +boolean context_core ; context_core := true ; + +pair lxy[], rxy[], cxy[], llxy[], lrxy[], ulxy[], urxy[] ; +path pxy[] ; +numeric hxy[], wxy[], dxy[], nxy[] ; + +def box_found (expr n,x,y,w,h,d) = + not ((x=0) and (y=0) and (w=0) and (h=0) and (d=0)) +enddef ; + +def initialize_box_pos (expr pos,n,x,y,w,h,d) = + pair lxy, rxy, cxy, llxy, lrxy, ulxy, urxy ; + path pxy ; numeric hxy, wxy, dxy, nxy; + lxy := (x,y) ; + llxy := (x,y-d) ; + lrxy := (x+w,y-d) ; + urxy := (x+w,y+h) ; + ulxy := (x,y+h) ; + wxy := w ; + hxy := h ; + dxy := d ; + rxy := lxy shifted (wxy,0) ; + pxy := llxy--lrxy--urxy--ulxy--cycle ; + cxy := center pxy ; + nxy := n ; + freeze_box(pos) ; +enddef ; + +def freeze_box (expr pos) = + lxy[pos] := lxy ; + llxy[pos] := llxy ; + lrxy[pos] := lrxy ; + urxy[pos] := urxy ; + ulxy[pos] := ulxy ; + wxy[pos] := wxy ; + hxy[pos] := hxy ; + dxy[pos] := dxy ; + rxy[pos] := rxy ; + pxy[pos] := pxy ; + cxy[pos] := cxy ; + nxy[pos] := nxy ; +enddef ; + +def initialize_box (expr n,x,y,w,h,d) = + + numeric bpos ; bpos := 0 ; initialize_box_pos(bpos,n,x,y,w,h,d) ; + +enddef ; + +def initialize_area (expr fn,fx,fy,fw,fh,fd, + tn,tx,ty,tw,th,td) = + + numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; + numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; + + do_initialize_area (fpos, tpos) ; + +enddef ; + +def do_initialize_area (expr fpos, tpos) = + lxy := lxy[fpos] ; + llxy := (xpart llxy[fpos], ypart llxy[tpos]) ; + lrxy := lrxy[tpos] ; + urxy := (xpart urxy[tpos], ypart urxy[fpos]) ; + ulxy := ulxy[fpos] ; + wxy := xpart lrxy - xpart llxy ; + hxy := hxy[fpos] ; + dxy := dxy[tpos] ; + rxy := lxy shifted (wxy,0) ; + pxy := llxy--lrxy--urxy--ulxy--cycle ; + 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, + pn,px,py,pw,ph,pd, + rw,rl,rr,rh,ra,ri) = + + numeric fpos ; fpos := 1 ; initialize_box_pos(fpos,fn,fx,fy,fw,fh,fd) ; + numeric tpos ; tpos := 2 ; initialize_box_pos(tpos,tn,tx,ty,tw,th,td) ; + numeric mpos ; mpos := 3 ; initialize_box_pos(mpos,mn,mx,my,mw,mh,md) ; + numeric ppos ; ppos := 4 ; initialize_box_pos(ppos,pn,px,py,pw,ph,pd) ; + + numeric par_strut_height, par_strut_depth, par_line_height ; + + set_par_line_height (ph, pd) ; + + do_initialize_area (fpos, tpos) ; + do_initialize_par (fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) ; + +enddef ; + +def initialize_area_par (expr fn,fx,fy,fw,fh,fd, + tn,tx,ty,tw,th,td, + wn,wx,wy,ww,wh,wd) = + + 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 par_strut_height, par_strut_depth, par_line_height ; + + 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) ; + + do_initialize_area (ffpos, ttpos) ; + + numeric mpos ; mpos := 6 ; freeze_box(mpos) ; + + do_initialize_par (fpos, tpos, mpos, ffpos, 0,0,0,0,0,0) ; + +enddef ; + +def do_initialize_par (expr fpos, tpos, mpos, ppos, rw,rl,rr,rh,ra,ri) = + + pair lref, rref, pref, lhref, rhref ; + + % clip the page area to the left and right skips + + llxy[mpos] := llxy[mpos] shifted (+rl,0) ; + lrxy[mpos] := lrxy[mpos] shifted (-rr,0) ; + urxy[mpos] := urxy[mpos] shifted (-rr,0) ; + ulxy[mpos] := ulxy[mpos] shifted (+rl,0) ; + + % fixate the leftskip, rightskip and hanging indentation + + lref := (xpart llxy[mpos],ypart ulxy[ppos]) ; lhref := lref shifted (rh,0) ; + rref := (xpart lrxy[mpos],ypart urxy[ppos]) ; rhref := rref shifted (rh,0) ; + + pref := lxy[ppos] ; + + if nxy[tpos] > nxy[fpos] : + if nxy[fpos] = nxy[mpos] : + % first of multiple pages + llxy[tpos] := llxy[mpos] ; + lrxy[tpos] := lrxy[mpos] ; + urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; + ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; + boxgriddirection := down ; + elseif nxy[tpos] = nxy[mpos] : + % last of multiple pages + llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; + lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; + urxy[fpos] := urxy[mpos] ; + ulxy[fpos] := ulxy[mpos] ; + boxgriddirection := up ; + else : + % middle of multiple pages + llxy[fpos] := ulxy[mpos] shifted (0,-par_line_height) ; + lrxy[fpos] := urxy[mpos] shifted (0,-par_line_height) ; + urxy[fpos] := urxy[mpos] ; + ulxy[fpos] := ulxy[mpos] ; + llxy[tpos] := llxy[mpos] ; + lrxy[tpos] := lrxy[mpos] ; + urxy[tpos] := lrxy[mpos] shifted (0,par_line_height) ; + ulxy[tpos] := llxy[mpos] shifted (0,par_line_height) ; + boxgriddirection := up ; + fi ; + else : + % just one page + boxgriddirection := up ; + fi ; + + path txy, bxy, pxy, mxy ; + + txy := originpath ; % top + bxy := originpath ; % bottom + pxy := originpath ; % composed + + boolean lefthang, righthang, somehang ; + + % we only hang on the first of a multiple page background + + if nxy[mpos] > nxy[fpos] : + lefthang := righthang := somehang := false ; + else : + lefthang := (rh>0) ; righthang := (rh<0) ; somehang := false ; + fi ; + + if lefthang : + mxy := boundingbox (lref -- lref shifted (rh,ra*par_line_height)) ; + elseif righthang : + mxy := boundingbox (rref -- rref shifted (rh,ra*par_line_height)) ; + else : + mxy := originpath ; + fi ; + + if round(ypart llxy[fpos]) = round(ypart llxy[tpos]) : + + % We have a one-liner. Watch how er use the bottom pos for + % determining the height. + + llxy[fpos] := (xpart llxy[fpos], ypart llxy[tpos]) ; + ulxy[fpos] := (xpart ulxy[fpos], ypart ulxy[tpos]) ; + + else : + + % We have a multi-liner. For convenience we now correct the + % begin and end points for indentation. + + if lefthang and (round(ypart llxy[tpos]) >= round(ypart lrcorner mxy)) : + llxy[tpos] := (xpart lhref, ypart llxy[tpos]) ; + ulxy[tpos] := (xpart lhref, ypart ulxy[tpos]) ; + else : + llxy[tpos] := (xpart lref, ypart llxy[tpos]) ; + ulxy[tpos] := (xpart lref, ypart ulxy[tpos]) ; + fi ; + + if righthang and (round(ypart lrxy[fpos]) >= round(ypart llcorner mxy)) : + lrxy[fpos] := (xpart rhref, ypart lrxy[fpos]) ; + urxy[fpos] := (xpart rhref, ypart urxy[fpos]) ; + else : + lrxy[fpos] := (xpart rref, ypart lrxy[fpos]) ; + urxy[fpos] := (xpart rref, ypart urxy[fpos]) ; + fi ; + + fi ; + + somehang := (ypart ulxy[fpos]>ypart llcorner mxy) and + (ypart llxy[tpos]0 : + left_skip := rl + xpart llxy[wpos] - xpart llxy[ppos] ; + right_skip := rw - left_skip - ww ; + else : + left_skip := rl ; + right_skip := rr ; + fi ; + + path multipar, multipars[] ; + numeric multiref, multirefs[] ; + numeric multiloc, multilocs[] ; % 1=begin 2=between 3=end + + numeric multi_par_pages ; multi_par_pages := nxy[tpos]-nxy[fpos]+1 ; + + % locals .. why can't i move these outside? + +vardef _pmp_set_multipar_ (expr i) = + ( (TextAreas[i] leftenlarged -left_skip) rightenlarged (-right_skip + if auto_multi_par_hsize : + rw - bbwidth(TextAreas[i]) fi) ) +enddef ; + +vardef _pmp_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 ; + +vardef _pmp_estimated_par_lines_ (expr h) = + round(h/par_line_height) +enddef ; + +vardef _pmp_top_multi_par_(expr p) = + (round(_pmp_estimated_par_lines_(bbheight(p)*par_line_height))=round(bbheight(p))) +enddef ; + +vardef _pmp_multi_par_tsc_(expr p) = + if _pmp_top_multi_par_(p) : TopSkipCorrection else : 0 fi +enddef ; + +vardef _pmp_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 + _pmp_estimated_par_lines_(ypart ulxy[fpos] - + ypart llcorner SavedTextAreas[i]) ; + elseif ok : + h := h + _pmp_estimated_par_lines_(bbheight(SavedTextAreas[i])) ; + fi ; + endfor ; + fi ; + if ok : + for i := 1 upto n-1 : + h := h + _pmp_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 + _pmp_estimated_par_lines_(ypart ulxy[fpos] - ypart llcorner TextAreas[i]) ; + elseif ok : + h := h + _pmp_estimated_par_lines_(bbheight(TextAreas[i])) ; + fi ; + endfor ; + fi ; + h + fi +enddef ; + +vardef _pmp_left_top_hang_ (expr same_area) = + + par_hang_after := ra + _pmp_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 _pmp_snapped_multi_pos_(ulxy[fpos])); + pair _pa_ ; _pa_ := _ul_ 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 llxy[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 _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 _pmp_right_top_hang_ (expr same_area) = + + par_hang_after := ra + _pmp_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 _pmp_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 _pmp_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 _pmp_snapped_multi_pos_(urxy[fpos])) + else : + (xpart urcorner multipar, ypart _pmp_snapped_multi_pos_(urxy[fpos])) + fi +enddef ; + +vardef _pmp_x_left_top_hang_ (expr i, t) = + par_hang_after := min(0,ra + _pmp_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])0) and (par_hang_after>0) and obey_multi_par_hang : + _ll_ := (xpart ulcorner multipar, ypart _pmp_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 _pmp_right_bottom_hang_ (expr same_area) = + pair _lr_, _sa_, _pa_ ; + _sa_ := if same_area : _pmp_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 _pmp_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 _pmp_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 _pmp_x_left_bottom_hang_ (expr i, t) = + pair _ll_, _sa_, _pa_ ; + _sa_ := if t : llxy[tpos] else : llcorner multipar fi ; + if (par_hang_indent>0) and (ra>0) : + par_hang_after := max(0,ra - _pmp_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 _pmp_x_right_bottom_hang_ (expr i, t) = + pair _lr_, _sa_, _pa_ ; + _sa_ := if t : _pmp_snapped_multi_pos_(ulxy[tpos]) else : llcorner multipar fi ; + if (par_hang_indent<0) and (ra>0) : + par_hang_after := max(0,ra - _pmp_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 _pmp_test_multipar_ = +% multipar := boundingbox multipar ; +% enddef ; + + % first loop + + ii := 0 ; nn := NOfTextAreas+1 ; nofmultipars := 0 ; + + if enable_multi_par_fallback and + (nxy[fpos]=RealPageNumber) and + (nxy[tpos]=RealPageNumber) and not + (InsideSomeTextArea(lxy[fpos]) and + InsideSomeTextArea(rxy[tpos])) : + + % fallback + + % multipar := + % llxy[fpos] -- + % lrxy[tpos] -- + % urxy[tpos] -- + % ulxy[fpos] -- cycle ; + % + % save_multipar (1,1,multipar) ; + + % we need to take the boundingbox because there can be + % more lines and we want a proper rectange + + multipar := + ulxy[fpos] -- + urxy[tpos] -- + lrxy[fpos] -- + llxy[tpos] -- cycle ; + + save_multipar (1,1,boundingbox(multipar)) ; + + else : + + % normal + + for i=1 upto NOfTextAreas : + + TopSkipCorrection := 0 ; + + multipar := _pmp_set_multipar_(i) ; + + % 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])) : + if (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) : + + % in same area + + nn := i ; + + if compensate_multi_par_topskip and (round(LineHeight-ph-pd)=0) : + + 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] -- + _pmp_snapped_multi_pos_(urxy[tpos]) -- + %ulxy[fpos] -- + _pmp_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 : + + _pmp_right_bottom_hang_(true) -- + _pmp_right_top_hang_(true) -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + + else : + + llxy[fpos] -- + (xpart urcorner multipar, ypart llxy[fpos]) -- + (xpart urcorner multipar, ypart ulxy[fpos]) -- + _pmp_snapped_multi_pos_(ulxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + multipar := _pmp_set_multipar_(i) ; + + multipar := if obey_multi_par_hang : + + _pmp_left_bottom_hang_(true) -- + llxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + _pmp_left_top_hang_(true) -- + + else : + + (xpart llcorner multipar, ypart llxy[tpos]) -- + llxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + (xpart llcorner multipar, ypart ulxy[tpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + else : + + multipar := if obey_multi_par_hang : + + _pmp_left_bottom_hang_(true) -- + llxy[tpos] -- + %ulxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + _pmp_right_bottom_hang_(true) -- + _pmp_right_top_hang_(true) -- + %urxy[fpos] -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + _pmp_left_top_hang_(true) -- + + else : + + (xpart llcorner multipar, ypart llxy[tpos]) -- + llxy[tpos] -- + %ulxy[tpos] -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + (xpart lrcorner multipar, ypart ulxy[tpos]) -- + (xpart urcorner multipar, ypart urxy[fpos]) -- + %urxy[fpos] -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + (xpart ulcorner multipar, ypart lrxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + fi ; + + else : + + multipar := if obey_multi_par_hang : + + _pmp_left_bottom_hang_(false) -- + _pmp_right_bottom_hang_(false) -- + _pmp_right_top_hang_(false) -- + %urxy[fpos] -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + _pmp_left_top_hang_(false) -- + + else : + + llcorner multipar -- + lrcorner multipar -- + (xpart urcorner multipar, ypart urxy[fpos]) -- + %urxy[fpos] -- + _pmp_snapped_multi_pos_(urxy[fpos]) -- + lrxy[fpos] -- + (xpart ulcorner multipar, ypart lrxy[fpos]) -- + + fi cycle ; + + save_multipar (i,1,multipar) ; + + fi ; + +% elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,llxy[tpos])) : + elseif (nxy[tpos]=RealPageNumber) and (InsideTextArea(i,par_stop_pos)) : + + % last one in chain + + nn := i ; + + if obey_multi_par_hang and obey_multi_par_more : + + multipar := + _pmp_x_left_top_hang_(i,true) -- + _pmp_x_right_top_hang_(i,true) -- + _pmp_x_right_bottom_hang_(i,true) -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + llxy[tpos] -- + _pmp_x_left_bottom_hang_(i,true) -- + cycle ; + + else : + + multipar := + ulcorner multipar -- + urcorner multipar -- + (xpart lrcorner multipar, ypart urxy[tpos]) -- + _pmp_snapped_multi_pos_(ulxy[tpos]) -- + llxy[tpos] -- + (xpart llcorner multipar, ypart llxy[tpos]) -- + cycle ; + + fi ; + + save_multipar (i,3,multipar) ; + + elseif multi_column_first_page_hack and ((nxy[fpos]=RealPageNumber) and (nxy[tpos]>=RealPageNumber) and (NOfTextColumns>1)) : + + save_multipar (i,2,multipar) ; + + else : + % handled later + fi ; + + endfor ; + + % second loop + + if force_multi_par_chain or (ii > 1) : + + for i=ii+1 upto nn-1 : + + % rest of chain / todo : hang + +% hm, the second+ column in column sets now gets lost in a NOfTextColumns + + if (not check_multi_par_chain) or + ((nxy[fpos]RealPageNumber)) + : + + multipar := _pmp_set_multipar_(i) ; + + if obey_multi_par_hang and obey_multi_par_more : + + multipar := + _pmp_x_left_top_hang_(i,false) -- + _pmp_x_right_top_hang_(i,false) -- + _pmp_x_right_bottom_hang_(i,false) -- + _pmp_x_left_bottom_hang_(i,false) -- + cycle ; + + fi ; + + save_multipar(i,2,multipar) ; + + fi ; + + endfor ; + + fi ; + + % end of normal/fallback + +fi ; + + if span_multi_column_pars : + endgroup ; + fi ; + + % potential safeguard: + + % for i=1 upto nofmultipars : + % if length p <= 4 : + % multipars[i] := boundingbox(multipars[i]) ; + % fi ; + % end ; + + % quick hack for gb: + + one_piece_multi_par := (nofmultipars=1) and (pn=tn) ; + +enddef ; + +def boxgridoptions = withcolor .8red enddef ; +def boxlineoptions = withcolor .8blue enddef ; +def boxfilloptions = withcolor .8white enddef ; + +numeric boxgridtype ; boxgridtype := 0 ; +numeric boxlinetype ; boxlinetype := 1 ; +numeric boxfilltype ; boxfilltype := 1 ; +numeric boxdashtype ; boxdashtype := 0 ; +pair boxgriddirection ; boxgriddirection := up ; +numeric boxgridwidth ; boxgridwidth := 1pt ; +numeric boxlinewidth ; boxlinewidth := 1pt ; +numeric boxlineradius ; boxlineradius := 0pt ; +numeric boxfilloffset ; boxfilloffset := 0pt ; +numeric boxgriddistance ; boxgriddistance := .5cm ; +numeric boxgridshift ; boxgridshift := 0pt ; + +def draw_box = + draw pxy boxlineoptions withpen pencircle scaled boxlinewidth ; + draw lxy -- rxy boxlineoptions withpen pencircle scaled boxgridwidth ; +enddef ; + +def draw_par = % 1 2 3 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 ) boxgridoptions ; + elseif boxgridtype = 2 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,false) boxgridoptions ; + elseif boxgridtype = 3 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,true ) boxgridoptions ; + draw baseline_grid (i,boxgriddirection,true ) + shifted (0,ExHeight) boxgridoptions ; + elseif boxgridtype = 4 : + boxgriddirection := origin ; + draw baseline_grid (i,boxgriddirection,true ) + shifted (0,ExHeight/2) boxgridoptions ; + elseif boxgridtype = 11 : + draw graphic_grid(i,boxgriddistance,boxgriddistance,boxgriddistance/2,boxgriddistance/2) ; + elseif boxgridtype = 12 : + draw graphic_grid(i,boxgriddistance,boxgriddistance,0,0) ; + fi ; + endfor ; +enddef ; + +def do_show_par (expr p, r, c) = + if length(p) > 2 : for i=0 upto length(p) : + draw fullcircle scaled r shifted point i of p + withpen pencircle scaled .5pt withcolor c ; + endfor ; fi ; + draw p withpen pencircle scaled .5pt withcolor c ; +enddef ; + +def show_par = + if length(mxy) > 2 : + draw mxy dashed evenly + withpen pencircle scaled .5pt withcolor .5white ; + fi ; + do_show_par(txy, 4pt, .5green) ; + do_show_par(bxy, 6pt, .5blue ) ; + do_show_par(pxy, 8pt, .5red ) ; + draw pref withpen pencircle scaled 2pt ; +enddef ; + +def sort_multi_pars = + if nofmultipars>1 : + begingroup ; save _p_, _n_ ; path _p_ ; numeric _n_ ; + for i := 1 upto nofmultipars : + if multilocs[i] = 3 : + _p_ := multipars[nofmultipars] ; + multipars[nofmultipars] := multipars[i] ; + multipars[i] := _p_ ; + _n_ := multirefs[nofmultipars] ; + multirefs[nofmultipars] := multirefs[i] ; + multirefs[i] := _n_ ; + _n_ := multilocs[nofmultipars] ; + multilocs[nofmultipars] := multilocs[i] ; + multilocs[i] := _n_ ; + fi ; + endfor ; + endgroup ; + fi ; +enddef ; + + +def collapse_multi_pars = + if nofmultipars>1 : + begingroup ; save _nofmultipars_ ; numeric _nofmultipars_ ; + _nofmultipars_ := 1 ; + sort_multi_pars ; % block not in order: 1, 3, 2.... + for i:=1 upto nofmultipars-1 : + if (round(xpart(llcorner multipars[i]-llcorner multipars[i+1]))=0) and + (round(xpart(lrcorner multipars[i]-lrcorner multipars[i+1]))=0) : +multilocs[_nofmultipars_] := multilocs[i+1] ; +multirefs[_nofmultipars_] := multirefs[i+1] ; + multipars[_nofmultipars_] := + ulcorner multipars[_nofmultipars_] -- + urcorner multipars[_nofmultipars_] -- + lrcorner multipars[i+1] -- + llcorner multipars[i+1] -- cycle ; + else : + _nofmultipars_ := _nofmultipars_ + 1 ; + multipars[_nofmultipars_] := multipars[i+1] ; + multilocs[_nofmultipars_] := multilocs[i+1] ; + multirefs[_nofmultipars_] := multirefs[i+1] ; + fi ; + endfor ; + nofmultipars := _nofmultipars_ ; + endgroup ; + fi ; +enddef ; + +def draw_multi_pars = + for i=1 upto nofmultipars : + do_draw_par(multipars[i]) ; + if boxgridtype= 1 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; + elseif boxgridtype= 2 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,false) ; + elseif boxgridtype= 3 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) ; + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight) ; + elseif boxgridtype= 4 : + draw baseline_grid (multipars[i],if multilocs[i]=1: down else: up fi,true) shifted (0,ExHeight/2) ; + elseif boxgridtype=11 : + 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 ; + +def show_multi_pars = + for i=1 upto nofmultipars : + do_show_par(multipars[i], 6pt, .5blue) ; + endfor ; +enddef ; + +vardef do_draw_par (expr p) = + if (length p>2) and (bbwidth(p)>1) and (bbheight(p)>1) : + save pp ; path pp ; + if (boxlineradius>0) and (boxlinetype=2) : + pp := p cornered boxlineradius ; + else : + pp := p ; + fi ; + if boxfilltype>0 : + if boxfilloffset>0 : + % temporary hack + begingroup ; interim linejoin := mitered ; + filldraw pp boxfilloptions withpen pencircle scaled (2*boxfilloffset) ; + endgroup ; + else : + fill pp boxfilloptions ; + fi ; + fi ; + if boxlinetype>0 : + draw pp boxlineoptions withpen pencircle scaled boxlinewidth ; + fi ; + fi ; +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 i, grid, bb ; picture grid ; pair start ; path bb ; + def _do_ (expr start) = + % 1 = normal, 2 = with background (i.e. no shine-through) + if boxdashtype = 2 : + draw start -- start shifted (bbwidth(pxy),0) + withpen pencircle scaled boxgridwidth + boxfilloptions ; + fi ; + draw start -- start shifted (bbwidth(pxy),0) + if boxdashtype > 0 : dashed evenly fi + withpen pencircle scaled boxgridwidth + boxgridoptions ; + 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 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) : + _do_ (ulcorner pxy shifted (0,-i)) ; + endfor ; + fi ; + ) ; + clip grid to pxy ; + bb := boundingbox grid ; + grid := grid shifted (0,boxgridshift) ; + setbounds grid to bb ; + grid + else : + nullpicture + fi +enddef ; + +vardef graphic_grid (expr pxy, dx, dy, x, y) = + if (bbheight(pxy)>dy) and (bbwidth(pxy)>dx) and (boxgridwidth>0) : + save grid ; picture grid ; + grid := image + ( for i = xpart llcorner pxy step dx until xpart lrcorner pxy : + draw (i,ypart llcorner pxy) -- (i,ypart ulcorner pxy) + withpen pencircle scaled boxgridwidth ; + endfor ; + for i = ypart llcorner pxy step dy until ypart ulcorner pxy : + draw (xpart llcorner pxy,i) -- (xpart lrcorner pxy,i) + withpen pencircle scaled boxgridwidth ; + endfor ) shifted (x,y) ; + clip grid to pxy ; + grid + else : + nullpicture + fi +enddef ; + +def anchor_box (expr n,x,y,w,h,d) = + currentpicture := currentpicture shifted (-x,-y) ; +enddef ; + +let draw_area = draw_box ; +let anchor_area = anchor_box ; +let anchor_par = anchor_box ; + + +numeric sync_n[], sync_p[][], sync_w[][], sync_h[][], sync_d[][], sync_t[][] ; +pair sync_xy[][] ; color sync_c[][] ; + +def ResetSyncTasks = + path SyncPaths[] ; numeric SyncTasks[], NOfSyncPaths, CurrentSyncClass ; + NOfSyncPaths := CurrentSyncClass := 0 ; + if unknown SyncLeftOffset : numeric SyncLeftOffset ; SyncLeftOffset := 0 ; fi ; + if unknown SyncWidth : numeric SyncWidth ; SyncWidth := 0 ; fi ; + if unknown SyncThreshold : numeric SyncThreshold ; SyncThreshold := LineHeight ; fi ; + if unknown SyncColor : color SyncColor ; SyncColor := .5white ; fi ; + if (SyncLeftOffset = 0) and (SyncWidth = 0) : + SyncWidth := if known TextWidth : TextWidth else : -1cm fi ; + fi ; +enddef ; + +ResetSyncTasks ; + +vardef SyncBox(expr n, i, leftoffset, width, topoffset, bottomoffset) = + save o ; pair o ; o := (xpart llcorner PlainTextArea,ypart sync_xy[n][i]) ; + o shifted (leftoffset,sync_h[n][i]+topoffset) -- + o shifted (width+leftoffset,sync_h[n][i]+topoffset) -- + o shifted (width+leftoffset,bottomoffset) -- + o shifted (leftoffset,bottomoffset) -- cycle +enddef ; + +def SetSyncColor(expr n, i, c) = + sync_c[n][i] := c ; +enddef ; + +def SetSyncThreshold(expr n, i, th) = + sync_th[n][i] := th ; +enddef ; + +vardef TheSyncColor(expr n, i) = + if known sync_c[n][i] : sync_c[n][i] else : SyncColor fi +enddef ; + +vardef TheSyncThreshold(expr n, i) = + if known sync_th[n][i] : sync_th[n][i] else : SyncThreshold fi +enddef ; + +vardef PrepareSyncTasks(expr n, collapse, extendtop, prestartnext) = + ResetSyncTasks ; + if known sync_n[n] : + CurrentSyncClass := n ; + save ok, l, d ; boolean ok ; ok := false ; NOfSyncPaths := l := 0 ; + for i=1 upto sync_n[n] : + if RealPageNumber > sync_p[n][i] : + l := i ; + elseif RealPageNumber = sync_p[n][i] : + NOfSyncPaths := NOfSyncPaths + 1 ; + if not ok : + if i>1 : + if sync_t[n][i-1] = sync_t[n][i] : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i-1, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i-1 ; + NOfSyncPaths := NOfSyncPaths + 1 ; + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + else : + SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := i ; + fi ; + ok := true ; + fi ; + endfor ; + if (NOfSyncPaths = 0) and (l > 0) : + NOfSyncPaths := 1 ; + SyncPaths[NOfSyncPaths] := SyncBox(n, l, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ; + SyncTasks[NOfSyncPaths] := l ; + fi ; + if NOfSyncPaths > 0 : + for i = 1 upto NOfSyncPaths-1 : + SyncPaths[i] := topboundary SyncPaths[i] -- reverse topboundary SyncPaths[i+1] -- cycle ; + endfor ; + if unknown SyncThresholdMethod : + numeric SyncThresholdMethod ; SyncThresholdMethod := 2 ; + fi ; + if extendtop : + if SyncThresholdMethod = 1 : + if NOfSyncPaths>1 : + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[2]]) ; + if (SyncTasks[2]>1) and (d > 0pt) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[2]])) and (sync_p[n][SyncTasks[2]] = RealPageNumber) : + SyncPaths[2] := SyncPaths[2] topenlarged PaperHeight ; + fi ; + fi ; + else : + for i = 1 upto NOfSyncPaths : + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[i]]) ; + if (d > 0) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[i]] = RealPageNumber) : + SyncPaths[i] := SyncPaths[i] topenlarged PaperHeight ; + fi ; + endfor ; + fi ; + fi ; + if prestartnext : + if NOfSyncPaths>1 : + if SyncTasks[NOfSyncPaths] < sync_n[n] : % there is a next one + d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[NOfSyncPaths]+1]) ; + if (d > 0) and (d <= TheSyncThreshold(n, sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[NOfSyncPaths]+1] = RealPageNumber+1) : + SyncPaths[NOfSyncPaths+1] := + (xpart ulcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- + (xpart urcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) -- + lrcorner SyncPaths[NOfSyncPaths] -- + llcorner SyncPaths[NOfSyncPaths] -- cycle ; + SyncTasks[NOfSyncPaths+1] := SyncTasks[NOfSyncPaths]+1 ; + NOfSyncPaths := NOfSyncPaths + 1 ; + fi ; + fi ; + fi ; + else : + if NOfSyncPaths>1 : + d := ypart (sync_xy[n][SyncTasks[NOfSyncPaths]] - llcorner PlainTextArea) ; + if (d < TheSyncThreshold(n, SyncTasks[NOfSyncPaths])) : + NOfSyncPaths := NOfSyncPaths - 1 ; + SyncPaths[NOfSyncPaths] := SyncPaths[NOfSyncPaths] bottomenlarged PaperHeight ; + fi ; + fi ; + fi ; + if (NOfSyncPaths>1) and collapse : + save j ; numeric j ; j := 1 ; + for i = 2 upto NOfSyncPaths : + if sync_t[n][SyncTasks[i]] = sync_t[n][SyncTasks[j]] : + SyncPaths[j] := boundingbox image (draw SyncPaths[i] ; draw SyncPaths[j] ; ) ; + SyncTasks[j] := SyncTasks[i] ; + else : + j := j + 1 ; + SyncPaths[j] := SyncPaths[i] ; + SyncTasks[j] := SyncTasks[i] ; + fi ; + endfor ; + NOfSyncPaths := j ; + fi ; + fi ; + fi ; +enddef ; + +def SyncTask(expr n) = + if known SyncTasks[n] : SyncTasks[n] else : 0 fi +enddef ; + +def FlushSyncTasks = + for i = 1 upto NOfSyncPaths : + ProcessSyncTask(SyncPaths[i], TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]])) ; + endfor ; +enddef ; + +def ProcessSyncTask(expr p, c) = + fill p withcolor c ; +enddef ; + +endinput ; diff --git a/metapost/context/base/mp-mlib.mp b/metapost/context/base/mp-mlib.mp deleted file mode 100644 index 59028640c..000000000 --- a/metapost/context/base/mp-mlib.mp +++ /dev/null @@ -1,573 +0,0 @@ -%D \module -%D [ file=mp-mlib.mp, -%D version=2008.03.21, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=plugins, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See licen-en.pdf for -%C details. - -if unknown mplib : endinput ; fi ; -if known context_mlib : endinput ; fi ; - -boolean context_mlib ; context_mlib := true ; - -%D Color and transparency - -%D Standard separable blend modes -newinternal normaltransparent ; normaltransparent := 1 ; -newinternal multiplytransparent ; multiplytransparent := 2 ; -newinternal screentransparent ; screentransparent := 3 ; -newinternal overlaytransparent ; overlaytransparent := 4 ; -newinternal softlighttransparent ; softlighttransparent := 5 ; -newinternal hardlighttransparent ; hardlighttransparent := 6 ; -newinternal colordodgetransparent ; colordodgetransparent := 7 ; -newinternal colorburntransparent ; colorburntransparent := 8 ; -newinternal darkentransparent ; darkentransparent := 9 ; -newinternal lightentransparent ; lightentransparent := 10 ; -newinternal differencetransparent ; differencetransparent := 11 ; -newinternal exclusiontransparent ; exclusiontransparent := 12 ; -%D Standard nonseparable blend modes -newinternal huetransparent ; huetransparent := 13 ; -newinternal saturationtransparent ; saturationtransparent := 14 ; -newinternal colortransparent ; colortransparent := 15 ; -newinternal luminositytransparent ; luminositytransparent := 16 ; - -vardef transparency_alternative_to_number(expr name) = - if string name : - if expandafter known scantokens(name & "transparent") : - scantokens(name & "transparent") - else : - 0 - fi - elseif name < 17 : - name - else : - 0 - fi -enddef ; - -def spotcolor(expr n, v) = - 1 - withprescript "sp_name=" & n - withprescript "sp_value=" & v -enddef ; - -def multitonecolor(expr name, fractions, components, value) = - 1 - withprescript "sp_name=" & name - withprescript "sp_fractions=" & decimal fractions - withprescript "sp_components=" & components - withprescript "sp_value=" & value -enddef ; - -def transparent(expr alternative, transparency)(text c) = - 1 % this permits withcolor x intoshade y - withprescript "tr_alternative=" & decimal transparency_alternative_to_number(alternative) - withprescript "tr_transparency=" & decimal transparency - withcolor c -enddef ; - -def withtransparency(expr alternative, transparency) = - withprescript "tr_alternative=" & decimal transparency_alternative_to_number(alternative) - withprescript "tr_transparency=" & decimal transparency -enddef ; - -def cmyk(expr c, m, y, k) = - (c,m,y,k) -enddef ; - -% Texts - -numeric _tt_w_[], _tt_h_[], _tt_d_[] ; -numeric _tt_n_ ; _tt_n_ := 0 ; -picture _tt_p_ ; _tt_p_ := nullpicture ; -boolean _trial_run_ ; _trial_run_ := false ; - -def resettextexts = - _tt_n_ := 0 ; - _tt_p_ := nullpicture ; -enddef ; - -def flushtextexts = - addto currentpicture also _tt_p_ -enddef ; - -extra_endfig := "flushtextexts;" & extra_endfig; -extra_beginfig := extra_beginfig & "resettextexts;"; - -% We collect and flush them all, as we can also have temporary textexts -% that gets never really flushed but are used for calculations. So, we -% flush twice: once in location in order to pick up e.g. color properties, -% and once at the end because we need to flush missing ones. - -vardef rawtextext(expr str) = - if str = "" : - nullpicture - elseif _trial_run_ : - _tt_n_ := _tt_n_ + 1 ; - addto _tt_p_ doublepath unitsquare - withprescript "tx_number=" & decimal _tt_n_ - withprescript "tx_stage=extra" - withpostscript str ; - image ( - addto currentpicture doublepath unitsquare - withprescript "tx_number=" & decimal _tt_n_ - withprescript "tx_stage=trial" - withpostscript str - ) - else : - _tt_n_ := _tt_n_ + 1 ; - if known _tt_d_[_tt_n_] : - image ( - addto currentpicture doublepath unitsquare - xscaled _tt_w_[_tt_n_] - yscaled (_tt_h_[_tt_n_] + _tt_d_[_tt_n_]) - withprescript "tx_number=" & decimal _tt_n_ - withprescript "tx_stage=final" - ; % withpostscript str ; - ) shifted (0,-_tt_d_[_tt_n_]) - else : - image ( - addto currentpicture doublepath unitsquare ; - ) - fi - fi -enddef ; - -% More text - -pair laboff.d, laboff.dlft, laboff.drt ; % new positional suffixes -pair laboff.origin, laboff.raw ; % graph mess - -laboff.d := laboff ; labxf.d := labxf ; labyf.d := labyf ; -laboff.dlft := laboff.lft ; labxf.dlft := labxf.lft ; labyf.dlft := labyf.lft ; -laboff.drt := laboff.rt ; labxf.drt := labxf.rt ; labyf.drt := labyf.rt ; - -labtype := 0 ; labtype.lft := 1 ; labtype.rt := 2 ; -labtype.bot := 3 ; labtype.top := 4 ; labtype.ulft := 5 ; -labtype.urt := 6 ; labtype.llft := 7 ; labtype.lrt := 8 ; -labtype.d := 10 ; labtype.dlft := 11 ; labtype.drt := 12 ; -labtype.origin := 0 ; labtype.raw := 0 ; - -% laboff.origin = (infinity,infinity) ; labxf.origin := 0 ; labyf.origin := 0 ; -% laboff.raw = (infinity,infinity) ; labxf.raw := 0 ; labyf.raw := 0 ; - -% todo: thelabel.origin("xxxx",origin) (overflows) - -laboff.origin = (0,0) ; labxf.origin := 0 ; labyf.origin := 0 ; -laboff.raw = (0,0) ; labxf.raw := 0 ; labyf.raw := 0 ; - -pair laboff.l ; laboff.l = laboff.lft ; -pair laboff.r ; laboff.r = laboff.rt ; -pair laboff.b ; laboff.b = laboff.bot ; -pair laboff.t ; laboff.t = laboff.top ; -pair laboff.l_t ; laboff.l_t = laboff.ulft ; -pair laboff.r_t ; laboff.r_t = laboff.urt ; -pair laboff.l_b ; laboff.l_b = laboff.llft ; -pair laboff.r_b ; laboff.r_b = laboff.lrt ; -pair laboff.t_l ; laboff.t_l = laboff.ulft ; -pair laboff.t_r ; laboff.t_r = laboff.urt ; -pair laboff.b_l ; laboff.b_l = laboff.llft ; -pair laboff.b_r ; laboff.b_r = laboff.lrt ; - -numeric labxf.l ; labxf.l = labxf.lft ; -numeric labxf.r ; labxf.r = labxf.rt ; -numeric labxf.b ; labxf.b = labxf.bot ; -numeric labxf.t ; labxf.t = labxf.top ; -numeric labxf.l_t ; labxf.l_t = labxf.ulft ; -numeric labxf.r_t ; labxf.r_t = labxf.urt ; -numeric labxf.l_b ; labxf.l_b = labxf.llft ; -numeric labxf.r_b ; labxf.r_b = labxf.lrt ; -numeric labxf.t_l ; labxf.t_l = labxf.ulft ; -numeric labxf.t_r ; labxf.t_r = labxf.urt ; -numeric labxf.b_l ; labxf.b_l = labxf.llft ; -numeric labxf.b_r ; labxf.b_r = labxf.lrt ; - -numeric labyf.l ; labyf.l = labyf.lft ; -numeric labyf.r ; labyf.r = labyf.rt ; -numeric labyf.b ; labyf.b = labyf.bot ; -numeric labyf.t ; labyf.t = labyf.top ; -numeric labyf.l_t ; labyf.l_t = labyf.ulft ; -numeric labyf.r_t ; labyf.r_t = labyf.urt ; -numeric labyf.l_b ; labyf.l_b = labyf.llft ; -numeric labyf.r_b ; labyf.r_b = labyf.lrt ; -numeric labyf.t_l ; labyf.t_l = labyf.ulft ; -numeric labyf.t_r ; labyf.t_r = labyf.urt ; -numeric labyf.b_l ; labyf.b_l = labyf.llft ; -numeric labyf.b_r ; labyf.b_r = labyf.lrt ; - -numeric labtype.l ; labtype.l = labtype.lft ; -numeric labtype.r ; labtype.r = labtype.rt ; -numeric labtype.b ; labtype.b = labtype.bot ; -numeric labtype.t ; labtype.t = labtype.top ; -numeric labtype.l_t ; labtype.l_t = labtype.ulft ; -numeric labtype.r_t ; labtype.r_t = labtype.urt ; -numeric labtype.l_b ; labtype.l_b = labtype.llft ; -numeric labtype.r_b ; labtype.r_b = labtype.lrt ; -numeric labtype.t_l ; labtype.t_l = labtype.ulft ; -numeric labtype.t_r ; labtype.t_r = labtype.urt ; -numeric labtype.b_l ; labtype.b_l = labtype.llft ; -numeric labtype.b_r ; labtype.b_r = labtype.lrt ; - -vardef thetextext@#(expr p,z) = % adapted copy of thelabel@ - if string p : - thetextext@#(rawtextext(p),z) - else : - p - if (labtype@# >= 10) : shifted (0,ypart center p) fi - shifted (z + labeloffset*laboff@# - (labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p)) - fi -enddef ; - -vardef textext@#(expr txt) = - interim labeloffset := textextoffset ; - if string txt : - thetextext@#(rawtextext(txt),origin) - else : - thetextext@#(txt,origin) - fi -enddef ; - -% \starttext -% \startMPpage -% numeric value ; value = 123 ; -% label.lft(decimal value,origin) ; -% draw "oeps" infont defaultfont ; -% \stopMPpage -% \stoptext - -vardef thelabel@#(expr s, z) = - save p ; picture p ; - if picture s : - p = s ; - else : - p = textext("\definedfont[" & defaultfont & "]" & s) scaled defaultscale ; - fi ; - p shifted (z + labeloffset*laboff@# - (labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p)) -enddef; - -let normalinfont = infont ; - -primarydef str infont name = % very naughty ! - if name = "" : - textext(str) - else : - textext("\definedfont[" & name & "]" & str) - fi -enddef ; - -% Shades - -newinternal shadefactor ; shadefactor := 1 ; -pair shadeoffset ; shadeoffset := origin ; -boolean trace_shades ; trace_shades := false ; - -def set_linear_vector (suffix a,b)(expr p,n) = - if (n=1) : a := llcorner p ; b := urcorner p ; - elseif (n=2) : a := lrcorner p ; b := ulcorner p ; - elseif (n=3) : a := urcorner p ; b := llcorner p ; - elseif (n=4) : a := ulcorner p ; b := lrcorner p ; - elseif (n=5) : a := .5[ulcorner p,llcorner p] ; b := .5[urcorner p,lrcorner p] ; - elseif (n=6) : a := .5[llcorner p,lrcorner p] ; b := .5[ulcorner p,urcorner p] ; - elseif (n=7) : a := .5[lrcorner p,urcorner p] ; b := .5[llcorner p,ulcorner p] ; - elseif (n=8) : a := .5[urcorner p,ulcorner p] ; b := .5[lrcorner p,llcorner p] ; - else : a := .5[ulcorner p,llcorner p] ; b := .5[urcorner p,lrcorner p] ; - fi ; -enddef ; - -def set_circular_vector (suffix ab, r)(expr p,n) = - if (n=1) : ab := llcorner p ; - elseif (n=2) : ab := lrcorner p ; - elseif (n=3) : ab := urcorner p ; - elseif (n=4) : ab := ulcorner p ; - else : ab := center p ; r := .5r ; - fi ; -enddef ; - -def circular_shade (expr p, n, ca, cb) = - begingroup ; - save ab, r ; pair ab ; numeric r ; - r := (xpart lrcorner p - xpart llcorner p) ++ (ypart urcorner p - ypart lrcorner p) ; - set_circular_vector(ab,r)(p,n) ; - fill p withcircularshade(ab,ab,0,r,ca,cb) ; - if trace_shades : - drawarrow ab -- ab shifted (0,r) withpen pencircle scaled 1pt withcolor .5white ; - fi ; - endgroup ; -enddef ; - -def linear_shade (expr p, n, ca, cb) = - begingroup ; - save a, b, sh ; pair a, b ; - set_linear_vector(a,b)(p,n) ; - fill p withlinearshade(a,b,ca,cb) ; - if trace_shades : - drawarrow a -- b withpen pencircle scaled 1pt withcolor .5white ; - fi ; - endgroup ; -enddef ; - -def withcircularshade (expr a, b, ra, rb, ca, cb) = - withprescript "sh_type=circular" - withprescript "sh_domain=0 1" - withprescript "sh_factor=" & decimal shadefactor - withprescript "sh_color_a=" & colordecimals ca - withprescript "sh_color_b=" & colordecimals cb - withprescript "sh_center_a=" & ddecimal (a shifted shadeoffset) - withprescript "sh_center_b=" & ddecimal (b shifted shadeoffset) - withprescript "sh_radius_a=" & decimal ra - withprescript "sh_radius_b=" & decimal rb -enddef ; - -def withlinearshade (expr a, b, ca, cb) = - withprescript "sh_type=linear" - withprescript "sh_domain=0 1" - withprescript "sh_factor=" & decimal shadefactor - withprescript "sh_color_a=" & colordecimals ca - withprescript "sh_color_b=" & colordecimals cb - withprescript "sh_center_a=" & ddecimal (a shifted shadeoffset) - withprescript "sh_center_b=" & ddecimal (b shifted shadeoffset) -enddef ; - -string _defined_cs_pre_[] ; numeric _defined_cs_ ; _defined_cs_:= 0 ; -string prescript_separator ; prescript_separator := char(13) ; - -vardef define_circular_shade (expr a, b, ra, rb, ca, cb) = - _defined_cs_ := _defined_cs_ + 1 ; - _defined_cs_pre_ [_defined_cs_] := "sh_type=circular" - & prescript_separator & "sh_domain=0 1" - & prescript_separator & "sh_factor=" & decimal shadefactor - & prescript_separator & "sh_color_a=" & colordecimals ca - & prescript_separator & "sh_color_b=" & colordecimals cb - & prescript_separator & "sh_center_a=" & ddecimal (a shifted shadeoffset) - & prescript_separator & "sh_center_b=" & ddecimal (b shifted shadeoffset) - & prescript_separator & "sh_radius_a=" & decimal ra - & prescript_separator & "sh_radius_b=" & decimal rb - ; - _defined_cs_ -enddef ; - -vardef define_linear_shade (expr a, b, ca, cb) = - _defined_cs_ := _defined_cs_ + 1 ; - _defined_cs_pre_ [_defined_cs_] := "sh_type=linear" - & prescript_separator & "sh_domain=0 1" - & prescript_separator & "sh_factor=" & decimal shadefactor - & prescript_separator & "sh_color_a=" & colordecimals ca - & prescript_separator & "sh_color_b=" & colordecimals cb - & prescript_separator & "sh_center_a=" & ddecimal (a shifted shadeoffset) - & prescript_separator & "sh_center_b=" & ddecimal (b shifted shadeoffset) - ; - _defined_cs_ -enddef ; - -primarydef p withshade sc = - p withprescript _defined_cs_pre_[sc] -enddef ; - - -vardef define_sampled_linear_shade(expr a,b,n)(text t) = - _defined_cs_ := _defined_cs_ + 1 ; - _defined_cs_pre_ [_defined_cs_] := "ssh_type=linear" - & prescript_separator & "ssh_center_a=" & ddecimal (a shifted shadeoffset) - & prescript_separator & "ssh_center_b=" & ddecimal (b shifted shadeoffset) - & prescript_separator & "ssh_nofcolors=" & decimal n - & prescript_separator & "ssh_domain=" & domstr - & prescript_separator & "ssh_extend=" & extstr - & prescript_separator & "ssh_colors=" & colstr - & prescript_separator & "ssh_bounds=" & bndstr - & prescript_separator & "ssh_ranges=" & ranstr - ; - _defined_cs_ -enddef ; - -vardef define_sampled_circular_shade(expr a,b,ra,rb,n)(text t) = - _defined_cs_ := _defined_cs_ + 1 ; - _defined_cs_pre_ [_defined_cs_] := "ssh_type=circular" - & prescript_separator & "ssh_center_a=" & ddecimal (a shifted shadeoffset) - & prescript_separator & "ssh_radius_a=" & decimal ra - & prescript_separator & "ssh_center_b=" & ddecimal (b shifted shadeoffset) - & prescript_separator & "ssh_radius_b=" & decimal rb - & prescript_separator & "ssh_nofcolors=" & decimal n - & prescript_separator & "ssh_domain=" & domstr - & prescript_separator & "ssh_extend=" & extstr - & prescript_separator & "ssh_colors=" & colstr - & prescript_separator & "ssh_bounds=" & bndstr - & prescript_separator & "ssh_ranges=" & ranstr - ; - _defined_cs_ -enddef ; - -% vardef predefined_linear_shade (expr p, n, ca, cb) = -% save a, b, sh ; pair a, b ; -% set_linear_vector(a,b)(p,n) ; -% define_linear_shade (a,b,ca,cb) -% enddef ; -% -% vardef predefined_circular_shade (expr p, n, ca, cb) = -% save ab, r ; pair ab ; numeric r ; -% r := (xpart lrcorner p - xpart llcorner p) ++ (ypart urcorner p - ypart lrcorner p) ; -% set_circular_vector(ab,r)(p,n) ; -% define_circular_shade(ab,ab,0,r,ca,cb) -% enddef ; - -% NEW EXPERIMENTAL CODE - -def withlinearshading (expr a, b) = - withprescript "sh_type=linear" - withprescript "sh_domain=0 1" - withprescript "sh_factor=" & decimal shadefactor - withprescript "sh_center_a=" & ddecimal (a shifted shadeoffset) - withprescript "sh_center_b=" & ddecimal (b shifted shadeoffset) -enddef ; - -def withcircularshading (expr a, b, ra, rb) = - withprescript "sh_type=circular" - withprescript "sh_domain=0 1" - withprescript "sh_factor=" & decimal shadefactor - withprescript "sh_center_a=" & ddecimal (a shifted shadeoffset) - withprescript "sh_center_b=" & ddecimal (b shifted shadeoffset) - withprescript "sh_radius_a=" & decimal ra - withprescript "sh_radius_b=" & decimal rb -enddef ; - -def withfromshadecolor expr t = - withprescript "sh_color=into" - withprescript "sh_color_a=" & colordecimals t -enddef ; - -def withtoshadecolor expr t = - withprescript "sh_color=into" - withprescript "sh_color_b=" & colordecimals t -enddef ; - -def withshading (expr how)(text rest) = - if how = "linear" : - withlinearshading(rest) - elseif how = "circular" : - withcircularshading(rest) - else : - % nothing - fi -enddef ; - -primarydef a shadedinto b = - 1 % does not work with transparency - withprescript "sh_color=into" - withprescript "sh_color_a=" & colordecimals a - withprescript "sh_color_b=" & colordecimals b -enddef ; - -% END OF NEW - -% Graphic text (we will move code here) - -def graphictext primary t = - if _trial_run_ : - let dographictextindeed = nographictext ; - else : - let dographictextindeed = dographictext ; - fi - dographictextindeed(t) -enddef ; - -def dographictext (expr t) = - % withprescript "gt_stage=final" - begingroup ; - save figurepicture ; picture figurepicture ; - figurepicture := currentpicture ; currentpicture := nullpicture ; - currentgraphictext := currentgraphictext + 1 ; - dofinishgraphictext -enddef ; - -def nographictext (expr t) text rest = - draw unitsquare withprescript "gt_stage=trial" withpostscript t -enddef ; - -% def savegraphictext (expr str) = -% enddef ; - -% def erasegraphictextfile = -% enddef ; - -% Layers - -def onlayer primary name = - withprescript "la_name=" & name -enddef ; - - -% Figures - -% def externalfigure primary filename = -% doexternalfigure (filename) -% enddef ; -% -% def doexternalfigure (expr filename) text transformation = -% if true : % a bit incompatible esp scaled 1cm now scaled the natural size -% draw rawtextext("\externalfigure[" & filename & "]") transformation ; -% else : -% draw unitsquare transformation withprescript "fg_name=" & filename ; -% fi ; -% enddef ; - -def withmask primary filename = - withprescript "fg_mask=" & filename -enddef ; - -def externalfigure primary filename = - if false : - rawtextext("\externalfigure[" & filename & "]") - else : - image ( - addto currentpicture doublepath unitsquare - withprescript "fg_name=" & filename ; - ) -% unitsquare -% withpen pencircle scaled 0 -% withprescript "fg_name=" & filename - fi -enddef ; - -def figure primary filename = - rawtextext("\externalfigure[" & filename & "]") -enddef ; - -% Positions - -def register (expr label, width, height, offset) = - image ( - addto currentpicture doublepath unitsquare xscaled width yscaled height shifted offset - withprescript "ps_label=" & label ; - ) ; % no transformations -enddef ; - -% Housekeeping - -extra_beginfig := extra_beginfig & "currentgraphictext := 0 ; " ; -extra_endfig := extra_endfig & "finishsavingdata ; " ; -extra_endfig := extra_endfig & "resettextexts ; " ; - -boolean cmykcolors ; cmykcolors := true ; -boolean spotcolors ; spotcolors := true ; - -% Bonus - -vardef verbatim(expr str) = - ditto & "\detokenize{" & str & "}" & ditto -enddef ; - -% New - -def bitmapimage(expr xresolution, yresolution, data) = - image ( - addto currentpicture doublepath unitsquare - withprescript "bm_xresolution=" & decimal xresolution - withprescript "bm_yresolution=" & decimal yresolution - withpostscript data ; - ) -enddef ; diff --git a/metapost/context/base/mp-spec.mp b/metapost/context/base/mp-spec.mp deleted file mode 100644 index 123e75faa..000000000 --- a/metapost/context/base/mp-spec.mp +++ /dev/null @@ -1,786 +0,0 @@ -%D \module -%D [ file=mp-spec.mp, -%D version=1999.6.26, -%D title=\CONTEXT\ \METAPOST\ graphics, -%D subtitle=special extensions, -%D author=Hans Hagen, -%D date=\currentdate, -%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] -%C -%C This module is part of the \CONTEXT\ macro||package and is -%C therefore copyrighted by \PRAGMA. See licen-en.pdf for -%C details. - -% Spot colors are not handled by mptopdf ! - -% let graycolor = numeric ; -% let greycolor = numeric ; -% let withanycolor = withcolor ; - -% rgbcolor red ; red := (1,0,0) ; -% rgbcolor green ; green := (0,1,0) ; -% rgbcolor blue ; blue := (0,0,1) ; -% cmykcolor cyan ; cyan := (1,0,0,0) ; -% cmykcolor magenta ; magenta := (0,1,0,0) ; -% cmykcolor yellow ; yellow := (0,0,1,0) ; -% graycolor black ; black := 0 ; % (0) ; -% graycolor white ; white := 1 ; % (1) ; - -% primarydef p withcolor c = -% p withanycolor (c) -% enddef ; - -% fill fullcircle scaled 10cm withcolor cyan ; -% fill fullcircle scaled 7cm withcolor red ; -% fill fullcircle scaled 4cm withcolor white ; - -% (r,g,b) => cmyk : r=123 g= 1 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 -%D changes. Here we closely cooperates with the \METAPOST\ -%D to \PDF\ converter module built in \CONTEXT\ and provides -%D for instance shading. More information can be found in -%D type {supp-mpe.tex}. - -if known mplib : endinput ; fi ; -if unknown context_tool : input mp-tool ; fi ; -if known context_spec : endinput ; fi ; - -boolean context_spec ; context_spec := true ; - -numeric _special_counter_ ; _special_counter_ := 0 ; -numeric _color_counter_ ; _color_counter_ := 11 ; % < 10 reserved -numeric _special_signal_ ; _special_signal_ := 123 ; - -numeric _special_div_ ; _special_div_ := 1000 ; - -%D When set to \type {true}, shading will be supported. Some -%D day I will also write an additional directive. - -boolean _inline_specials_ ; _inline_specials_ := false ; - -%D Because we want to output only those specials that are -%D actually used in a figure, we need a bit complicated -%D bookkeeping and collection of specials. At the cost of some -%D obscurity, we now have rather efficient resources. - -string _global_specials_ ; _global_specials_ := "" ; -string _local_specials_ ; _local_specials_ := "" ; - -% vardef add_special_signal = % write the version number -% if (length _global_specials_>0) or (length _local_specials_ >0) : -% special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ ) ; -% fi ; -% enddef ; -% -% After some reported problems at the \CONTEXT\ mailing list, -% Taco's came up with: - -% TH: \quotation {Ok, got it. There is a bug in mp-spec.mp (inside metafun). -% Because of a wrapping number, it fails to recognize the fact that there -% are embedded specials at all.} The corrected definition is: - -vardef add_special_signal = % write the version number - if (length _global_specials_ <> 0) or (length _local_specials_ <> 0) : - special ("%%MetaPostSpecials: 2.0 " & decimal _special_signal_ & " " & decimal _special_div_) ; - fi ; -enddef ; - -% \quotation {It now tests for \quote {not equal to zero} instead of -% \quote {larger than zero}: because of all the included files, the -% string \type {_local_specials_} becomes longer than the maximum number -% \quote {length} can return, so it returns -32768 instead, and that is -% of course less than zero.} - -vardef add_extra_specials = - scantokens _global_specials_ ; - scantokens _local_specials_ ; -enddef ; - -vardef reset_extra_specials = - % only local ones - _local_specials_ := "" ; -enddef ; - -boolean insidefigure ; insidefigure := false ; - -% todo: alleen als special gebruikt flush - -extra_beginfig := - " insidefigure := true ; " & - " reset_extra_specials ; " & - extra_beginfig & - " ; " ; - -extra_endfig := - " ; " & - " add_special_signal ; " & - extra_endfig & - " add_extra_specials ; " & - " reset_extra_specials ; " & - " insidefigure := false ; " ; - -def set_extra_special (expr s) = - if insidefigure : - _local_specials_ := _local_specials_ & s ; - else : - _global_specials_ := _global_specials_ & s ; - fi -enddef ; - -def flush_special (expr typ, siz, dat) = - _special_counter_ := _special_counter_ + 1 ; - if _inline_specials_ : - set_extra_special - ( "special " - & "(" & ditto - & dat & " " - & decimal _special_counter_ & " " - & decimal typ & " " - & decimal siz - & " special" - & ditto & ");" ) ; - else : - set_extra_special - ( "special " - & "(" & ditto - & "%%MetaPostSpecial: " - & decimal siz & " " - & dat & " " - & decimal _special_counter_ & " " - & decimal typ - & ditto & ");" ) ; - fi ; -enddef ; - -%D The next hack is needed in case you use a version of -%D \METAPOST\ that does not provide you the means to configure -%D the buffer size. Patrick Gundlach suggested to use arrays -%D in this case. - -boolean bufferhack ; bufferhack := false ; % true ; - -if bufferhack : - - string _global_specials_[] ; numeric _nof_global_specials_ ; - string _local_specials_[] ; numeric _nof_local_specials_ ; - - _nof_global_specials_ := _nof_local_specials_ := 0 ; - - vardef add_special_signal = % write the version number - if (_nof_global_specials_>0) or (_nof_local_specials_>0) : - special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ ) ; - fi ; - enddef ; - - vardef add_extra_specials = - for i=1 upto _nof_global_specials_ : - scantokens _global_specials_[i] ; - endfor; - for i=1 upto _nof_local_specials_ : - scantokens _local_specials_[i] ; - endfor; - enddef ; - - vardef reset_extra_specials = - string _local_specials_[] ; _nof_local_specials_ := 0 ; - enddef ; - - def set_extra_special (expr s) = - if insidefigure : - _local_specials_[incr(_nof_local_specials_)] := s ; - else : - _global_specials_[incr(_nof_global_specials_)] := s ; - fi - enddef ; - -fi ; - -%D So far for this hack. - -%D Shade allocation. - -newinternal shadefactor ; shadefactor := 1 ; - -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) ) ; -% _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 ) ; -% _special_counter_ -% enddef ; - -% these tests are not yet robust for new gray/cmyk features; -% -% - we need to get rid of cmykcolor() and - -vardef _is_cmyk_(expr c) = - (redpart c = _special_signal_/_special_div_) and (greenpart c = 1/_special_div_) -enddef ; -vardef _is_spot_(expr c) = - (redpart c = _special_signal_/_special_div_) and (greenpart c = 2/_special_div_) -enddef ; -vardef _is_gray_(expr c) = - (redpart c = greenpart c) and (greenpart c = bluepart c) -enddef ; - -numeric mp_shade_version ; mp_shade_version := 2 ; % more colors, needs new backend - -vardef define_linear_shade (expr a, b, ca, cb) = - save cmyk_a, cmyk_b ; boolean cmyk_a, cmyk_b ; - save gray_a, gray_b ; boolean gray_a, gray_b ; - cmyk_a := _is_cmyk_(ca) ; gray_a := _is_gray_(ca) ; - cmyk_b := _is_cmyk_(cb) ; gray_b := _is_gray_(cb) ; - if (mp_shade_version > 1) and cmyk_a and cmyk_b : - flush_special(32, 17, "0 1 " & decimal shadefactor & " " & - cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & - cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ; - elseif (mp_shade_version > 1) and cmyk_a and gray_b : - save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart cb) ; - flush_special(32, 17, "0 1 " & decimal shadefactor & " " & - cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & - cmykcolorpattern[bluepart cg] & " " & ddecimal (b shifted shadeoffset) ) ; - elseif (mp_shade_version > 1) and gray_a and cmyk_b : - save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart ca) ; - flush_special(32, 17, "0 1 " & decimal shadefactor & " " & - cmykcolorpattern[bluepart cg] & " " & ddecimal (a shifted shadeoffset) & " " & - cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ; - elseif (mp_shade_version > 1) and _is_spot_(ca) and _is_spot_(cb) : - flush_special(34, 17, "0 1 " & decimal shadefactor & " " & - spotcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & - spotcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ; - else : - flush_special(30, 15, "0 1 " & decimal shadefactor & " " & - dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & - dddecimal cb & " " & ddecimal (b shifted shadeoffset) ) ; - fi ; - _special_counter_ -enddef ; - -vardef define_circular_shade (expr a, b, ra, rb, ca, cb) = - save cmyk_a, cmyk_b ; boolean cmyk_a, cmyk_b ; - save gray_a, gray_b ; boolean gray_a, gray_b ; - cmyk_a := _is_cmyk_(ca) ; gray_a := _is_gray_(ca) ; - cmyk_b := _is_cmyk_(cb) ; gray_b := _is_gray_(cb) ; - if (mp_shade_version > 1) and cmyk_a and cmyk_b : - flush_special(33, 19, "0 1 " & decimal shadefactor & " " & - cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & - cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; - elseif (mp_shade_version > 1) and cmyk_a and gray_b : - save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart cb) ; - flush_special(33, 19, "0 1 " & decimal shadefactor & " " & - cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & - cmykcolorpattern[bluepart cg] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; - elseif (mp_shade_version > 1) and gray_a and cmyk_b : - save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart ca) ; - flush_special(33, 19, "0 1 " & decimal shadefactor & " " & - cmykcolorpattern[bluepart cg] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & - cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; - elseif (mp_shade_version > 1) and _is_spot_(ca) and _is_spot_(cb) : - flush_special(35, 19, "0 1 " & decimal shadefactor & " " & - spotcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & - spotcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; - else : - flush_special(31, 17, "0 1 " & decimal shadefactor & " " & - dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & - dddecimal cb & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; - fi ; - _special_counter_ -enddef ; - -%D A few predefined shading macros. - -boolean trace_shades ; trace_shades := false ; - -% if (n=1) : a := llcorner p ; b := urcorner p ; -% elseif (n=2) : a := llcorner p ; b := ulcorner p ; -% elseif (n=3) : a := lrcorner p ; b := ulcorner p ; -% else : a := llcorner p ; b := lrcorner p ; -% fi ; - -def set_linear_vector (suffix a,b)(expr p,n) = - if (n=1) : a := llcorner p ; - b := urcorner p ; - elseif (n=2) : a := lrcorner p ; - b := ulcorner p ; - elseif (n=3) : a := urcorner p ; - b := llcorner p ; - elseif (n=4) : a := ulcorner p ; - b := lrcorner p ; - elseif (n=5) : a := .5[ulcorner p,llcorner p] ; - b := .5[urcorner p,lrcorner p] ; - elseif (n=6) : a := .5[llcorner p,lrcorner p] ; - b := .5[ulcorner p,urcorner p] ; - elseif (n=7) : a := .5[lrcorner p,urcorner p] ; - b := .5[llcorner p,ulcorner p] ; - elseif (n=8) : a := .5[urcorner p,ulcorner p] ; - b := .5[lrcorner p,llcorner p] ; - else : a := .5[ulcorner p,llcorner p] ; - b := .5[urcorner p,lrcorner p] ; - fi ; -enddef ; - -def set_circular_vector (suffix ab, r)(expr p,n) = - if (n=1) : ab := llcorner p ; - elseif (n=2) : ab := lrcorner p ; - elseif (n=3) : ab := urcorner p ; - elseif (n=4) : ab := ulcorner p ; - else : ab := center p ; r := .5r ; - fi ; -enddef ; - -def linear_shade (expr p, n, ca, cb) = - begingroup ; - save a, b, sh ; pair a, b ; - set_linear_vector(a,b)(p,n) ; - fill p withshade define_linear_shade (a,b,ca,cb) ; - if trace_shades : - drawarrow a -- b withpen pencircle scaled 1pt withcolor .5white ; - fi ; - endgroup ; -enddef ; - -def circular_shade (expr p, n, ca, cb) = - begingroup ; - save ab, r ; pair ab ; numeric r ; - r := (xpart lrcorner p - xpart llcorner p) ++ - (ypart urcorner p - ypart lrcorner p) ; - set_circular_vector(ab,r)(p,n) ; - fill p withshade define_circular_shade(ab,ab,0,r,ca,cb) ; - if trace_shades : - drawarrow ab -- ab shifted (0,r) withpen pencircle scaled 1pt withcolor .5white ; - fi ; - endgroup ; -enddef ; - -vardef predefined_linear_shade (expr p, n, ca, cb) = - save a, b, sh ; pair a, b ; - set_linear_vector(a,b)(p,n) ; - define_linear_shade (a,b,ca,cb) -enddef ; - -vardef predefined_circular_shade (expr p, n, ca, cb) = - save ab, r ; pair ab ; numeric r ; - r := (xpart lrcorner p - xpart llcorner p) ++ (ypart urcorner p - ypart lrcorner p) ; - set_circular_vector(ab,r)(p,n) ; - define_circular_shade(ab,ab,0,r,ca,cb) -enddef ; - -%D Since a \type {fill p withshade s} syntax looks better -%D than some macro, we implement a new primary. - -primarydef p withshade sc = % == p withcolor shadecolor(sh) - hide (_color_counter_ := _color_counter_ + 1) - p withcolor (_special_signal_/_special_div_,_color_counter_/_special_div_,sc/_special_div_) -enddef ; - -vardef shadecolor(expr sc) = - hide (_color_counter_ := _color_counter_ + 1) - (_special_signal_/_special_div_,_color_counter_/_special_div_,sc/_special_div_) -enddef ; - -%D Figure inclusion. - -%numeric cef ; cef := 0 ; - -def externalfigure primary filename = - doexternalfigure (filename) -enddef ; - -def doexternalfigure (expr filename) text transformation = - begingroup ; save p, t ; picture p ; transform t ; - p := nullpicture ; t := identity transformation ; - flush_special(10, 9, - dddecimal (xxpart t, yxpart t, xypart t) & " " & - dddecimal (yypart t, xpart t, ypart t) & " " & filename) ; - addto p contour unitsquare scaled 0 ; - setbounds p to unitsquare transformed t ; - _color_counter_ := _color_counter_ + 1 ; - draw p withcolor (_special_signal_/_special_div_,_color_counter_/_special_div_,_special_counter_/_special_div_) ; - endgroup ; -enddef ; - -%D Experimental: - -%numeric currenthyperlink ; currenthyperlink := 0 ; - -def hyperlink primary t = dohyperlink(t) enddef ; -def hyperpath primary t = dohyperpath(t) enddef ; - -def dohyperlink (expr destination) text transformation = - begingroup ; save somepath ; path somepath ; - somepath := fullsquare transformation ; - dohyperpath(destination) somepath ; - endgroup ; -enddef ; - -def dohyperpath (expr destination) expr somepath = - begingroup ; - flush_special(20, 7, - ddecimal (xpart llcorner somepath, ypart llcorner somepath) & " " & - ddecimal (xpart urcorner somepath, ypart urcorner somepath) & " " & destination) ; - _color_counter_ := _color_counter_ + 1 ; - fill boundingbox unitsquare scaled 0 withcolor - (_special_signal_/_special_div_,_color_counter_/_special_div_,_special_counter_/_special_div_) ; - endgroup ; -enddef ; - -% \setupinteraction[state=start] -% \setupcolors [state=start] -% -% Hello There! \blank -% -% \startMPcode -% pickup pencircle scaled 5 ; -% draw fullcircle scaled 4cm withcolor red ; -% hyperpath "nextpage" boundingbox currentpicture ; -% draw origin withcolor blue ; -% \stopMPcode -% -% \blank Does it work or not? -% -% \startMPcode -% pickup pencircle scaled 5 ; -% draw fullcircle scaled 4cm withcolor red ; -% hyperpath "nextpage" fullcircle scaled 4cm ; -% draw origin withcolor blue ; -% draw fullcircle scaled 4cm shifted (1cm,1cm); -% \stopMPcode -% -% \blank Does it work or not? \page Hello There! \blank -% -% \startMPcode -% pickup pencircle scaled 5 ; -% draw fullcircle scaled 2cm shifted (-2cm,-1cm) ; -% draw fullcircle scaled 3cm shifted (2cm,1cm) withcolor red ; -% draw fullcircle scaled 1cm ; -% hyperlink "previouspage" scaled 3cm shifted (2cm,1cm) ; -% draw origin withcolor blue ; -% \stopMPcode -% -% \blank Does it work or not? - -_cmyk_counter_ := 0 ; - -extra_endfig := " ; resetcmykcolors ; " & extra_endfig ; - -def resetcmykcolors = - numeric cmykcolorhash[][][][] ; -enddef ; - -resetcmykcolors ; boolean cmykcolors ; cmykcolors := false ; % true - -string cmykcolorpattern[] ; % needed for transparancies - -vardef cmyk(expr c,m,y,k) = - if cmykcolors : - save ok ; boolean ok ; - if unknown cmykcolorhash[c][m][y][k] : - ok := false ; % not yet defined - elseif cmykcolorhash[c][m][y][k] = -1 : - ok := false ; % locally defined and undefined - else : - ok := true ; % globally already defined - fi ; - if not ok : -% save s ; string s ; s := dddecimal (c,m,y) & " " & decimal k ; - save s ; string s ; s := ddddecimal (c,m,y,k) ; - _cmyk_counter_ := _cmyk_counter_ + 1 ; - cmykcolorpattern[_cmyk_counter_/_special_div_] := s ; - cmykcolorhash[c][m][y][k] := _cmyk_counter_ ; - flush_special(1, 7, decimal _cmyk_counter_ & " " & s) ; - _local_specials_ := _local_specials_ & - " cmykcolorhash[" & decimal c & "][" & decimal m & - "][" & decimal y & "][" & decimal k & "] := -1 ; " ; - fi ; - (_special_signal_/_special_div_,1/_special_div_,cmykcolorhash[c][m][y][k]/_special_div_) - else : - (1-c-k,1-m-k,1-y-k) - fi -enddef ; - -% newcolor truecyan, truemagenta, trueyellow ; -% -% truecyan = (1,0,0,0) ; -% truemagenta = (0,1,0,0) ; -% trueyellow = (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) = - multitonecolor(p, 1, "", decimal s) -enddef ; - -vardef multitonecolor(expr n, f, d, p) = % name fractions names factors - if spotcolors : - save ok, pc_tag ; boolean ok ; string pc_tag ; - pc_tag := "_pct_" & n ; - if not unstringed(pc_tag) : - _spotcolor_number_ := _spotcolor_number_ + 1 ; - setunstringed(pc_tag,_spotcolor_number_) ; - fi ; - pp := getunstringed(pc_tag) ; - pc_tag := "_pct_"& decimal f & "_" & if d = "" : n else : d fi & "_" & p ; % check for d empty - if not unstringed(pc_tag) : - _spotcolor_number_ := _spotcolor_number_ + 1 ; - setunstringed(pc_tag,_spotcolor_number_) ; - fi ; - ps := getunstringed(pc_tag) ; - if unknown spotcolorhash[pp][ps] : - ok := false ; % not yet defined - elseif spotcolorhash[pp][ps] = -1 : - ok := false ; % locally defined and undefined - else : - ok := true ; % globally already defined - fi ; - if not ok : - save ss ; string ss ; ss := n & " " & decimal f & " " & if d = "" : n else : d fi & " " & p ; - _spotcolor_counter_ := _spotcolor_counter_ + 1 ; - spotcolorpattern[_spotcolor_counter_/_special_div_] := ss ; - spotcolorhash[pp][ps] := _spotcolor_counter_ ; - flush_special(2, 7, decimal _spotcolor_counter_ & " " & ss) ; - _local_specials_ := _local_specials_ & - "spotcolorhash["&decimal pp&"]["&decimal ps&"]:=-1;" ; - fi ; - (_special_signal_/_special_div_,2/_special_div_,spotcolorhash[pp][ps]/_special_div_) - else : - .5white - fi -enddef ; - -%D Transparency - -normaltransparent := 1 ; multiplytransparent := 2 ; -screentransparent := 3 ; overlaytransparent := 4 ; -softlighttransparent := 5 ; hardlighttransparent := 6 ; -colordodgetransparent := 7 ; colorburntransparent := 8 ; -darkentransparent := 9 ; lightentransparent := 10 ; -differencetransparent := 11 ; exclusiontransparent := 12 ; - -% nottransparent := 0 ; -% compatibletransparent := 99 ; - -% fill fullcircle scaled 10cm withcolor transparant(8,.3,red) ; - -vardef transparent(expr n, t, c) = - 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") : - nn := scantokens(n&"transparent") ; - else : - nn := 0 ; - fi - else : % nn := min(n,13) - nn := if n<13 : n else : nn := 0 fi ; - fi ; - % we need to expand the color (can be cmyk(..) or predefined) - cc := c ; % expand color - % check for cmyk special - is_cmyk := (redpart cc = _special_signal_/_special_div_) - and (greenpart cc = 1/_special_div_) ; - is_spot := (redpart cc = _special_signal_/_special_div_) - and (greenpart cc = 2/_special_div_) ; - % build special string, fetch cmyk components - 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 := cleanstring("tr_" & s) ; - % we now have rather unique names, i.e. a color spec of .234 becomes - % tr..._234.... and metapost gives a number overflow (parse error) - % for variables like tr_12345678 which may result from many decimal - % positions (imo mp bug) - ss := asciistring(ss) ; - % efficiency hack - if expandafter unknown scantokens(ss) : - ok := false ; % not yet defined - elseif scantokens(ss) < 0 : - ok := false ; % locally defined and undefined - else : - ok := true ; % globally already defined - fi ; - if not ok : - if is_spot : - flush_special(5, 8, 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_spot : - (_special_signal_/_special_div_,5/_special_div_,scantokens(ss)/_special_div_) - elseif is_cmyk : - (_special_signal_/_special_div_,4/_special_div_,scantokens(ss)/_special_div_) - else : - (_special_signal_/_special_div_,3/_special_div_,scantokens(ss)/_special_div_) - fi -enddef ; - -%D This function returns true of false, dependent on transparency. - -vardef is_transparent(text t) = - begingroup ; save transparent ; save _c_, _b_ ; - vardef transparent(expr nn, tt, cc) = _b_ := true ; cc enddef ; - boolean _b_ ; _b_ := false ; - color _c_ ; _c_ := t ; _b_ - endgroup -enddef ; - -% boolean _b_ ; better namespacing -% color _c_ ; -% vardef _transparent_(expr nn, tt, cc) = _b_ := true ; cc enddef ; -% vardef is_transparent(text t) = -% begingroup ; -% save transparent ; -% transparent := _transparent_ ; -% _b_ := false ; -% _c_ := t ; _b_ -% endgroup -% enddef ; - -%D This function returns the not transparent color. - -vardef not_transparent(text t) = - begingroup ; save transparent ; - vardef transparent(expr nn, tt, cc) = cc enddef ; - t endgroup -enddef ; - -%D Basic position tracking: - -def register (expr label, width, height, offset) = - begingroup ; - flush_special(50, 7, - ddecimal offset & " " & - decimal width & " " & - decimal height & " " & label) ; - 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 ; - -% just an exercise (due to a question by Chof on the context mailing list); scaling of -% 'special' colors is not possible and the next solution is incomplete (spot colors, -% transparency, etc); watch the the tricky chained macro construction - -% vardef normalgray(expr s ) = (s,s,s) enddef ; -% vardef normalrgb (expr r,g,b ) = (r,g,b) enddef ; -% vardef normalcmyk(expr c,m,y,k) = if cmykcolors : save ok ; boolean ok ; if unknown cmykcolorhash[c][m][y][k] : ok := false ; elseif cmykcolorhash[c][m][y][k] = -1 : ok := false ; else : ok := true ; fi ; if not ok : save s ; string s ; s := dddecimal (c,m,y) & " " & decimal k ; _cmyk_counter_ := _cmyk_counter_ + 1 ; cmykcolorpattern[_cmyk_counter_/_special_div_] := s ; cmykcolorhash[c][m][y][k] := _cmyk_counter_ ; flush_special(1, 7, decimal _cmyk_counter_ & " " & s) ; _local_specials_ := _local_specials_ & " cmykcolorhash[" & decimal c & "][" & decimal m & "][" & decimal y & "][" & decimal k & "] := -1 ; " ; fi ; (_special_signal_/_special_div_,1/_special_div_,cmykcolorhash[c][m][y][k]/_special_div_) else : (1-c-k,1-m-k,1-y-k) fi enddef ; - -% vardef gray(expr s) = normalgray(s ) enddef ; -% vardef rgb (expr r,g,b) = normalrgb (r,g,b ) enddef ; -% vardef cmyk(expr c,m,y,k) = normalcmyk(c,m,y,k) enddef ; - -% numeric _scaled_color_t_ ; -% color _scaled_color_c_ ; - -% def withscaledcolor = -% hide ( -% _scaled_color_t_ := 0 ; % direct -% def gray(expr s) = -% hide ( -% _gray_s_ := s ; -% _scaled_color_t_ := 1; % gray -% ) -% 0 -% enddef ; -% def rgb (expr r,g,b) = -% hide ( -% _rgb_r_ := r ; _rgb_g_ := g ; _rgb_b_ := b ; -% _scaled_color_t_ := 2 ; % rgb -% ) -% 0 -% enddef ; -% def cmyk (expr c,m,y,k) = -% hide ( -% _cmyk_c_ := c ; _cmyk_m_ := m ; _cmyk_y_ := y ; _cmyk_k_ := k ; -% _scaled_color_t_ := 3 ; % cmyk -% ) -% 0 -% enddef ; ) -% dowithscaledcolor -% enddef ; - -% def dowithscaledcolor expr t = -% hide ( -% if color t : _scaled_color_c_ := t fi ; -% vardef gray(expr s) = normalgray(s) enddef ; -% vardef rgb (expr r,g,b) = normalrgb (r,g,b) enddef ; -% vardef cmyk(expr c,m,y,k) = normalcmyk(c,m,y,k) enddef ; -% ) -% enddef ; - -% def by expr s = -% if _scaled_color_t_ = 0 : -% withcolor s*_scaled_color_c_ -% elseif _scaled_color_t_ = 1 : -% withcolor gray(s*_gray_s_) -% elseif _scaled_color_t_ = 2 : -% withcolor rgb (s*_rgb_r_, s*_rgb_g_, s*_rgb_b_) -% elseif _scaled_color_t_ = 3 : -% withcolor cmyk(s*_cmyk_c_, s*_cmyk_m_, s*_cmyk_y_, s*_cmyk_k_) -% fi -% enddef ; - -% fill fullcircle scaled 10cm withscaledcolor cmyk(0,0,1,0) by .5 ; -% fill fullcircle scaled 8cm withscaledcolor rgb (0,0,1) by .5 ; -% fill fullcircle scaled 6cm withscaledcolor gray(1) by .5 ; -% fill fullcircle scaled 4cm withscaledcolor (0,1,0) by .5 ; diff --git a/metapost/context/base/mp-spec.mpii b/metapost/context/base/mp-spec.mpii new file mode 100644 index 000000000..123e75faa --- /dev/null +++ b/metapost/context/base/mp-spec.mpii @@ -0,0 +1,786 @@ +%D \module +%D [ file=mp-spec.mp, +%D version=1999.6.26, +%D title=\CONTEXT\ \METAPOST\ graphics, +%D subtitle=special extensions, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA / Hans Hagen \& Ton Otten}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See licen-en.pdf for +%C details. + +% Spot colors are not handled by mptopdf ! + +% let graycolor = numeric ; +% let greycolor = numeric ; +% let withanycolor = withcolor ; + +% rgbcolor red ; red := (1,0,0) ; +% rgbcolor green ; green := (0,1,0) ; +% rgbcolor blue ; blue := (0,0,1) ; +% cmykcolor cyan ; cyan := (1,0,0,0) ; +% cmykcolor magenta ; magenta := (0,1,0,0) ; +% cmykcolor yellow ; yellow := (0,0,1,0) ; +% graycolor black ; black := 0 ; % (0) ; +% graycolor white ; white := 1 ; % (1) ; + +% primarydef p withcolor c = +% p withanycolor (c) +% enddef ; + +% fill fullcircle scaled 10cm withcolor cyan ; +% fill fullcircle scaled 7cm withcolor red ; +% fill fullcircle scaled 4cm withcolor white ; + +% (r,g,b) => cmyk : r=123 g= 1 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 +%D changes. Here we closely cooperates with the \METAPOST\ +%D to \PDF\ converter module built in \CONTEXT\ and provides +%D for instance shading. More information can be found in +%D type {supp-mpe.tex}. + +if known mplib : endinput ; fi ; +if unknown context_tool : input mp-tool ; fi ; +if known context_spec : endinput ; fi ; + +boolean context_spec ; context_spec := true ; + +numeric _special_counter_ ; _special_counter_ := 0 ; +numeric _color_counter_ ; _color_counter_ := 11 ; % < 10 reserved +numeric _special_signal_ ; _special_signal_ := 123 ; + +numeric _special_div_ ; _special_div_ := 1000 ; + +%D When set to \type {true}, shading will be supported. Some +%D day I will also write an additional directive. + +boolean _inline_specials_ ; _inline_specials_ := false ; + +%D Because we want to output only those specials that are +%D actually used in a figure, we need a bit complicated +%D bookkeeping and collection of specials. At the cost of some +%D obscurity, we now have rather efficient resources. + +string _global_specials_ ; _global_specials_ := "" ; +string _local_specials_ ; _local_specials_ := "" ; + +% vardef add_special_signal = % write the version number +% if (length _global_specials_>0) or (length _local_specials_ >0) : +% special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ ) ; +% fi ; +% enddef ; +% +% After some reported problems at the \CONTEXT\ mailing list, +% Taco's came up with: + +% TH: \quotation {Ok, got it. There is a bug in mp-spec.mp (inside metafun). +% Because of a wrapping number, it fails to recognize the fact that there +% are embedded specials at all.} The corrected definition is: + +vardef add_special_signal = % write the version number + if (length _global_specials_ <> 0) or (length _local_specials_ <> 0) : + special ("%%MetaPostSpecials: 2.0 " & decimal _special_signal_ & " " & decimal _special_div_) ; + fi ; +enddef ; + +% \quotation {It now tests for \quote {not equal to zero} instead of +% \quote {larger than zero}: because of all the included files, the +% string \type {_local_specials_} becomes longer than the maximum number +% \quote {length} can return, so it returns -32768 instead, and that is +% of course less than zero.} + +vardef add_extra_specials = + scantokens _global_specials_ ; + scantokens _local_specials_ ; +enddef ; + +vardef reset_extra_specials = + % only local ones + _local_specials_ := "" ; +enddef ; + +boolean insidefigure ; insidefigure := false ; + +% todo: alleen als special gebruikt flush + +extra_beginfig := + " insidefigure := true ; " & + " reset_extra_specials ; " & + extra_beginfig & + " ; " ; + +extra_endfig := + " ; " & + " add_special_signal ; " & + extra_endfig & + " add_extra_specials ; " & + " reset_extra_specials ; " & + " insidefigure := false ; " ; + +def set_extra_special (expr s) = + if insidefigure : + _local_specials_ := _local_specials_ & s ; + else : + _global_specials_ := _global_specials_ & s ; + fi +enddef ; + +def flush_special (expr typ, siz, dat) = + _special_counter_ := _special_counter_ + 1 ; + if _inline_specials_ : + set_extra_special + ( "special " + & "(" & ditto + & dat & " " + & decimal _special_counter_ & " " + & decimal typ & " " + & decimal siz + & " special" + & ditto & ");" ) ; + else : + set_extra_special + ( "special " + & "(" & ditto + & "%%MetaPostSpecial: " + & decimal siz & " " + & dat & " " + & decimal _special_counter_ & " " + & decimal typ + & ditto & ");" ) ; + fi ; +enddef ; + +%D The next hack is needed in case you use a version of +%D \METAPOST\ that does not provide you the means to configure +%D the buffer size. Patrick Gundlach suggested to use arrays +%D in this case. + +boolean bufferhack ; bufferhack := false ; % true ; + +if bufferhack : + + string _global_specials_[] ; numeric _nof_global_specials_ ; + string _local_specials_[] ; numeric _nof_local_specials_ ; + + _nof_global_specials_ := _nof_local_specials_ := 0 ; + + vardef add_special_signal = % write the version number + if (_nof_global_specials_>0) or (_nof_local_specials_>0) : + special ("%%MetaPostSpecials: 1.0 " & decimal _special_signal_ ) ; + fi ; + enddef ; + + vardef add_extra_specials = + for i=1 upto _nof_global_specials_ : + scantokens _global_specials_[i] ; + endfor; + for i=1 upto _nof_local_specials_ : + scantokens _local_specials_[i] ; + endfor; + enddef ; + + vardef reset_extra_specials = + string _local_specials_[] ; _nof_local_specials_ := 0 ; + enddef ; + + def set_extra_special (expr s) = + if insidefigure : + _local_specials_[incr(_nof_local_specials_)] := s ; + else : + _global_specials_[incr(_nof_global_specials_)] := s ; + fi + enddef ; + +fi ; + +%D So far for this hack. + +%D Shade allocation. + +newinternal shadefactor ; shadefactor := 1 ; + +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) ) ; +% _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 ) ; +% _special_counter_ +% enddef ; + +% these tests are not yet robust for new gray/cmyk features; +% +% - we need to get rid of cmykcolor() and + +vardef _is_cmyk_(expr c) = + (redpart c = _special_signal_/_special_div_) and (greenpart c = 1/_special_div_) +enddef ; +vardef _is_spot_(expr c) = + (redpart c = _special_signal_/_special_div_) and (greenpart c = 2/_special_div_) +enddef ; +vardef _is_gray_(expr c) = + (redpart c = greenpart c) and (greenpart c = bluepart c) +enddef ; + +numeric mp_shade_version ; mp_shade_version := 2 ; % more colors, needs new backend + +vardef define_linear_shade (expr a, b, ca, cb) = + save cmyk_a, cmyk_b ; boolean cmyk_a, cmyk_b ; + save gray_a, gray_b ; boolean gray_a, gray_b ; + cmyk_a := _is_cmyk_(ca) ; gray_a := _is_gray_(ca) ; + cmyk_b := _is_cmyk_(cb) ; gray_b := _is_gray_(cb) ; + if (mp_shade_version > 1) and cmyk_a and cmyk_b : + flush_special(32, 17, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & + cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ; + elseif (mp_shade_version > 1) and cmyk_a and gray_b : + save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart cb) ; + flush_special(32, 17, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & + cmykcolorpattern[bluepart cg] & " " & ddecimal (b shifted shadeoffset) ) ; + elseif (mp_shade_version > 1) and gray_a and cmyk_b : + save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart ca) ; + flush_special(32, 17, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart cg] & " " & ddecimal (a shifted shadeoffset) & " " & + cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ; + elseif (mp_shade_version > 1) and _is_spot_(ca) and _is_spot_(cb) : + flush_special(34, 17, "0 1 " & decimal shadefactor & " " & + spotcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & + spotcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) ) ; + else : + flush_special(30, 15, "0 1 " & decimal shadefactor & " " & + dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & + dddecimal cb & " " & ddecimal (b shifted shadeoffset) ) ; + fi ; + _special_counter_ +enddef ; + +vardef define_circular_shade (expr a, b, ra, rb, ca, cb) = + save cmyk_a, cmyk_b ; boolean cmyk_a, cmyk_b ; + save gray_a, gray_b ; boolean gray_a, gray_b ; + cmyk_a := _is_cmyk_(ca) ; gray_a := _is_gray_(ca) ; + cmyk_b := _is_cmyk_(cb) ; gray_b := _is_gray_(cb) ; + if (mp_shade_version > 1) and cmyk_a and cmyk_b : + flush_special(33, 19, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + elseif (mp_shade_version > 1) and cmyk_a and gray_b : + save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart cb) ; + flush_special(33, 19, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + cmykcolorpattern[bluepart cg] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + elseif (mp_shade_version > 1) and gray_a and cmyk_b : + save cg ; color cg ; cg := cmyk(0,0,0,1-greenpart ca) ; + flush_special(33, 19, "0 1 " & decimal shadefactor & " " & + cmykcolorpattern[bluepart cg] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + cmykcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + elseif (mp_shade_version > 1) and _is_spot_(ca) and _is_spot_(cb) : + flush_special(35, 19, "0 1 " & decimal shadefactor & " " & + spotcolorpattern[bluepart ca] & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + spotcolorpattern[bluepart cb] & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + else : + flush_special(31, 17, "0 1 " & decimal shadefactor & " " & + dddecimal ca & " " & ddecimal (a shifted shadeoffset) & " " & decimal ra & " " & + dddecimal cb & " " & ddecimal (b shifted shadeoffset) & " " & decimal rb ) ; + fi ; + _special_counter_ +enddef ; + +%D A few predefined shading macros. + +boolean trace_shades ; trace_shades := false ; + +% if (n=1) : a := llcorner p ; b := urcorner p ; +% elseif (n=2) : a := llcorner p ; b := ulcorner p ; +% elseif (n=3) : a := lrcorner p ; b := ulcorner p ; +% else : a := llcorner p ; b := lrcorner p ; +% fi ; + +def set_linear_vector (suffix a,b)(expr p,n) = + if (n=1) : a := llcorner p ; + b := urcorner p ; + elseif (n=2) : a := lrcorner p ; + b := ulcorner p ; + elseif (n=3) : a := urcorner p ; + b := llcorner p ; + elseif (n=4) : a := ulcorner p ; + b := lrcorner p ; + elseif (n=5) : a := .5[ulcorner p,llcorner p] ; + b := .5[urcorner p,lrcorner p] ; + elseif (n=6) : a := .5[llcorner p,lrcorner p] ; + b := .5[ulcorner p,urcorner p] ; + elseif (n=7) : a := .5[lrcorner p,urcorner p] ; + b := .5[llcorner p,ulcorner p] ; + elseif (n=8) : a := .5[urcorner p,ulcorner p] ; + b := .5[lrcorner p,llcorner p] ; + else : a := .5[ulcorner p,llcorner p] ; + b := .5[urcorner p,lrcorner p] ; + fi ; +enddef ; + +def set_circular_vector (suffix ab, r)(expr p,n) = + if (n=1) : ab := llcorner p ; + elseif (n=2) : ab := lrcorner p ; + elseif (n=3) : ab := urcorner p ; + elseif (n=4) : ab := ulcorner p ; + else : ab := center p ; r := .5r ; + fi ; +enddef ; + +def linear_shade (expr p, n, ca, cb) = + begingroup ; + save a, b, sh ; pair a, b ; + set_linear_vector(a,b)(p,n) ; + fill p withshade define_linear_shade (a,b,ca,cb) ; + if trace_shades : + drawarrow a -- b withpen pencircle scaled 1pt withcolor .5white ; + fi ; + endgroup ; +enddef ; + +def circular_shade (expr p, n, ca, cb) = + begingroup ; + save ab, r ; pair ab ; numeric r ; + r := (xpart lrcorner p - xpart llcorner p) ++ + (ypart urcorner p - ypart lrcorner p) ; + set_circular_vector(ab,r)(p,n) ; + fill p withshade define_circular_shade(ab,ab,0,r,ca,cb) ; + if trace_shades : + drawarrow ab -- ab shifted (0,r) withpen pencircle scaled 1pt withcolor .5white ; + fi ; + endgroup ; +enddef ; + +vardef predefined_linear_shade (expr p, n, ca, cb) = + save a, b, sh ; pair a, b ; + set_linear_vector(a,b)(p,n) ; + define_linear_shade (a,b,ca,cb) +enddef ; + +vardef predefined_circular_shade (expr p, n, ca, cb) = + save ab, r ; pair ab ; numeric r ; + r := (xpart lrcorner p - xpart llcorner p) ++ (ypart urcorner p - ypart lrcorner p) ; + set_circular_vector(ab,r)(p,n) ; + define_circular_shade(ab,ab,0,r,ca,cb) +enddef ; + +%D Since a \type {fill p withshade s} syntax looks better +%D than some macro, we implement a new primary. + +primarydef p withshade sc = % == p withcolor shadecolor(sh) + hide (_color_counter_ := _color_counter_ + 1) + p withcolor (_special_signal_/_special_div_,_color_counter_/_special_div_,sc/_special_div_) +enddef ; + +vardef shadecolor(expr sc) = + hide (_color_counter_ := _color_counter_ + 1) + (_special_signal_/_special_div_,_color_counter_/_special_div_,sc/_special_div_) +enddef ; + +%D Figure inclusion. + +%numeric cef ; cef := 0 ; + +def externalfigure primary filename = + doexternalfigure (filename) +enddef ; + +def doexternalfigure (expr filename) text transformation = + begingroup ; save p, t ; picture p ; transform t ; + p := nullpicture ; t := identity transformation ; + flush_special(10, 9, + dddecimal (xxpart t, yxpart t, xypart t) & " " & + dddecimal (yypart t, xpart t, ypart t) & " " & filename) ; + addto p contour unitsquare scaled 0 ; + setbounds p to unitsquare transformed t ; + _color_counter_ := _color_counter_ + 1 ; + draw p withcolor (_special_signal_/_special_div_,_color_counter_/_special_div_,_special_counter_/_special_div_) ; + endgroup ; +enddef ; + +%D Experimental: + +%numeric currenthyperlink ; currenthyperlink := 0 ; + +def hyperlink primary t = dohyperlink(t) enddef ; +def hyperpath primary t = dohyperpath(t) enddef ; + +def dohyperlink (expr destination) text transformation = + begingroup ; save somepath ; path somepath ; + somepath := fullsquare transformation ; + dohyperpath(destination) somepath ; + endgroup ; +enddef ; + +def dohyperpath (expr destination) expr somepath = + begingroup ; + flush_special(20, 7, + ddecimal (xpart llcorner somepath, ypart llcorner somepath) & " " & + ddecimal (xpart urcorner somepath, ypart urcorner somepath) & " " & destination) ; + _color_counter_ := _color_counter_ + 1 ; + fill boundingbox unitsquare scaled 0 withcolor + (_special_signal_/_special_div_,_color_counter_/_special_div_,_special_counter_/_special_div_) ; + endgroup ; +enddef ; + +% \setupinteraction[state=start] +% \setupcolors [state=start] +% +% Hello There! \blank +% +% \startMPcode +% pickup pencircle scaled 5 ; +% draw fullcircle scaled 4cm withcolor red ; +% hyperpath "nextpage" boundingbox currentpicture ; +% draw origin withcolor blue ; +% \stopMPcode +% +% \blank Does it work or not? +% +% \startMPcode +% pickup pencircle scaled 5 ; +% draw fullcircle scaled 4cm withcolor red ; +% hyperpath "nextpage" fullcircle scaled 4cm ; +% draw origin withcolor blue ; +% draw fullcircle scaled 4cm shifted (1cm,1cm); +% \stopMPcode +% +% \blank Does it work or not? \page Hello There! \blank +% +% \startMPcode +% pickup pencircle scaled 5 ; +% draw fullcircle scaled 2cm shifted (-2cm,-1cm) ; +% draw fullcircle scaled 3cm shifted (2cm,1cm) withcolor red ; +% draw fullcircle scaled 1cm ; +% hyperlink "previouspage" scaled 3cm shifted (2cm,1cm) ; +% draw origin withcolor blue ; +% \stopMPcode +% +% \blank Does it work or not? + +_cmyk_counter_ := 0 ; + +extra_endfig := " ; resetcmykcolors ; " & extra_endfig ; + +def resetcmykcolors = + numeric cmykcolorhash[][][][] ; +enddef ; + +resetcmykcolors ; boolean cmykcolors ; cmykcolors := false ; % true + +string cmykcolorpattern[] ; % needed for transparancies + +vardef cmyk(expr c,m,y,k) = + if cmykcolors : + save ok ; boolean ok ; + if unknown cmykcolorhash[c][m][y][k] : + ok := false ; % not yet defined + elseif cmykcolorhash[c][m][y][k] = -1 : + ok := false ; % locally defined and undefined + else : + ok := true ; % globally already defined + fi ; + if not ok : +% save s ; string s ; s := dddecimal (c,m,y) & " " & decimal k ; + save s ; string s ; s := ddddecimal (c,m,y,k) ; + _cmyk_counter_ := _cmyk_counter_ + 1 ; + cmykcolorpattern[_cmyk_counter_/_special_div_] := s ; + cmykcolorhash[c][m][y][k] := _cmyk_counter_ ; + flush_special(1, 7, decimal _cmyk_counter_ & " " & s) ; + _local_specials_ := _local_specials_ & + " cmykcolorhash[" & decimal c & "][" & decimal m & + "][" & decimal y & "][" & decimal k & "] := -1 ; " ; + fi ; + (_special_signal_/_special_div_,1/_special_div_,cmykcolorhash[c][m][y][k]/_special_div_) + else : + (1-c-k,1-m-k,1-y-k) + fi +enddef ; + +% newcolor truecyan, truemagenta, trueyellow ; +% +% truecyan = (1,0,0,0) ; +% truemagenta = (0,1,0,0) ; +% trueyellow = (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) = + multitonecolor(p, 1, "", decimal s) +enddef ; + +vardef multitonecolor(expr n, f, d, p) = % name fractions names factors + if spotcolors : + save ok, pc_tag ; boolean ok ; string pc_tag ; + pc_tag := "_pct_" & n ; + if not unstringed(pc_tag) : + _spotcolor_number_ := _spotcolor_number_ + 1 ; + setunstringed(pc_tag,_spotcolor_number_) ; + fi ; + pp := getunstringed(pc_tag) ; + pc_tag := "_pct_"& decimal f & "_" & if d = "" : n else : d fi & "_" & p ; % check for d empty + if not unstringed(pc_tag) : + _spotcolor_number_ := _spotcolor_number_ + 1 ; + setunstringed(pc_tag,_spotcolor_number_) ; + fi ; + ps := getunstringed(pc_tag) ; + if unknown spotcolorhash[pp][ps] : + ok := false ; % not yet defined + elseif spotcolorhash[pp][ps] = -1 : + ok := false ; % locally defined and undefined + else : + ok := true ; % globally already defined + fi ; + if not ok : + save ss ; string ss ; ss := n & " " & decimal f & " " & if d = "" : n else : d fi & " " & p ; + _spotcolor_counter_ := _spotcolor_counter_ + 1 ; + spotcolorpattern[_spotcolor_counter_/_special_div_] := ss ; + spotcolorhash[pp][ps] := _spotcolor_counter_ ; + flush_special(2, 7, decimal _spotcolor_counter_ & " " & ss) ; + _local_specials_ := _local_specials_ & + "spotcolorhash["&decimal pp&"]["&decimal ps&"]:=-1;" ; + fi ; + (_special_signal_/_special_div_,2/_special_div_,spotcolorhash[pp][ps]/_special_div_) + else : + .5white + fi +enddef ; + +%D Transparency + +normaltransparent := 1 ; multiplytransparent := 2 ; +screentransparent := 3 ; overlaytransparent := 4 ; +softlighttransparent := 5 ; hardlighttransparent := 6 ; +colordodgetransparent := 7 ; colorburntransparent := 8 ; +darkentransparent := 9 ; lightentransparent := 10 ; +differencetransparent := 11 ; exclusiontransparent := 12 ; + +% nottransparent := 0 ; +% compatibletransparent := 99 ; + +% fill fullcircle scaled 10cm withcolor transparant(8,.3,red) ; + +vardef transparent(expr n, t, c) = + 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") : + nn := scantokens(n&"transparent") ; + else : + nn := 0 ; + fi + else : % nn := min(n,13) + nn := if n<13 : n else : nn := 0 fi ; + fi ; + % we need to expand the color (can be cmyk(..) or predefined) + cc := c ; % expand color + % check for cmyk special + is_cmyk := (redpart cc = _special_signal_/_special_div_) + and (greenpart cc = 1/_special_div_) ; + is_spot := (redpart cc = _special_signal_/_special_div_) + and (greenpart cc = 2/_special_div_) ; + % build special string, fetch cmyk components + 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 := cleanstring("tr_" & s) ; + % we now have rather unique names, i.e. a color spec of .234 becomes + % tr..._234.... and metapost gives a number overflow (parse error) + % for variables like tr_12345678 which may result from many decimal + % positions (imo mp bug) + ss := asciistring(ss) ; + % efficiency hack + if expandafter unknown scantokens(ss) : + ok := false ; % not yet defined + elseif scantokens(ss) < 0 : + ok := false ; % locally defined and undefined + else : + ok := true ; % globally already defined + fi ; + if not ok : + if is_spot : + flush_special(5, 8, 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_spot : + (_special_signal_/_special_div_,5/_special_div_,scantokens(ss)/_special_div_) + elseif is_cmyk : + (_special_signal_/_special_div_,4/_special_div_,scantokens(ss)/_special_div_) + else : + (_special_signal_/_special_div_,3/_special_div_,scantokens(ss)/_special_div_) + fi +enddef ; + +%D This function returns true of false, dependent on transparency. + +vardef is_transparent(text t) = + begingroup ; save transparent ; save _c_, _b_ ; + vardef transparent(expr nn, tt, cc) = _b_ := true ; cc enddef ; + boolean _b_ ; _b_ := false ; + color _c_ ; _c_ := t ; _b_ + endgroup +enddef ; + +% boolean _b_ ; better namespacing +% color _c_ ; +% vardef _transparent_(expr nn, tt, cc) = _b_ := true ; cc enddef ; +% vardef is_transparent(text t) = +% begingroup ; +% save transparent ; +% transparent := _transparent_ ; +% _b_ := false ; +% _c_ := t ; _b_ +% endgroup +% enddef ; + +%D This function returns the not transparent color. + +vardef not_transparent(text t) = + begingroup ; save transparent ; + vardef transparent(expr nn, tt, cc) = cc enddef ; + t endgroup +enddef ; + +%D Basic position tracking: + +def register (expr label, width, height, offset) = + begingroup ; + flush_special(50, 7, + ddecimal offset & " " & + decimal width & " " & + decimal height & " " & label) ; + 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 ; + +% just an exercise (due to a question by Chof on the context mailing list); scaling of +% 'special' colors is not possible and the next solution is incomplete (spot colors, +% transparency, etc); watch the the tricky chained macro construction + +% vardef normalgray(expr s ) = (s,s,s) enddef ; +% vardef normalrgb (expr r,g,b ) = (r,g,b) enddef ; +% vardef normalcmyk(expr c,m,y,k) = if cmykcolors : save ok ; boolean ok ; if unknown cmykcolorhash[c][m][y][k] : ok := false ; elseif cmykcolorhash[c][m][y][k] = -1 : ok := false ; else : ok := true ; fi ; if not ok : save s ; string s ; s := dddecimal (c,m,y) & " " & decimal k ; _cmyk_counter_ := _cmyk_counter_ + 1 ; cmykcolorpattern[_cmyk_counter_/_special_div_] := s ; cmykcolorhash[c][m][y][k] := _cmyk_counter_ ; flush_special(1, 7, decimal _cmyk_counter_ & " " & s) ; _local_specials_ := _local_specials_ & " cmykcolorhash[" & decimal c & "][" & decimal m & "][" & decimal y & "][" & decimal k & "] := -1 ; " ; fi ; (_special_signal_/_special_div_,1/_special_div_,cmykcolorhash[c][m][y][k]/_special_div_) else : (1-c-k,1-m-k,1-y-k) fi enddef ; + +% vardef gray(expr s) = normalgray(s ) enddef ; +% vardef rgb (expr r,g,b) = normalrgb (r,g,b ) enddef ; +% vardef cmyk(expr c,m,y,k) = normalcmyk(c,m,y,k) enddef ; + +% numeric _scaled_color_t_ ; +% color _scaled_color_c_ ; + +% def withscaledcolor = +% hide ( +% _scaled_color_t_ := 0 ; % direct +% def gray(expr s) = +% hide ( +% _gray_s_ := s ; +% _scaled_color_t_ := 1; % gray +% ) +% 0 +% enddef ; +% def rgb (expr r,g,b) = +% hide ( +% _rgb_r_ := r ; _rgb_g_ := g ; _rgb_b_ := b ; +% _scaled_color_t_ := 2 ; % rgb +% ) +% 0 +% enddef ; +% def cmyk (expr c,m,y,k) = +% hide ( +% _cmyk_c_ := c ; _cmyk_m_ := m ; _cmyk_y_ := y ; _cmyk_k_ := k ; +% _scaled_color_t_ := 3 ; % cmyk +% ) +% 0 +% enddef ; ) +% dowithscaledcolor +% enddef ; + +% def dowithscaledcolor expr t = +% hide ( +% if color t : _scaled_color_c_ := t fi ; +% vardef gray(expr s) = normalgray(s) enddef ; +% vardef rgb (expr r,g,b) = normalrgb (r,g,b) enddef ; +% vardef cmyk(expr c,m,y,k) = normalcmyk(c,m,y,k) enddef ; +% ) +% enddef ; + +% def by expr s = +% if _scaled_color_t_ = 0 : +% withcolor s*_scaled_color_c_ +% elseif _scaled_color_t_ = 1 : +% withcolor gray(s*_gray_s_) +% elseif _scaled_color_t_ = 2 : +% withcolor rgb (s*_rgb_r_, s*_rgb_g_, s*_rgb_b_) +% elseif _scaled_color_t_ = 3 : +% withcolor cmyk(s*_cmyk_c_, s*_cmyk_m_, s*_cmyk_y_, s*_cmyk_k_) +% fi +% enddef ; + +% fill fullcircle scaled 10cm withscaledcolor cmyk(0,0,1,0) by .5 ; +% fill fullcircle scaled 8cm withscaledcolor rgb (0,0,1) by .5 ; +% fill fullcircle scaled 6cm withscaledcolor gray(1) by .5 ; +% fill fullcircle scaled 4cm withscaledcolor (0,1,0) by .5 ; -- cgit v1.2.3