%%%% %%%% This file belongs to the MFTOEPS package. %%%% %%% mod div %%% length cycle pos_turn neg_turn %%% endchar ori_endchar %%% draw eofill killtext %%% draw find_BB set_BB reset_BB %%% draw draw_C normal_draw_C no_export_draw_C %%% draw fill_C normal_fill_C no_export_fill_C %%% draw clip_C normal_clip_C %%% draw write_preamble normal_write_preamble no_export_write_preamble %%% endchar write_postamble normal_write_postamble no_export_write_postamble %%% endchar g_save g_restore %%% message write_PS normal_write_PS %%% draw write_def %%% draw fix_line_width set_line_width %%% draw fix_line_join set_line_join fix_line_cap set_line_cap %%% draw fix_miter_limit set_miter_limit fix_dash set_dash %%% draw fix_fill_cmyk set_fill_cmyk fix_draw_cmyk set_draw_cmyk %%% draw fix_fill_rgb set_fill_rgb fix_draw_rgb set_draw_rgb %%% xpart norm_color %%% mode_setup ori_mode_setup eps_mode_setup EPS_mode_setup %%% draw mftoeps_default %%\vsize245mm %%\font\titfnt cmtt10 at 48 pt %%{\let\makefootline\empty \let\makeheadline\empty %%\vglue0ptplus1fill %%\centerline{\titfnt MFTOEPS.MF} %%\bigskip %%\centerline{ver. 0.68 (Tuesday, March 4th, 1997)} %%\vfill\vfill\eject} % --- % \MF format for exporting to EPS via LOG-file + AWK-like utility % --- % NAME: MFTOEPS.MF % AUTHORS: B. Jackowski, P. Pianowski, M. Ry\'cko % HISTORY: % Version 0.5 (Friday, May 5th, 1995): first public domain release % Version 0.6 (Thursday, July 27th, 1995): major revision % * macro |reset_BB| added (it was silly not to have it) % * |pickup pencircle scaled 0.4pt| performed by |no_export_write_preamble| % * `mftoeps_bhook' and `mftoeps_ehook' introduced % * `setlinecap', `setlinejoin', `setmiterlimit', and `setdash' included % * switching between no export and compatibility modes made more tidy % * colours are forced to fall into the interval [0..1] % * formatting, comments and internal naming altered % Version 0.65 (Friday, September 1st, 1995): % A lot of small changes introduced introduced during the work over % PSTOEPS and EPSTOMF converters, and over ROEX macros: % * defaults for line joins and caps changed (WARNING: incompatibility % with the version 0.6 described in proceedings of 9th European \TeX % Conference, Arnhem, Holland); now they are compatible with PostScript, % not with our predilections % * `gsave'/`grestore' grouping added (macros |g_save| and |g_restore|); % the graphic object is embedded into a `gsave'/`grestore' pair % * |set_BB| and |find_BB| available also in no-export mode % * string variable |extra_eps_setup| added % * a general purpose macro |make_list| added % * version number appears in the header of EPS file % * |reset_BB| performed by newly introduced |no_export_write_postamble| % * definitions of EPS header more robust % * macros |pos_turn|, |neg_turn|, and |is_line| more robust % * global defaults defined as in ROEX (macro |mftoeps_default|) % * code optimized, formatting slightly altered (e.g., the underscore % character ending a name appears as a superscript asterisk) % This version was released during the 9th EuroTeX meeting in Arnhem % Version 0.66 (Tuesday, September 19th, 1995): % * |find_BB| a bit more robust % * |is_line| is exactly the same as in ROEX.MF (it should have been % in version 0.65...) % This version was released during the CyrTUG-95 meeting in Moscow % Version 0.67 (Friday, October 27th, 1995): % * |miter_limit| used to be a dimen; it was my mistake (BJ), % in PostScript it is a dimensionless quantity % Version 0.68 (Tuesday, March 4th, 1997): % * |extra_preamble| and |extra_postamble| added % --- if known mftoeps: expandafter endinput fi % no double loading mftoeps:=1; vardef mftoeps_ver ="0.68" enddef; % --- % DECLARATIONS (only explicitly needed): no_export_level=0; compatibility_level=1; % constants let ori_mode_setup=mode_setup; let ori_endchar=endchar; boolean closed_path; % set by |normal_fill_C|, |normal_draw_C|, % |close_op|, and just before writing definitions % of |mid_draw_op|; checked by |mid_draw_op|; boolean dash_array_empty; % used locally by |set_dash| boolean known_yes_eps; % used by |eps_mode_setup| string extra_eps_setup; % used by |eps_mode| for last-minute adjustments extra_eps_setup=""; % usually there's nothing special to do string extra_preamble, extra_postamble; % for special comments and/or defs extra_preamble=extra_postamble=""; % usually there's nothing special to add % We follow the naming convention of The \MF{}book: % ``Private tokens always end with the underscore character.'' % Since the underscore is a rather illegible character, in a ``neat'' % printing (using MFT utility) it will appear as an superscript asterisk. %% % an innocent formatting trick: the underscore character ending a name %% % will be typeset as an superscript asterisk %% \let\oriunderscore\_ %% \newif\ifbgroupopen \bgroupopenfalse %% \def\altdblbackslash#1{\bgroup\bgroupopentrue\it#1} %% \def\optegroup{\ifbgroupopen\egroup\fi} %% \def\underscoreasasterisk#1{% %% \ifx#1\relax\optegroup^*\else\oriunderscore#1\fi} %% \def\\#1{% %% \let\_\underscoreasasterisk %% \altdblbackslash{#1\relax}\optegroup %% \let\_\oriunderscore} % --- def make_list(expr k,l) suffix s = for i_:=k upto l: if i_>k: , fi \\ s[i_] endfor enddef; % --- vardef distance(expr za,zb) = length(za-zb) enddef; % in fact, an alias % --- vardef pos_turn primary p = interim autorounding:=0; if check_turn(p)=0: show p; errhelp "I will leave the path intact, continue with crossed fingers."; errmessage "Cannot make positive turn (check_turn=0)"; elseif check_turn(p)<0: reverse fi \\ p enddef; % --- vardef neg_turn primary p = interim autorounding:=0; if check_turn(p)=0: show p; errhelp "I will leave the path intact, continue with crossed fingers."; errmessage "Cannot make negative turn (check_turn=0)"; elseif check_turn(p)>0: reverse fi \\ p enddef; % --- vardef check_turn primary p = % seems more adequate than |turningnumber| % |epsilon|=|totalweight currentpicture| after |fill unitsquare|, % |eps/epsilon=32|, i.e., we admit accuracy of 32 pixels (isn't it too many?) save r_,currentpicture; picture currentpicture; interim turningcheck:=0; interim autorounding:=0; currentpicture:=nullpicture; fill p; r_:=totalweight(currentpicture); if r_>eps: 1 elseif r_<-eps: -1 else: turningnumber(p) fi enddef; % --- vardef is_line(expr B) = % checks if a B\'ezier segment |B| is an almost straight line; % recall that |z reflectedabout (origin,right)=1/z| for a complex % number |z| such that |length(z)=1|; recall also that the multiplication % of complex numbers (|zscale| operation) implies the addition of % their angle arguments save pa_,pb_,pc_,pd_,ba_,da_,dc_; pair pa_,pb_,pc_,pd_,ba_,da_,dc_; pa_:=point 0 of B; pd_:=point 1 of B; if distance(pa_,pd_)"": message ":PS: " & s; fi enddef; % --- def write_P (expr op,P) = % writes a point |P| in PostScript, followed by the operation |op| write_PS bp_pair(P) & op; enddef; % --- def write_B (expr op,B) = % writes a B\'ezier segment |B| in PostScript, followed by the operation |op| write_PS bp_pair(postcontrol 0 of B) & bp_pair(precontrol 1 of B) & bp_pair(point 1 of B) & op; enddef; % --- def write_L (expr op,L) = % writes a line |L| in PostScript, followed by the operation |op| write_PS bp_pair(point 1 of L) & op; enddef; % --- vardef write_C (expr C) = % writes a B\'ezier curve |C| in PostScript followed by an operation % which depends on whether |C| is cyclic or not save ll_; ll_:= % |(length(C)-ll_,length(C)-ll_+1)| is the last segment processed if (cycle C) and ((point length(C) of C) = (point length(C)-1 of C)): 2 % artificial situation related to an old EPS2MF converter else: 1 fi; write_P(move_op,point 0 of C); for tt_:=0 upto length(C)-ll_: if is_line(subpath (tt_,tt_+1) of C): write_L(line_op,subpath (tt_,tt_+1) of C); else: write_B(bezi_op,subpath (tt_,tt_+1) of C); fi endfor if cycle C: write_PS close_op; fi enddef; % --- def no_export_fill_C text t = begingroup save rr_; picture rr_; % must not be |pp_| (see |eofill|) begingroup save currentpicture; def currentpicture = rr_ enddef; % danger! currentpicture:=nullpicture; for qq_:=t: eofill qq_; endfor endgroup; addto currentpicture also rr_; cullit; endgroup enddef; % --- def normal_fill_C text t = write_PS beg_path_op; set_fill_cmyk; for pp_:=t: write_C(pp_); write_PS mid_fill_op; closed_path:=false; endfor write_PS end_path_op; enddef; % --- def no_export_draw_C text t = for pp_:=t: draw pp_; endfor enddef; % --- def normal_draw_C text t = write_PS beg_path_op; set_draw_cmyk; set_line_width; set_line_join; set_line_cap; set_miter_limit; set_dash; for pp_:=t: write_C(pp_); write_PS mid_draw_op; closed_path:=false; endfor write_PS end_path_op; enddef; % --- def normal_clip_C text t = clipping_count:=0; % local for pp_:=t: clipping_count:=clipping_count+1; endfor if clipping_count=0: if clipping_level>0: g_restore; clipping_level:=clipping_level-1; fi else: clipping_level:=clipping_level+1; g_save; write_PS beg_path_op; for pp_:=t: write_C(pp_); write_PS mid_clip_op; endfor write_PS end_path_op; fi enddef; % --- vardef update_BC(expr C)(suffix xl,yl,xh,yh) = % updates variables |xl|, |yl|, |xh|, |yh| by finding extremal points % of a B\'ezier curve |C| if xl>xpart(point 0 of C): xl:=xpart(point 0 of C); fi if xhypart(point 0 of C): yl:=ypart(point 0 of C); fi if yh0: vv_:=ypart (point ta_ of Bx_); if vv_xh: xh:=vv_; fi tb_:=directiontime right of subpath (ta_+eps,1) of Bx_; if tb_>=0: vv_:=ypart (point tb_ of (subpath (ta_+eps,1) of Bx_)); if vv_xh: xh:=vv_; fi fi fi vv_:=ypart (point 1 of Bx_); if vv_xh: xh:=vv_; fi % ta_:=directiontime right of By_; if ta_>0: vv_:=ypart (point ta_ of By_); if vv_yh: yh:=vv_; fi tb_:=directiontime right of subpath (ta_+eps,1) of By_; if tb_>=0: vv_:=ypart (point tb_ of (subpath (ta_+eps,1) of By_)); if vv_yh: yh:=vv_; fi fi fi vv_:=ypart (point 1 of By_); if vv_yh: yh:=vv_; fi enddef; % --- % |xl|, |yl|, |xh|, and |yh| can likely be used in a program, hence % longer names: |xl_crd|, |yl_crd|, |xh_crd|, and |yh_crd|, respectively def reset_BB = xl_crd:=whatever; yl_crd:=whatever; xh_crd:=whatever; yh_crd:=whatever; enddef; % --- def find_BB text t = for CC_:=t: % |t| may be empty if unknown xl_crd: xl_crd=yl_crd=-xh_crd=-yh_crd=infinity; fi update_BC(CC_)(xl_crd,yl_crd,xh_crd,yh_crd); endfor enddef; % --- vardef llxy = (xl_crd,yl_crd) enddef; vardef urxy = (xh_crd,yh_crd) enddef; % --- def set_BB text t = % it may happen that |t| refers to the previously fixed coordinates of the % bounding box, therefore the coordinates should not be changed too early numeric xl_crd_, yl_crd_, xh_crd_, yh_crd_; for rr_:=t: % syntax trick if pair rr_: for ss_:=xpart rr_, ypart rr_: if unknown xl_crd_: xl_crd_:=ss_; elseif unknown yl_crd_: yl_crd_:=ss_; elseif unknown xh_crd_: xh_crd_:=ss_; elseif unknown yh_crd_: yh_crd_:=ss_; fi endfor else: if unknown xl_crd_: xl_crd_:=rr_; elseif unknown yl_crd_: yl_crd_:=rr_; elseif unknown xh_crd_: xh_crd_:=rr_; elseif unknown yh_crd_: yh_crd_:=rr_; fi fi endfor numeric xl_crd, yl_crd, xh_crd, yh_crd; xl_crd:=xl_crd_; yl_crd:=yl_crd_; xh_crd:=xh_crd_; yh_crd:=yh_crd_; enddef; % --- % somewhat unusual formula was employed in the definition of |bp_num| % because |(72/300)*x| is not equivalent to |72/300x|: the latter yields % better accuracy vardef bp_num primary x = decimal(scantokens("72/" & decimal(pixels_per_inch))x) enddef; vardef bp_pair primary z = bp_num(xpart(z)) & " " & bp_num(ypart(z)) & " " enddef; % --- mode_def eps_mode = proofing:=0; % no, we're not making proofs fontmaking:=0; % no, we're not making a TFM file tracingtitles:=1; % yes, show titles online pixels_per_inch:=300; % standard laser printer resolution blacker:=0; % no additional blackness fillin:=0; % no compensation for fillin o_correction:=1; % no reduction in overshoot mag:=1; % standard magnification autorounding:=0; % removing pimples is unimportant scantokens extra_eps_setup; % the user's special last-minute adjustments enddef; % --- mode_def vicar_mode = proofing:=0; % no, we're not making proofs fontmaking:=0; % no, we're not making a TFM file tracingtitles:=1; % yes, show titles online pixels_per_inch:=300; % standard laser printer resolution blacker:=0; % no additional blackness fillin:=0; % no compensation for fillin o_correction:=1; % no reduction in overshoot mag:=1; % standard magnification enddef; % --- def EPS_mode_setup = eps_mode_setup enddef; % an alias (upward compatibility) def eps_mode_setup suffix e_l = % fixing |export_level|: known_yes_eps:=(known yesEPS) or (known YESEPS) or (known yeseps); if not known_yes_eps: export_level:=no_export_level; elseif str e_l="": export_level:=compatibility_level; else: if (if known e_l: (e_l=no_export_level) or (e_l=compatibility_level) else: false fi): export_level:=e_l; else: message "Default export level assumed."; export_level:=compatibility_level; fi fi % |mode_setup| hackery (last chance to abandon exporting): if export_level<>no_export_level: if not (string mode): mode:=vicar_mode; fi % for hackers only mode_setup; % trial setup if proofing>0: export_level:=no_export_level; fi % proofing has priority fi % now either |export_level=no_export_level| % or |export_level=compatibility_level): if export_level=no_export_level: let mode_setup=ori_mode_setup; mode_setup; let endchar=ori_endchar; let write_PS=killtext; let write_preamble=no_export_write_preamble; let write_postamble=no_export_write_postamble; let fill_C=no_export_fill_C; let draw_C=no_export_draw_C; let clip_C=killtext; else: % |error_level=compatibility_level| if not (string mode): mode:=eps_mode; fi % for hackers only mode_setup; % set private mode let mode_setup=relax; % no more |mode_setup|s def endchar = % no shipping characters out scantokens extra_endchar; endgroup enddef; let write_PS=normal_write_PS; let write_preamble=normal_write_preamble; let write_postamble=normal_write_postamble; let fill_C=normal_fill_C; let draw_C=normal_draw_C; let clip_C=normal_clip_C; fi enddef; % --- def plain_new_path_op = "newpath" enddef; def plain_close_op = "closepath" enddef; def plain_move_op = "moveto" enddef; def plain_line_op = "lineto" enddef; def plain_bezi_op = "curveto" enddef; def plain_fill_op = "eofill" enddef; def plain_draw_op = "stroke" enddef; def plain_clip_op = "eoclip" enddef; def plain_set_line_width_op = "setlinewidth" enddef; def plain_set_fill_cmyk_op = "setcmykcolor" enddef; def plain_set_draw_cmyk_op = "setcmykcolor" enddef; def plain_set_line_join_op = "setlinejoin" enddef; def plain_set_line_cap_op = "setlinecap" enddef; def plain_set_miter_limit_op = "setmiterlimit" enddef; def plain_set_dash_op = "setdash" enddef; def plain_g_save_op = "gsave" enddef; def plain_g_restore_op = "grestore" enddef; % --- % there is some inconsistency between Corel and AI (it could be said that % even between Corel and Corel, and between AI and AI), therefore the code % for filling, drawing and clipping operations is somewhat messy... % --- def close_op = begingroup closed_path:=true; "" endgroup enddef; def close_path_op = "h" enddef; def move_op = "m" enddef; def line_op = "l" enddef; def bezi_op = "c" enddef; def beg_path_op = "*u" enddef; def end_path_op = "*U" enddef; let beg_fill_op=beg_path_op; def mid_fill_op = "f" enddef; def end_fill_op = "*U*f" enddef; let beg_draw_op=beg_path_op; def mid_draw_op = if closed_path: "s" else: "S" fi enddef; def end_draw_op = "*U*d" enddef; let beg_clip_op=beg_path_op; def prep_clip_op = "W" enddef; % AI-oriented, here just empty def do_clip_op = "n" enddef; def mid_clip_op = close_path_op & " " & prep_clip_op & " " & do_clip_op enddef; def end_clip_op = "*U*c" enddef; def set_line_width_op = "w" enddef; def set_fill_cmyk_op = "k" enddef; def set_draw_cmyk_op = "K" enddef; def set_line_join_op = "j" enddef; def set_line_cap_op = "J" enddef; def set_miter_limit_op = "M" enddef; def set_dash_op = "d" enddef; def g_save_op = "q" enddef; def g_restore_op = "Q" enddef; % --- def mark_null = "/oper_kind -1 def" enddef; def mark_fill = "/oper_kind 0 def" enddef; def mark_draw = "/oper_kind 1 def" enddef; def mark_clip = "/oper_kind 2 def" enddef; def check_fill = "0 oper_kind eq" enddef; def check_draw = "1 oper_kind eq" enddef; def check_clip = "2 oper_kind eq" enddef; % --- def write_def(expr p,q) = if p<>"": write_PS "/" & p & " {" & q & "} def"; fi enddef; % --- def no_export_write_preamble expr s = pickup pencircle scaled 0.4pt; enddef; def normal_write_preamble expr s = message "generating " & s & ".eps"; if unknown testing: batchmode; % don't write mess to the terminal fi message ":EPS FILE NAME: " & s; write_PS "%!PS-Adobe-2.0 EPSF-2.0"; write_PS "%%Creator: MFTOEPS ver. " & mftoeps_ver; if (known xl_crd) and (known yl_crd) and (known xh_crd) and (known yh_crd): write_PS "%%BoundingBox: " & bp_num(xl_crd) & " " & bp_num(yl_crd) & " " & bp_num(xh_crd) & " " & bp_num(yh_crd); else: xl_crd:=0; xh_crd:=72bp; yl_crd:=0; yh_crd:=72bp; if unknown testing: errorstopmode; % switch temporarily to the usual mode fi message "Unknown bounding box (0 0 72 72 assumed)"; if unknown testing: batchmode; % again don't write mess to the terminal fi write_PS "%%BoundingBox: 0 0 72 72"; fi write_PS "%%Title: " & s & ".eps"; write_PS "%%CreationDate: " & decimal(day) & "." if month<10: & "0" fi & decimal(month) & "." & decimal(year) & " " & decimal(time div 60) & ":" if (time mod 60)<10: & "0" fi & decimal(time mod 60); write_PS "%%DocumentStyle: compatibility " & "(CorelDRAW! & Adobe Illustrator oriented)"; write_PS "%%DocumentFonts:"; write_PS "%%EndComments"; write_PS "%%BeginProlog"; write_PS "/mftoeps_export 100 dict def % you may wish to add some entries"; write_PS "mftoeps_export begin"; write_def (close_op,plain_close_op); write_def (close_path_op,plain_close_op); write_def (move_op,plain_move_op); write_def (bezi_op,plain_bezi_op); write_def (line_op,plain_line_op); write_def (set_fill_cmyk_op,plain_set_fill_cmyk_op); write_def (set_draw_cmyk_op,plain_set_draw_cmyk_op); write_def (beg_path_op,mark_null); write_def (end_path_op, end_fill_op & " " & end_draw_op & " " & end_clip_op); write_def (mid_fill_op,mark_fill); write_def (end_fill_op,check_fill & " {" & plain_fill_op & "} if") closed_path:=true; write_def (mid_draw_op, plain_close_op & " " & mark_draw); closed_path:=false; write_def (mid_draw_op, mark_draw); write_def (end_draw_op,check_draw & " {" & plain_draw_op & "} if") write_def (prep_clip_op,""); write_def (do_clip_op, mark_clip); write_def (end_clip_op,check_clip & " {" & plain_clip_op & " " & plain_new_path_op & "} if"); write_def (set_line_width_op,plain_set_line_width_op); write_def (set_line_join_op,plain_set_line_join_op); write_def (set_line_cap_op,plain_set_line_cap_op); write_def (set_miter_limit_op,plain_set_miter_limit_op); write_def (set_dash_op,plain_set_dash_op); write_PS "/setcmykcolor where {pop}"; write_PS " {/setcmykcolor {1 sub /mf exch def"; write_PS " 3 {mf add neg dup 0 lt {pop 0} if 3 1 roll} repeat"; write_PS " setrgbcolor} def} ifelse"; write_def (g_save_op,plain_g_save_op); write_def (g_restore_op,plain_g_restore_op); write_PS "/mftoeps_bhook where {pop mftoeps_bhook} {} ifelse"; scantokens extra_preamble; write_PS "%%EndProlog"; write_PS "%%BeginSetup"; % important structural comment write_PS "%%EndSetup"; % ditto g_save; fix_line_width 0.4pt; fix_fill_cmyk 0,0,0,1; fix_draw_cmyk 0,0,0,1; fix_line_join default_line_join; fix_line_cap default_line_cap; fix_miter_limit default_miter_limit; clipping_level:=0; fix_dash () 0; enddef; % --- def no_export_write_postamble = reset_BB; enddef; def normal_write_postamble = forever: exitif clipping_level=0; clip_C; endfor g_restore; write_PS "%%Trailer"; write_PS "/mftoeps_ehook where {pop mftoeps_ehook} {} ifelse"; scantokens extra_postamble; write_PS "end showpage"; if unknown testing: errorstopmode; % switch to the usual mode fi message ""; reset_BB; enddef; % --- def g_save = write_PS g_save_op enddef; def g_restore = write_PS g_restore_op enddef; % --- def fix_dash (text t) expr x = def current_dash_array = t enddef; current_dash_offset:=x; enddef; def set_dash = dash_array_empty:=true; write_PS "[" for dash_array:=current_dash_array: if not dash_array_empty: & " " fi & hide(dash_array_empty:=false) bp_num(dash_array) endfor & "] " & bp_num(current_dash_offset) & " " & set_dash_op; enddef; % --- def fix_line_width expr p = current_line_width:=max(p,0); pickup pencircle scaled current_line_width; enddef; def set_line_width = write_PS bp_num(if known current_line_width: current_line_width else: .5[pen_rt-pen_lft,pen_top-pen_bot] fi) & " " & set_line_width_op; enddef; % --- def fix_line_join expr p = current_line_join:= if (round(p)<0) or (round(p)>2): default_line_join else: round(p) fi; enddef; def set_line_join = write_PS decimal(if known current_line_join: current_line_join else: default_line_join fi) & " " & set_line_join_op; enddef; % --- def fix_line_cap expr p = current_line_cap:= if (round(p)<0) or (round(p)>2): default_line_cap else: round(p) fi; enddef; def set_line_cap = write_PS decimal(if known current_line_cap: current_line_cap else: default_line_cap fi) & " " & set_line_cap_op; enddef; % --- def fix_miter_limit expr p = current_miter_limit:=if p<1: default_miter_limit else: p fi; enddef; def set_miter_limit = write_PS decimal(if known current_miter_limit: current_miter_limit else: default_miter_limit fi) & " " & set_miter_limit_op; enddef; % --- def set_fill_cmyk = write_PS decimal(fill_cyan) & " " & decimal(fill_magenta) & " " & decimal(fill_yellow) & " " & decimal(fill_black) & " " & set_fill_cmyk_op; enddef; def set_draw_cmyk = write_PS decimal(draw_cyan) & " " & decimal(draw_magenta) & " " & decimal(draw_yellow) & " " & decimal(draw_black) & " " & set_draw_cmyk_op; enddef; % --- vardef norm_color expr c = min(1,max(0,c)) enddef; def fix_fill_cmyk text t = % syntax trick fill_cyan:=whatever; fill_magenta:=whatever; fill_yellow:=whatever; fill_black:=whatever; for vv_:=t: if unknown fill_cyan: fill_cyan:=norm_color vv_; elseif unknown fill_magenta: fill_magenta:=norm_color vv_; elseif unknown fill_yellow: fill_yellow:=norm_color vv_; elseif unknown fill_black: fill_black:=norm_color vv_; fi endfor enddef; def fix_draw_cmyk text t = % syntax trick draw_cyan:=whatever; draw_magenta:=whatever; draw_yellow:=whatever; draw_black:=whatever; for vv_:=t: if unknown draw_cyan: draw_cyan:=norm_color vv_; elseif unknown draw_magenta: draw_magenta:=norm_color vv_; elseif unknown draw_yellow: draw_yellow:=norm_color vv_; elseif unknown draw_black: draw_black:=norm_color vv_; fi endfor enddef; % --- def fix_fill_rgb text t = % syntax trick begingroup save R_,G_,B_; for vv_:=t: if unknown R_: R_:=norm_color vv_; elseif unknown G_: G_:=norm_color vv_; elseif unknown B_: B_:=norm_color vv_; fi endfor convert_rgb_to_cmyk(R_,G_,B_) (fill_cyan, fill_magenta, fill_yellow, fill_black); endgroup enddef; def fix_draw_rgb text t = % syntax trick begingroup save R_,G_,B_; for vv_:=t: if unknown R_: R_:=norm_color vv_; elseif unknown G_: G_:=norm_color vv_; elseif unknown B_: B_:=norm_color vv_; fi endfor convert_rgb_to_cmyk(R_,G_,B_) (draw_cyan, draw_magenta, draw_yellow, draw_black); endgroup enddef; % --- def convert_rgb_to_cmyk (expr R,G,B)(suffix C,M,Y,K) = begingroup save C_,M_,Y_,K_; C_:=1-R; M_:=1-G; Y_:=1-B; K_:=min(C_,M_,Y_); C:=min(1, max(0,C_-under_color_removal(K_))); M:=min(1, max(0,M_-under_color_removal(K_))); Y:=min(1, max(0,Y_-under_color_removal(K_))); K:=min(1, max(0,black_generation(K_))); endgroup enddef; % --- % DEFAULTS: def mftoeps_default text t = % main global defaults forsuffixes S_:=t: if str S_ = "under_color_removal": vardef under_color_removal(expr k) = 0 enddef; % modify if you know better elseif str S_ = "black_generation": vardef black_generation(expr k) = 0 enddef; % ditto elseif str S_ = "default_miter_limit": default_miter_limit:=10; % as in PostScript % incidentally, |10bp| would convert to |10.00002| during export at |300dpi| elseif str S_ = "default_line_join": default_line_join:=0; % as in PostScript elseif str S_ = "default_line_cap": default_line_cap:=0; % ditto elseif str S_ = "epsil.ang": epsil.ang:=.1; % in degrees elseif str S_ = "epsil.dist": epsil.dist:=1/10pt; % ca |2/5|pxl at |300dpi| fi endfor enddef; % mftoeps_default under_color_removal, black_generation, default_miter_limit, default_line_join, default_line_cap, epsil.ang, epsil.dist; % --- endinput; %%\end