diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-09 23:38:21 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-09 23:38:21 +0000 |
commit | 215012a8d684889983ec2c0629e1c704e6853d9c (patch) | |
tree | ebf1271bd71869069824935ae8a5678745bf8bce /Master/texmf-dist/fonts/source/lh/base/lcyrdefs.mf | |
parent | 1af3d19d6dbcbf309667d9cb4aa3cdda914914a9 (diff) |
trunk/Master/texmf-dist/fonts/source
git-svn-id: svn://tug.org/texlive/trunk@101 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/fonts/source/lh/base/lcyrdefs.mf')
-rw-r--r-- | Master/texmf-dist/fonts/source/lh/base/lcyrdefs.mf | 1403 |
1 files changed, 1403 insertions, 0 deletions
diff --git a/Master/texmf-dist/fonts/source/lh/base/lcyrdefs.mf b/Master/texmf-dist/fonts/source/lh/base/lcyrdefs.mf new file mode 100644 index 00000000000..8f7796d668f --- /dev/null +++ b/Master/texmf-dist/fonts/source/lh/base/lcyrdefs.mf @@ -0,0 +1,1403 @@ +% +% lcyrdefs.mf +% +%% Cyrillic font container with T2 encoding beta-support +% +% This file is future part of lxfonts package +% Version 3.4 // Patchlevel=0 +% (c) O.Lapko +% +% This package belongs to the public domain under conditions similar to +% those of D. E. Knuth specified for the Computer Modern family of fonts. +% In particular, only the authors are entitled to modify this file +% and to save it under the same name. +% +% Content: +% +% Cyrillic definitions and +% macros borrowed from ec fonts package (J"org Knappen) +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Content: +% +% Cyrillic startup definitions: +% cyrchar stuff +% load components absent in Computer Modern parameters files +% redefined font_setup +% Advanced cmbase's definitions +% macros for cyr letter's drawing +% macro for accent cyrbreve - cyrillic breve +% Exbase's special routines for accenting +% (borrowed part from exbase) +% Macros for processing chars twice +% (borrowed part from exbase) +% Accents which created with beginchar_twice routine +% (borrowed from exaccess) +% + +LHver_check(3,4); % like |version_check| in ec + +let lhchar=\; % `|lhchar|' should precede each character + +%if roman_ec: % for inputed exrullett.mf and exrllett.mf +% def version_check(expr e,f) = enddef; +% let ecchar=\; +%fi; + +% +% defining cyrchar stuff - chars with floating codes +% +if unknown autocount: % set auto code count for miscelaneous fonts + def cyrchar(suffix $)(expr w_sharp,h_sharp,d_sharp) = + iff known CYR_.$: beginchar(CYR_.$,w_sharp,h_sharp,d_sharp); + enddef; + + def cyrarithchar(suffix $) = + iff known CYR_.$: beginarithchar(CYR_.$); + enddef; + + def cyrchar_twice(suffix $)(expr w_sharp,h_sharp,d_sharp) = + iff known CYR_.$: beginchar_twice(CYR_.$,w_sharp,h_sharp,d_sharp); + enddef; + + def getcharcode(suffix $) = + if known CYR_.$: charcode:=CYR_.$; fi + enddef; +fi + +% next macro necessary for absent Old Slav letters in Italic fonts +def cyrcharmoving (suffix $) = if known CYR_.$: CYR_.$ := -2; fi enddef; + +% +% load components absent in parameter files +% +if unknown acc_height#: % emulation ecfonts parameter file + + if monospace: % borrowed from ectt + basedef ( 8, 9, 10, 12); + gendef[1/36pt#](acc_height#)(60, 67.5, 75, 90); + gendef[1/36pt#](dot_height#)(60, 67.5, 75, 90); + else: % borrowed from ecrm + basedef ( 5, 6, 7, 8, 9, 10, 12, 17.28); + gendef[1/36pt#](acc_height#)(42.5, 49, 55.5, 62, 68.5, 75, 90, 127.5); + gendef[1/36pt#](dot_height#)( 42, 46.6, 51.2, 56, 60.4, 66, 77.2, 100); + fi + +fi + +sbeak# := (if serifs: max(beak#,3/4desc_depth#) else: desc_depth# fi) /1.2; +cap_sbeak# := if serifs: max(beak#,3/4desc_depth#) else: desc_depth# fi; + +% +% add absent exbase parameters in cmbase's font_setup +% original font_setup macro redefined to ADD necessary settings in it's context +% +let font_setup_ = font_setup; + +if unknown true_mono: + boolean true_mono; + if monospace: true_mono:=true; % |true| forces ligatures to monowidth + else: true_mono:=false; % + fi +fi + +def font_setup = + font_setup_; + define_whole_blacker_pixels(acc_height); + define_pixels(cap_sbeak,sbeak); + pickup pencircle scaled min(hair,vair); + extra_rule.nib:=savepen; + if true_mono: let normal_adjust_fit=mono_adjust_fit; fi +enddef; + +% +% booleans for lowercase/uppercase identifying +% +boolean cyrcaph, cyrcaph.cyrcaph; +cyrcaph = false; +cyrcaph.cyrcaph = true; + +% +% advanced cmbase's definitions: macros for cyr letter's drawing +% set_bar_axis, bar_stroke +% cyr_serif, l_serif, r_serif +% cyrbulb +% cbreve + +% sets for bar axis in lowercase letters +% +vardef set_bar_axis = + pickup tiny.nib; y1.bh:=vround(.55x_height-.6[thin_join,vair]/2); + y2.bh:=y1.bh+.6[thin_join,vair]; y0.bh:=.5[y2.bh,y1.bh]; +enddef; + +vardef bar_stroke(expr left_jut,right_jut) = % |x$r| and |x$$r| (only) are known + if left_jut>right_jut: errmessage ("change `bar' points"); fi + fix_virgin z; + set_bar_axis; + if serifs: pickup crisp.nib; else: pickup fine.nib; fi + if (y2.bh-y1.bh)>(currentbreadth+eps): + pos[ii](.6[thin_join,vair],90); pos[jj](.6[thin_join,vair],90); + lft x[ii]r=left_jut; rt x[jj]r=right_jut; + top y[ii]r=top y[jj]r=y2.bh; + filldraw stroke z[ii]e--z[jj]e; % bar + else: + y[ii]l=y[jj]l=y1.bh; y[ii]r=y[jj]r=y2.bh; + x[ii]l=x[ii]r=left_jut; x[jj]l=x[jj]r=right_jut; + fill z[jj]l{right}...{left}z[jj]r--z[ii]r{left}...{right}z[ii]l--cycle; % bar + fi + penlabels([ii],[jj]); +enddef; + +% +% Cyrillic descender serif +% +vardef cyr_serif(suffix $,$$,@) % serif at |z$| for stroke from |z$$| + (expr darkness,beak_darkness,jut,beak_jut) = + if serifs: + pickup crisp.nib; + else: + pickup pencircle scaled (3/5[fine,crisp]+eps); + fi + numeric bracket_height,light_stem; pair downward; + bracket_height=bracket; + light_stem=hround (max(tiny.breadth,fudged.hair if hefty:-4stem_corr fi)); + % for cyr_serif always |y$|<|y$$| + if (y$>y$$): errmessage ("`cyr_serif' placed only on the bottom"); fi + downward=z$-z$$; + y@0=min(y$+bracket_height,y$$)+eps; + top y@1-slab-eps=bot y@4+eps=tiny.bot y$; + if y@1>y@0: y@0:=y@1+eps; fi + bot y@2=bot y@3=vround(-d); + y@5=y@1; y@6=y@0; + z@5=whatever[z$,z$$]; z@6=whatever[z$,z$$]; + if jut<0: + z@0+penoffset downward of currentpen = + z$l+penoffset downward of pen_[tiny.nib]+whatever*downward; + lft x@1=hround (tiny.lft x$l+jut)-eps; + if x@6<x@0+eps: x@6:=x@0+eps; fi + lft x@2=rt x@3-light_stem-eps=hround (lft x@1+beak_jut)-eps; + x@4=x$+.5(fudged.stem-3stem_corr-tiny)+eps; + else: + z@0-penoffset downward of currentpen = + z$r-penoffset downward of pen_[tiny.nib]-whatever*downward; + rt x@1=hround (tiny.rt x$r+jut)+eps; + if x@6>x@0-eps: x@6:=x@0-eps; fi + rt x@2=lft x@3+light_stem+eps=hround (rt x@1+beak_jut)+eps; + x@4=x$-.5(fudged.stem-3stem_corr-tiny)-eps; + fi + pair corner,beak_corner; + ypart corner=y@1; corner=z@0+whatever*downward; + ypart beak_corner=y@4; beak_corner=z@3+whatever*(z@1-z@2); + if jut<0: + filldraw z@0{z$-z$$} + ...(darkness+eps)[corner,.5[z@1,z@0]]{z@1-z@0} + ...{jut,0}z@1--z@2--z@3{z@1-z@2} + ...(beak_darkness+eps)[beak_corner,.5[z@3,z@4]] + ...{-jut,0}z@4--(x@4,y@1)--z@5--z@6--cycle; % descender + else: + filldraw z@6--z@5--(x@4,y@1)--z@4{jut,0} + ...(beak_darkness+eps)[beak_corner,.5[z@3,z@4]] + ...{z@2-z@1}z@3--z@2--z@1{-jut,0} + ...(darkness+eps)[corner,.5[z@1,z@0]]{z@0-z@1} + ...{z$$-z$}z@0--cycle; % descender + fi + labels (@0,@1,@2,@3,@4,@5,@6); +enddef; + +% +% roman descenders +% +def l_serif(suffix $,$$,@) % descender at |z$| for stroke from |z$$| + (expr left_darkness,beak_darkness,left_jut,beak_jut) + (suffix @@) + (expr right_darkness,right_jut) = + cyr_serif($,$$,@,left_darkness,beak_darkness,-left_jut,-beak_jut); + serif($,$$,@@,right_darkness,right_jut); +enddef; +% +def r_serif(suffix $,$$,@) % descender at |z$| for stroke from |z$$| + (expr left_darkness,left_jut) + (suffix @@) + (expr right_darkness,beak_darkness,right_jut,beak_jut) = + serif($,$$,@,left_darkness,-left_jut); + cyr_serif($,$$,@@,right_darkness,beak_darkness,right_jut,beak_jut); +enddef; + +% +% italic descender +% +def i_serif(suffix $,@) = % vawed italic descender + y@1=.5[y$,y@2r]; x@1r=x$r; + numeric theta,slope; + theta=angle(-max(3u,u+2curve),d); + slope=-angle(-max(2u,u+curve),d); + pos@1(.5[vair,hair],180); + pos@2(7/8[hair,curve],theta); + pos@3(vair,theta); + lft x@2r=lft x@1r+max(.5hair,1)+eps; + y@2r=-.35d; + bot y@3l=-d-oo; + z@3l=z@2l+hair*dir (if monospace: .5 fi theta)+whatever*dir slope; + filldraw stroke z$e{down}...z@1e...z@2e{down}....{dir (slope)}z@3e; + penlabels (@1,@2,@3); +enddef; + +% +% redefined bulb: ... with directions instead of -- +% +def cyrbulb(suffix $,$$,$$$) = + z$$$r=z$$r; + path_.l:=z$l{x$$r-x$r,0}...{0,y$$r-y$r}z$$l; + path p_; p_:=z$r{x$$r-x$r,0}...{0,y$$r-y$r}z$$r; + filldraw path_.l--reverse p_--cycle; % link + path_.r:=z$$$l{0,y$r-y$$r}..z$$$r{0,y$$r-y$r}; % near-circle + y_:=xpart(path_.r intersectiontimes p_); + if y_<0: y_:=1; fi + filldraw subpath(0,y_) of path_.r + {dir (angle direction y_ of p_)}...%-- + z$$r{0,y$$r-y$r}..cycle; % bulb +enddef; + +% +% cbreve accent for Cyrillic letters +% +boolean altaccent; altaccent=false; + +vardef cbreve(expr x_center,y_move, + _one,_two,_three,_four,_five,_six,_seven) suffix modifier = + numeric mid_thickness,bulb_diam; + mid_thickness=max(crisp.breadth,vround if serifs: 1/5 else: 1/3 fi[vair,stem]); + bulb_diam=max(crisp.breadth,hround(max(dot_size,cap_curve)-2stem_corr)); + pickup crisp.nib; + pos[_one](bulb_diam,0); pos[_two](bulb_diam,90); + x[_one]=x[_two]=x_center-1.75u if monospace: /expansion_factor fi; + if cyrcaph.modifier: + bot y[_six]r=vround (y_move+max( + min(cap_height+o+max(tiny,0.5mid_thickness), + cap_height+0.3acc_height), + 1/3[cap_height,min(asc_height,2x_height)]+o-.5mid_thickness + )); + top y[_two]r=vround (y_move+max( + (cap_height+dot_height#*hppp), + bot y[_six]r+mid_thickness+bulb_diam+eps + )); + else: + bot y[_six]r=vround (y_move+max( + min(x_height+o+max(tiny,0.5mid_thickness), + x_height+0.3acc_height), + if serifs: + 1/3[x_height, min(asc_height,2x_height) + -cap_height+x_height] + else: + 1/3[x_height,h] + fi + o - 0.5mid_thickness + )); + top y[_two]r=vround (y_move+max( + (x_height+dot_height#*hppp), + bot y[_six]r+mid_thickness+bulb_diam+eps + )); + fi + y[_one]=y_move+.5[y[_two]l,y[_two]r]; + pos[_three](bulb_diam,0); + penpos[_four](y[_two]r-y[_two]l,90); + y[_three]=y[_four]=y[_one]; + x[_three]=x[_four]=x[_one]+3.5u if monospace: /expansion_factor fi; + if square_dots: % no dots in sans serif cyrbreve + x[_six]=hround x_center; + lft x[_five]r=hround(x[_six]-2.5u + if monospace: /expansion_factor fi-.5vair); + rt x[_seven]r=hround(x[_six]+2.5u + if monospace: /expansion_factor fi+.5vair); + top y[_five]=top y[_seven]=h+y_move; % common for both upper and lower + if y[_six]r>(bot y[_seven]-eps): + y[_six]r:=bot y[_seven]-eps; + fi + else: + dot([_one],[_two]); % left dot + if not altaccent: + dot([_three],[_four]); % right dot + fi + x[_six]=.5[x[_one]l,x[_three]r]; + lft x[_five]r=lft x[_one]l; + rt x[_seven]r=rt x[_three]r; + top y[_five]=top y[_seven]=y[_two]; % common for both upper and lower + fi + pos[_five](vair,-180); + pos[_seven](vair,0); + pos[_six](mid_thickness,-90); + filldraw stroke z[_five]e{down} + ...z[_six]e{right} + ...{up}z[_seven]e; % stroke + penlabels ([_five],[_six],[_seven]); +enddef; + +%%% fine hi higher +% |higher| is a counterpart to |lower| (see the file excsc.mf), +% |hi| facilitates using higher values (which are reference points in +% the floating world of CM fonts) +def hi = if is_small_cap: higher fi\\ enddef; + +% +% special routines for accenting bowwowed from ecfonts but rearranged +% +%!!!lhfonts: first goes umlaut for yo +vardef lowercase_umlaut(expr x_move,y_move,umlaut_one,umlaut_two, + umlaut_three,umlaut_four) = +pickup tiny.nib; +pos[umlaut_one](udot_diam,0); +pos[umlaut_two](udot_diam,90); +x[umlaut_one]=x[umlaut_two]=x_move+.5w-1.75u if monospace:/expansion_factor fi ; +top y[umlaut_two]r=lc_trema_height; +y[umlaut_one]=y_move+.5[y[umlaut_two]l,y[umlaut_two]r]; +dot([umlaut_one],[umlaut_two]); % left dot +pos[umlaut_three](udot_diam,0); +penpos[umlaut_four](y[umlaut_two]r-y[umlaut_two]l,90); +y[umlaut_three]=y[umlaut_four]=y[umlaut_one]; +x[umlaut_three]=x[umlaut_four]=x[umlaut_one] + +3.5u if monospace: /expansion_factor fi ; +dot([umlaut_three],[umlaut_four]); % right dot +enddef; +% +vardef uppercase_umlaut(expr x_move,y_move,umlaut_one,umlaut_two, + umlaut_three,umlaut_four) = +pickup tiny.nib; +pos[umlaut_one](udot_diam,0); +pos[umlaut_two](udot_diam,90); +x[umlaut_one]=x[umlaut_two]=x_move+.5w-1.75u if monospace:/expansion_factor fi ; +top y[umlaut_two]r=vround(cap_height+dot_height#*hppp); +y[umlaut_one]=y_move+.5[y[umlaut_two]l,y[umlaut_two]r]; +dot([umlaut_one],[umlaut_two]); % left dot +pos[umlaut_three](udot_diam,0); +penpos[umlaut_four](y[umlaut_two]r-y[umlaut_two]l,90); +y[umlaut_three]=y[umlaut_four]=y[umlaut_one]; +x[umlaut_three]=x[umlaut_four]=x[umlaut_one] + +3.5u if monospace: /expansion_factor fi ; +dot([umlaut_three],[umlaut_four]); % right dot +enddef; +% +% +% breve accent used in wncyr font +% +%!!! lowercase_breve edited +vardef lowercase_breve(expr x_center,y_move,breve_one,breve_two,breve_three)= +pickup crisp.nib; pos[breve_one](vair,-180); +pos[breve_three](vair,0); +top y[breve_one]=top y[breve_three]=h; +x[breve_two]=x_center; +lft x[breve_one]r=hround(x[breve_two]-2.5u + if monospace: /expansion_factor fi -0.5vair); +rt x[breve_three]r=hround(x[breve_two]+2.5u + if monospace: /expansion_factor fi +0.5vair); +numeric mid_thickness; mid_thickness=max(crisp.breadth,vround 1/3[vair,stem]);%!!! +bot y[breve_two]r= + vround max(x_height+o+tiny,1/3[x_height,h]+o-.5mid_thickness); +if y[breve_two]r>(y[breve_one]-.5crisp-eps): %!!! + y[breve_two]r:=y[breve_one]-.5crisp-eps; fi %!!! +pos[breve_two](mid_thickness,-90); %!!! moved here after if +filldraw stroke z[breve_one]e{down}... + z[breve_two]e{right}...{up}z[breve_three]e; % stroke +enddef; +% +%!!! uppercase_breve edited +vardef uppercase_breve (expr x_center,y_move,breve_one, + breve_two,breve_three)= +pickup crisp.nib; pos[breve_one](vair,-180); +pos[breve_three](vair,0); +top y[breve_one]=top y[breve_three]=cap_height + acc_height; +x[breve_two]=hround x_center; +x[breve_two]-rt x[breve_one]l + =(lft x[breve_three]l)-x[breve_two] + =hround (2.5u if monospace: /expansion_factor fi -.5vair); +numeric mid_thickness; +mid_thickness=max(crisp.breadth,vround min(1/3[vair,stem],.5acc_height));%!!! +pos[breve_two](mid_thickness,-90); +% |accent_gap| SHOULD be defined by the acute accent, before this macro runs +if unknown accent_gap: % accent_gap emulation + if serifs: + y[breve_two]'=h-.5mid_stem+eps-max(2/3[h,hi.x_height],hi.x_height+o+hair); + accent_gap=a_ht-(y[breve_two]'+.5mid_stem)-hi.x_height; + else: + top y[breve_two]'=h-vround(2/3[h,hi.x_height]); + accent_gap=a_ht-y[breve_two]'-hi.x_height; + fi +fi +bot y[breve_two]r=cap_height + if hefty: .5 fi accent_gap; +filldraw stroke z[breve_one]e{down}...z[breve_two]e{right}... + {up}z[breve_three]e; % stroke +enddef; +% +% +% the rest of accents +% +%!!! lowercase_cedilla edited +vardef lowercase_cedilla (expr x_center,y_move, + cedi_one,cedi_two,cedi_three,cedi_four,cedi_five) = +x[cedi_one]=x_center; % .5w+.5u; +if serifs: + pickup crisp.nib; + pos[cedi_one](stem,0); + pos[cedi_two](stem,0); + pos[cedi_three](vair,90); + pos[cedi_four](stem,0); + pos[cedi_five](vair,-90); + x[cedi_one]=x[cedi_two]; + z[cedi_three]l=z[cedi_two]l; + x[cedi_four]=x[cedi_two]+1.5u; + x[cedi_five]=x[cedi_three]-1.5u; + bot y[cedi_one]=y_move;%!!! was 0 + bot y[cedi_two]=-vround 2/7d-o; + y[cedi_four]=.5[y[cedi_three],y[cedi_five]]; + bot y[cedi_five]=-d-o; + filldraw stroke z[cedi_one]e--z[cedi_two]e; % stem + filldraw stroke z[cedi_three]e{right}... + z[cedi_four]e{down}...{left}z[cedi_five]e; % hook +else: pickup fine.nib; pos[cedi_one](vair,0); top y[cedi_one]=-o-2; + pos[cedi_two](.5[vair,stem],0); + bot y[cedi_two]=-d-o; x[cedi_two]=x[cedi_one]-1.25u; + filldraw stroke z[cedi_one]e--z[cedi_two]e; fi % diagonal +enddef; +% +vardef uppercase_cedilla(expr x_center,y_move, + cedi_one,cedi_two,cedi_three,cedi_four,cedi_five) = +x[cedi_one]=x_center; +if serifs: + pickup crisp.nib; + pos[cedi_one](stem,0); + pos[cedi_two](stem,0); + pos[cedi_three](vair,90); + pos[cedi_four](stem,0); + pos[cedi_five](vair,-90); + x[cedi_one]=x[cedi_two]; + z[cedi_three]l=z[cedi_two]l; + x[cedi_four]=x[cedi_two]+1.5u if monospace: /expansion_factor fi; + x[cedi_five]=x[cedi_three]-1.5u if monospace: /expansion_factor fi; + top y[cedi_one]=y_move; + bot y[cedi_two]=-vround 2/7d-o; + y[cedi_four]=.5[y[cedi_three],y[cedi_five]]; + bot y[cedi_five]=-d-o; + filldraw stroke z[cedi_one]e--z[cedi_two]e; % stem + filldraw stroke z[cedi_three]e{right}... + z[cedi_four]e{down}...{left}z[cedi_five]e; % hook +else: pickup fine.nib; pos[cedi_one](vair,0); + top y[cedi_one]=-o-2; + pos[cedi_two](.5[vair,stem],0); + bot y[cedi_two]=-d-o; x[cedi_two] = + x[cedi_one]-1.25u if monospace: /expansion_factor fi; + filldraw stroke z[cedi_one]e--z[cedi_two]e; fi % diagonal +enddef; +% +% +%!!! uppercase_hat edited +vardef uppercase_hat + (expr x_center,y_move,hat_zero,hat_one,hat_two,hat_three,hat_four) = +if serifs: + pickup crisp.nib; + pos[hat_two](.5[vair,curve],90); + top y[hat_two]r=cap_accent_height+oo; + x[hat_two]=good.x x_center; % optically centered + x[hat_one]=good.x x[hat_two]-2.25u if monospace: /expansion_factor fi ; + x[hat_three]=2x[hat_two]-x[hat_one]; + %!!! |accent_gap| SHOULD be defined by the acute accent, before this macro runs + if unknown accent_gap: % accent_gap emulation + y[hat_one]'=h-.5mid_stem+eps-max(2/3[h,hi.x_height],hi.x_height+o+hair); + accent_gap=a_ht-(y[hat_one]'+.5mid_stem)-hi.x_height; + fi + y[hat_one]=y[hat_three] = accent_gap + cap_height; + pos[hat_one](hair,angle(z[hat_two]-z[hat_one])+90); + pos[hat_three](hair,angle(z[hat_three]-z[hat_two])+90); + filldraw stroke z[hat_one]e--z[hat_two]e--z[hat_three]e; % diagonals +else: + pickup fine.nib; + pos[hat_one](vair,0); + pos[hat_three](vair,0); + pos[hat_two](stem,0); + top y[hat_two]=cap_accent_height+oo; + x[hat_two]=good.x x_center; % optically centered + x[hat_one]=good.x x[hat_two]-2.25u if monospace: /expansion_factor fi ; + x[hat_three]=2x[hat_two]-x[hat_one]; + %!!! |accent_gap| SHOULD be defined by the acute accent, before this macro runs + if unknown accent_gap: % accent_gap emulation + top y[hat_one]'=h-vround(2/3[h,hi.x_height]); + accent_gap=a_ht-y[hat_one]'-hi.x_height; + fi + bot y[hat_one]=bot y[hat_three]=.5accent_gap + cap_height; + z[hat_zero]=whatever[z[hat_one]r,z[hat_two]r]= + whatever[z[hat_two]l,z[hat_three]l]; + y[hat_four]l=y[hat_four]r=y[hat_two]; + x[hat_four]l=hround (.2[x[hat_two]l,x[hat_two]]-eps); %!!! + x[hat_four]r=w-x[hat_four]l; + filldraw z[hat_four]l--z[hat_one]l--z[hat_one]r-- + z[hat_zero]--z[hat_three]l-- + z[hat_three]r--z[hat_four]r--cycle; fi % diagonals +enddef; +% +%!!! lowercase_hat edited +vardef lowercase_hat + (expr x_center,y_move,hat_zero,hat_one,hat_two,hat_three,hat_four) = +if serifs: + pickup crisp.nib; + pos[hat_two](.5[vair,curve],90); + top y[hat_two]r=h+y_move; + x[hat_two]=good.x x_center; % optically centered + x[hat_one]=good.x x[hat_two]-2.25u if monospace: /expansion_factor fi ; + x[hat_three]=2x[hat_two]-x[hat_one]; + y[hat_one]=y[hat_three] = + max(y[hat_two]-0.5(min(asc_height,2x_height)-x_height), + 1/6[x_height,h]); + pos[hat_one](hair,angle(z[hat_two]-z[hat_one])+90); + pos[hat_three](hair,angle(z[hat_three]-z[hat_two])+90); + filldraw stroke z[hat_one]e--z[hat_two]e--z[hat_three]e; % diagonals +else: + pickup fine.nib; + pos[hat_one](vair,0); + pos[hat_three](vair,0); + pos[hat_two](stem,0); + top y[hat_two]=h+y_move; + x[hat_two]=good.x x_center; % optically centered + x[hat_one]=good.x x[hat_two]-2.25u if monospace: /expansion_factor fi ; + x[hat_three]=2x[hat_two]-x[hat_one]; + bot y[hat_one]=bot y[hat_three]=vround (2/3[x_height+acc_height,x_height]-eps); %!!! + % same slope as in the acute accent + z[hat_zero]=whatever[z[hat_one]r,z[hat_two]r]= + whatever[z[hat_two]l,z[hat_three]l]; + y[hat_four]l=y[hat_four]r=y[hat_two]; + x[hat_four]l=hround (.2[x[hat_two]l,x[hat_two]]-eps); %!!! + x[hat_four]r=w-x[hat_four]l; + filldraw z[hat_four]l--z[hat_one]l--z[hat_one]r-- + z[hat_zero]--z[hat_three]l-- + z[hat_three]r--z[hat_four]r--cycle; fi % diagonals +enddef; +% +% +vardef lowercase_tilde(expr x_move,y_move,tilde_one,tilde_two,tilde_three, + tilde_four,tilde_five)= +h':=min(asc_height,10/7x_height+.5dot_size); +if serifs: numeric theta; + theta=angle(1/6( + 6u if monospace: /expansion_factor fi-vair), + 1/4(h'-x_height)); + pickup crisp.nib; + numeric mid_width; mid_width=.4[vair,stem]; + pos[tilde_one](vair,theta+90); + pos[tilde_two](vair,theta+90); + pos[tilde_three](vair,theta+90); + pos[tilde_four](vair,theta+90); + z[tilde_two]-z[tilde_one]= + z[tilde_four]-z[tilde_three]=(mid_width-crisp)*dir theta; + lft x[tilde_one]r=hround(x_move+0.5w-3u if monospace: /expansion_factor fi); + rt x[tilde_four]l=hround(x_move+0.5w+3u if monospace: /expansion_factor fi); + top y[tilde_four]r=h'; + pair delta; + ypart delta=3(y[tilde_three]l-y[tilde_one]l); + delta=whatever*dir theta; + bot y[tilde_one]l=vround(bot y[tilde_one]l+ + min(2/3[x_height,h'],y[tilde_three]l-.25vair)-top y[tilde_one]r); + filldraw z[tilde_one]l.. + controls(z[tilde_one]l+ + delta)and(z[tilde_three]l-delta)..z[tilde_three]l..z[tilde_four]l + --z[tilde_four]r.. + controls(z[tilde_four]r-delta)and(z[tilde_two]r+delta).. + z[tilde_two]r..z[tilde_one]r--cycle; % stroke +else: + pickup fine.nib; + pos[tilde_one](vair,180); + pos[tilde_two](vair,90); + pos[tilde_three](.5[vair,slab],90); + pos[tilde_four](vair,90); + pos[tilde_five](vair,180); + lft x[tilde_one]r=hround (x_move + 0.5w-3u); + rt x[tilde_five]l=hround (x_move + 0.5w+3u); + x[tilde_two]-x[tilde_one]= + x[tilde_three]-x[tilde_two]= + x[tilde_four]-x[tilde_three]=x[tilde_five]-x[tilde_four]; + bot y[tilde_one]=bot y[tilde_four]l=y_move+vround(.75[x_height,h]-vair); + top y[tilde_two]r=top y[tilde_five]=h+y_move; + y[tilde_three]=.5[y[tilde_two],y[tilde_four]]; + filldraw stroke + z[tilde_one]e{up}... + z[tilde_two]e{right}.. + z[tilde_three]e.. + {right}z[tilde_four]e...{up}z[tilde_five]e; fi % stroke +enddef; + +% +%!!! uppercase_tilde edited +vardef uppercase_tilde(expr x_move,y_move,tilde_one,tilde_two,tilde_three, + tilde_four,tilde_five)= +if serifs: numeric theta; + theta=angle(1/8(7u if monospace: /expansion_factor fi-vair),1/4acc_height); + pickup crisp.nib; + numeric mid_width; mid_width=.4[vair,stem]; + pos[tilde_one](vair,theta+90); + pos[tilde_two](vair,theta+90); + pos[tilde_three](vair,theta+90); + pos[tilde_four](vair,theta+90); + z[tilde_two]-z[tilde_one]= + z[tilde_four]-z[tilde_three]=(mid_width-crisp)*dir theta; + lft x[tilde_one]r=hround(x_move+0.5w-3.5u if monospace: /expansion_factor fi); + rt x[tilde_four]l=hround(x_move+0.5w+3.5u if monospace: /expansion_factor fi); + top y[tilde_four]r=h; + % |accent_gap| SHOULD be defined by the acute accent, before this macro runs + %if unknown accent_gap: % accent_gap emulation + % y[tilde_one]'=h-.5mid_stem+eps-max(2/3[h,hi.x_height],hi.x_height+o+hair); + % accent_gap=a_ht-(y[tilde_one]'+.5mid_stem)-hi.x_height; + %fi + %bot y[tilde_one]l=accent_gap+cap_height; + bot y[tilde_one]l=vround(bot y[tilde_one]l + +min(2/3[cap_height,cap_accent_height],y[tilde_three]l-.25vair) + -top y[tilde_one]r); + pair delta; + ypart delta=3(y[tilde_three]l-y[tilde_one]l); + delta=whatever*dir theta; + filldraw z[tilde_one]l.. + controls(z[tilde_one]l+ + delta)and(z[tilde_three]l-delta)..z[tilde_three]l..z[tilde_four]l + --z[tilde_four]r.. + controls(z[tilde_four]r-delta)and(z[tilde_two]r+delta).. + z[tilde_two]r..z[tilde_one]r--cycle; % stroke +else: + pickup fine.nib; + pos[tilde_one](vair,180); + pos[tilde_two](vair,90); + pos[tilde_three](.5[vair,slab],90); + pos[tilde_four](vair,90); + pos[tilde_five](vair,180); + lft x[tilde_one]r=w-rt x[tilde_five]l=hround 1.5u+0.5(w-9u); + x[tilde_two]-x[tilde_one]= + x[tilde_three]-x[tilde_two]= + x[tilde_four]-x[tilde_three]=x[tilde_five]-x[tilde_four]; + % |accent_gap| SHOULD be defined by the acute accent, before this macro runs + if unknown accent_gap: % accent_gap emulation + top y[tilde_one]'=h-vround(2/3[h,hi.x_height]); + accent_gap=a_ht-y[tilde_one]'-hi.x_height; + fi + bot y[tilde_one]=bot y[tilde_four]l=cap_height+.5accent_gap; + top y[tilde_two]r=top y[tilde_five]=h; + y[tilde_three]=.5[y[tilde_two],y[tilde_four]]; + filldraw stroke + z[tilde_one]e{up}... + z[tilde_two]e{right}.. + z[tilde_three]e.. + {right}z[tilde_four]e...{up}z[tilde_five]e; fi % stroke +enddef; +% +% umlauts moved up +% +vardef lowercase_circle(expr + x_center,y_bottom,circ_one,circ_two,circ_three,circ_four)= +numeric circ_hair,circ_vair; +circ_hair=hround min(hair,u if monospace: /expansion_factor fi +.5); +circ_vair=vround min(vair,(h-x_height)/6+.5); +penpos[circ_one](circ_vair,90); penpos[circ_three](circ_vair,-90); +penpos[circ_two](circ_hair,180); penpos[circ_four](circ_hair,0); +x[circ_one]=x[circ_three]=x_center; % +x[circ_two]r=hround(x[circ_one]-1.5u-.5circ_hair); +x[circ_four]r=hround(x[circ_one]+1.5u+.5circ_hair); +y[circ_one]r=h+apex_o; +y[circ_two]=y[circ_four]=.5[y[circ_one],y[circ_three]]; +y[circ_three]l=vround y_bottom; % (1/3[x_height,h]+apex_o); +penstroke pulled_arc.e([circ_one],[circ_two]) + & pulled_arc.e([circ_two],[circ_three]) + & pulled_arc.e([circ_three],[circ_four]) + & pulled_arc.e([circ_four],[circ_one]) & cycle; % bowl +enddef; +% +vardef uppercase_circle(expr + x_center,y_bottom,circ_one,circ_two,circ_three,circ_four)= +numeric circ_hair,circ_vair; +circ_hair=hround min(hair,u if monospace: /expansion_factor fi +.5); +circ_vair=vround vair; % min(vair,(h-x_height)/6+.5); +penpos[circ_one](circ_vair,90); penpos[circ_three](circ_vair,-90); +penpos[circ_two](circ_hair,180); penpos[circ_four](circ_hair,0); +x[circ_one]=x[circ_three]=x_center; % .5w; +x[circ_two]r + = hround(x[circ_one]-1.5u if monospace: /expansion_factor fi -.5circ_hair); +x[circ_four]r + = hround(x[circ_one]+1.5u if monospace: /expansion_factor fi +.5circ_hair); +y[circ_one]r=cap_height + acc_height+apex_o; +y[circ_two]=y[circ_four]=.5[y[circ_one],y[circ_three]]; +y[circ_three]l=vround y_bottom; % (1/3[x_height,h]+apex_o); +penstroke pulled_arc.e([circ_one],[circ_two]) + & pulled_arc.e([circ_two],[circ_three]) + & pulled_arc.e([circ_three],[circ_four]) + & pulled_arc.e([circ_four],[circ_one]) & cycle; % bowl +enddef; +% +% +% cedillas moved up +% +% breves moved up +% +% renamed lowercase ogonek +vardef the_ogonek(expr x_move,y_move,ogon_one,ogon_two,ogon_three) = +x[ogon_one]r=x_move; + pickup crisp.nib; + pos[ogon_one]( + if currentbreadth<0.9vair: 0.9vair else: currentbreadth+eps fi,-60); + pos[ogon_two](stem,0); + pos[ogon_three](vair,145); + x[ogon_two]=x[ogon_one]-2.5u if monospace: / expansion_factor fi ; + x[ogon_three]=x[ogon_one]+0.5u if monospace: / expansion_factor fi ; + bot y[ogon_one]r = y_move; + bot y[ogon_three]=0.5(-d-o)+y_move; %0.4 + bot y[ogon_two]=0.5(-d-o)+y_move; + filldraw stroke z[ogon_one]e{dir 225}... + z[ogon_two]e{dir -110}...{dir 60}z[ogon_three]e; % hook +enddef; + +% +% MACROS FOR PROCESSING CHARS TWICE: +% PASS 1: COLLECTING TFM (SHARP) INFORMATION +% PASS 2: CREATING THE GLYPH +% +%%% define_pixels prepare_pen +%%% beginchar beginchar_twice +%%% endfor repeat_once + +% A special provision is necessary if one uses |modes.mf|: +% This file assumes, that one never wants to use more than one mode +% in the same font, but we will do so. +% +% Make sure, that you never input |modes.mf| after this file, otherwise +% unpleasant surprises wait for you. + +def clear_mode_guards = + forsuffixes $=proofing,fontmaking,tracingtitles,pixels_per_inch, + blacker,fillin,o_correction,blacker_min,aspect_ratio: + numeric mode_guard_$; + endfor +enddef; + +let ori_draw:=draw; +let ori_fill:=fill; +let ori_filldraw:=filldraw; +let ori_erase:=erase; +let ori_penstroke:=penstroke; +let ori_special:=special; +let ori_numspecial:=numspecial; + +mode_def canonical_sharp_mode = % nearly |proof| mode + proofing:=0; % no, we aren't making full proofs + fontmaking:=0; % yes, we are making a font + tracingtitles:=0; % don't show titles online + pixels_per_inch:=2601.72; % that's 36 pixels per pt + blacker:=0; % no additional blackness + blacker_min:=0; % no write_white provision + fillin:=0; % no compensation for fillin + o_correction:=1; % no reduction in overshoot +enddef; + +def beginchar_twice(expr c,w_sharp,h_sharp,d_sharp) = + begingroup + if string mode: string prev_mode; prev_mode:=mode; + else: numeric prev_mode; prev_mode:=mode; + fi + for sharp_calc_:=1,whatever: +% |sharp_calc| is checked in |corrital|, |mark_height|, and |put_accent| + sharp_calc:=sharp_calc_; + if known sharp_calc: % carry out ``sharp'' calculations + begingroup save mode,mag; mode:=canonical_sharp_mode; + clear_mode_guards; mode_setup; font_setup; pseudo_setup; + if is_small_cap: % excerpt from |font_setup| + define_pixels(higher.u,higher.bar_height); + define_corrected_pixels(higher.o); + define_whole_pixels(higher.letter_fit); + define_whole_vertical_pixels(higher.x_height,higher.body_height); + define_whole_blacker_pixels(higher.stem); + fi + endgroup; + def draw expr e=enddef; + let fill:=draw; + let filldraw:=draw; + let erase:=killtext; % |killtext| was absent from earlier versions of plain + let penstroke:=killtext; + def special primary t = enddef; + def numspecial primary t = enddef; + charwd:=w_sharp; charht:=h_sharp; chardp:=d_sharp; charic:=0; + else: % carry out ``discrete'' calculations + mode:=prev_mode; + clear_mode_guards; mode_setup; font_setup; pseudo_setup; + if is_small_cap: % excerpt from |font_setup| + define_pixels(higher.u,higher.bar_height); + define_corrected_pixels(higher.o); + define_whole_pixels(higher.letter_fit); + define_whole_vertical_pixels(higher.x_height,higher.body_height); + define_whole_blacker_pixels(higher.stem); + fi + let draw:=ori_draw; + let fill:=ori_fill; + let filldraw:=ori_filldraw; + let erase:=ori_erase; + let penstroke:=ori_penstroke; + let special:=ori_special; + let numspecial:=ori_numspecial; + charwd:=w_sharp; + fi + charcode:=if known c: byte c else: 0 fi; + w:=hround(w_sharp*hppp); h:=vround(h_sharp*hppp); d:=vround(d_sharp*hppp); + clearxy; clearit; clearpen; scantokens extra_beginchar; +enddef; + +let repeat_once = endfor; + +% +% +% accents which created with beginchar_twice routine +% (borrowed from exaccess but with +% redefining is_cap put_accent put_gravis and put_dot) + +% +% GENERAL PURPOSE ACCESSORIES +% +vardef is_egyptian = +% |false| for most of the CM fonts, except funny fonts; +% |true| for the CC fonts + serifs and (1.4max(fine#,crisp#, tiny#)<slab#) and (1.6slab#>stem#) +enddef; + +vardef is_bold = if serifs: (hair#+.5stem#)>1.5u# else: stem#>2u# fi\\ enddef; + +%!!! set is_cap as boolean +boolean is_cap; + +%%% top is_known +%%% top fix_virgin +vardef is_known z suffix $ = +% an auxiliary macro for |fix_virgin z|, used also while constructing ogoneks + (known x$) or (known x$l) or (known x$r)\\ or + (known y$) or (known y$l) or (known y$r) +enddef; + +vardef fix_virgin z = % find a pair of virgin pairs + numeric ii,jj; jj:=1; + forever: + if is_known z[jj] or is_known z[jj+1]: % unknown gaps may occur + jj:=incr jj else: jj=ii fi; exitif known ii; + endfor; + jj:=ii+1; +% now |ii| and |jj| are such that |z[ii]| and |z[jj]| are ``untouched'' +enddef; + +%%% italcorr corrital +% correction of italic correction (cf. D. E. Knuth, The \MF{}book, p. 105): +vardef corrital z suffix $ = +% |z$| is the rightmost position of a pen (in accent path) + if known sharp_calc: + if not monospace: + save charic_; charic_=(rt(x$)-r)/hppp+slant*y$/vppp+.5u#; + if charic_>charic: charic:=charic_; fi + fi +%| else: %| |charic=mono_charic#|, do nothing + fi +enddef; + +%%% top prepare_pen +def prepare_pen suffix $ = +%%% fine $ %%%% temporary MFT convention + if $>fudged.hair: $:=fudged.hair; fi + $.breadth:=$; + pickup if $=0: nullpen else: pencircle scaled $; $:=$-eps fi; + $.nib:=savepen; breadth_[$.nib]:=$; + forsuffixes $$=lft,rt,top,bot: shiftdef($.$$,$$ 0); endfor +%%% qq $ %%%% ordinary MFT convention +enddef; + +% The proportion of |vair/stem| depends drastically on resolution; +% e.g., for 300 dpi cmbx10 |vair=1| and |stem=5|, for 746 dpi cmbx10 +% (300 dpi, magstep 5) |vair=4| and |stem=12|, while, sharply speaking, +% |stem#/vair#=3.15381|; hence a new variable |xvair| has been introduced +% to be used in some crucial places instead of |vair|. +vardef xvair = stem*vair#/stem# enddef; + +% +% ACCENT ACCESSORIES +% +% |the_cap_flat| is a factor controlling the flatness of accents over +% majuscules; a default value may be overriden by assigning a value to the +% variable |cap_flat| (cf. also |the_|... macros in ogonek accessories). +vardef the_cap_flat = + if known cap_flat: cap_flat elseif serifs and hefty: 1/5 else: 1/3 fi +enddef; +% +% The |hpos_corr| variable is an optional parameter to |put_ogonek|, meant +% to be set locally inside |beginchar| ... |endchar|, if a horizontal +% correction of the accent position is needed: +numeric hpos_corr; +% +%%%% temporary MFT convention: +%%% top x_height diam a_wd a_ht i_ht u asc_height cap_A_wd +% width of the acute accent: +vardef a_wd@# = 9hi.u@# enddef; +% height of the acute accent: +vardef a_ht@# = %!!!in plfonts: skipped ,hi.x_height@#+acc_h + min(asc_height@#,2hi.x_height@#,hi.x_height@#+acc_height@#) enddef; +% height of the letter `i': +vardef i_ht@#(suffix diam) = + if is_small_cap: a_ht@# % usually there is no dot over a small cap `i' + else: min(asc_height@#, 10/7hi.x_height@#+.5diam@#) fi +enddef; +% width of the letter `A' (used in |put_ogonek|): +vardef cap_A_wd@# = 13u@# enddef; +%%%% ordinary MFT convention: +%%% qq x_height diam a_wd a_ht i_ht u asc_height cap_A_wd + +def mark_height(expr sharp_h)= +% |sharp_h| is the height of an accented minuscule + if known sharp_calc: + charht:=if is_cap: h/vppp else: sharp_h fi;% in plfonts line placed after `if' in ec---before + if\\ (proofing>0) and is_cap: +% BJ likes to have proofs vertically aligned (somehow): + proofoffset(0,h-charht*vppp-1mm); + fi + fi +% say earlier, e.g., |is_smoke=1| if you're making `smoked' proofs +% and you don't like to have a rule marking the height + if unknown is_smoke: + if proofing>0: proofrule((l+w/2,charht*hppp)t_,(r+u,charht*hppp)t_); fi + if displaying>0: screenrule((l+w/2,charht*hppp)t_,(r+u,charht*hppp)t_); fi + fi +enddef; + +def fix_acc_pairs = + fix_virgin z; + begingroup +% excerpt from |beginchar|: + save w,h; w=round(a_wd); h=round(a_ht); +% excerpt from |mono_adjust|: + if monospace: + save u_; numeric u_; u_:=hi.u#; save u; u#:=u_; + numeric expansion_faktor; + mono_charwd#=2 hi.letter_fit#+expansion_faktor*a_wd#; + hi.u:=u#*expansion_faktor*hppp; + w:=mono_charwd-shrink_fit-2 hi.letter_fit; + fi +% end of the excerpts + numeric accent_gap,mid_stem; mid_stem=2/3[stem,hi.stem]; + if serifs: + pickup crisp.nib; + x[jj]'=hround(w-2hi.u)-.5mid_stem; x[jj]':=x[jj]'-2/3[x[jj]',w-x[jj]']; + y[jj]'=h-.5mid_stem+eps-max(2/3[h,hi.x_height],hi.x_height+o+hair); + accent_gap=a_ht-(y[jj]'+.5mid_stem)-hi.x_height; + bot z[ii]=round(accent_hpos, + accent_gap+if is_cap: cap_height else: hi.x_height fi); + z[jj]=z[ii]+(z[jj]' + if is_cap: rotated (-the_cap_flat*angle(z[jj]')) fi); + numeric theta; theta=angle(z[ii]-z[jj])+90; + pos[jj](mid_stem,theta); pos[ii](hair,theta); + else: + pickup fine.nib; + rt x[jj]'r=hround(.5w-1.25hi.u); + top y[jj]'=h-vround(2/3[h,hi.x_height]); + z[ii]'=origin; pos[jj]'(mid_stem,0); pos[ii]'(vair,0); + accent_gap=a_ht-y[jj]'-hi.x_height; + if is_cap: + numeric beta; beta=-the_cap_flat*angle(z[jj]'-z[ii]'); + z[ii]=round(accent_hpos,accent_gap+cap_height); + z[jj]=z[ii]+(z[jj]' rotated beta); + y[jj]r=y[jj]l=y[jj]; y[ii]r=y[ii]l=y[ii]; + for xx:=jj,ii: forsuffixes $:=l,r: + (z[xx]$-z[ii]) rotated -beta=whatever[z[jj]'$,z[ii]'$]; + endfor\\ endfor + else: + for xx:=jj,ii: forsuffixes $:=r, ,l: + z[xx]$=z[xx]'$+round(accent_hpos, + accent_gap+if is_small_cap: cap_height else: x_height fi); + endfor\\ endfor + fi + fi + endgroup; +enddef; + +% is_cap checked by modifier +def put_accent suffix modifier = %!!! + if cyrcaph.modifier: is_cap:=true; else: is_cap:=false; fi %!!! + numeric accent_hpos; + accent_hpos=.5w - if is_cap: .75 else: .5 fi\\ u + if known hpos_corr: +hpos_corr fi; + fix_acc_pairs; % |fix_acc_pairs| uses private values of |w|, |h| \& |u| + numeric hpos_corr; % |hpos_corr| is local: forget its value +% draw the diagonal: + if serifs: + pickup crisp.nib; filldraw circ_stroke (z[jj]e--z[ii]e); + z[jj].right=directionpoint up of (z[jj]r{z[jj]r-z[ii]r}..{z[ii]l-z[jj]l}z[jj]l); + z[jj].top=directionpoint left of (z[jj]r{z[jj]r-z[ii]r}..{z[ii]l-z[jj]l}z[jj]l); + else: + pickup fine.nib; filldraw stroke (z[jj]e--z[ii]e); + z[jj].right=z[jj].top=z[jj]r; + fi + corrital z[jj].right; % correct italic correction +% adjust and save height (it is used in the program for the dotted `Z'): + h:=if is_cap: y[jj].top else: a_ht fi; + if known sharp_calc: saved_height:=h; fi + mark_height(a_ht#); + penlabels([ii],[jj]); +enddef; + +% +% GRAVE ACCENT ACCESSORIES +% + +% This section borrows heavily from the (acute) accent accessories +def fix_grav_pairs = + fix_virgin z; + begingroup +% excerpt from |beginchar|: + save w,h; w=round(a_wd); h=round(a_ht); +% excerpt from |mono_adjust|: + if monospace: + save u_; numeric u_; u_:=hi.u#; save u; u#:=u_; + numeric expansion_faktor; + mono_charwd#=2 hi.letter_fit#+expansion_faktor*a_wd#; + hi.u:=u#*expansion_faktor*hppp; + w:=mono_charwd-shrink_fit-2 hi.letter_fit; + fi +% end of the excerpts + numeric accent_gap,mid_stem; mid_stem=2/3[stem,hi.stem]; + if serifs: + pickup crisp.nib; + x[jj]'=hround(w-2hi.u)-.5mid_stem; x[jj]':= -x[jj]'+ 2/3[x[jj]',w-x[jj]']; + y[jj]'=h-.5mid_stem+eps-max(2/3[h,hi.x_height],hi.x_height+o+hair); + accent_gap=a_ht-(y[jj]'+.5mid_stem)-hi.x_height; + bot z[ii]=round(accent_hpos, + accent_gap+if is_cap: cap_height else: hi.x_height fi); + z[jj]=z[ii]+(z[jj]' + if is_cap: rotated (-the_cap_flat*(angle(z[jj]')-180)) fi); + numeric theta; theta=angle(z[ii]-z[jj])+90; + pos[jj](mid_stem,theta); pos[ii](hair,theta); + else: + pickup fine.nib; + lft x[jj]'l=-hround(.5w-1.25hi.u); + top y[jj]'=h-vround(2/3[h,hi.x_height]); + z[ii]'=origin; pos[jj]'(mid_stem,0); pos[ii]'(vair,0); + accent_gap=a_ht-y[jj]'-hi.x_height; + if is_cap: + numeric beta; beta=-the_cap_flat*(angle(z[jj]'-z[ii]')-180); + z[ii]=round(accent_hpos,accent_gap+cap_height); + z[jj]=z[ii]+(z[jj]' rotated beta); + y[jj]r=y[jj]l=y[jj]; y[ii]r=y[ii]l=y[ii]; + for xx:=jj,ii: forsuffixes $:=l,r: + (z[xx]$-z[ii]) rotated -beta=whatever[z[jj]'$,z[ii]'$]; + endfor\\ endfor + else: + for xx:=jj,ii: forsuffixes $:=r, ,l: + z[xx]$=z[xx]'$+round(accent_hpos, + accent_gap+if is_small_cap: cap_height else: x_height fi); + endfor\\ endfor + fi + fi + endgroup; +enddef; + +% is_cap checked by modifier +def put_gravis suffix modifier = %!!! + if cyrcaph.modifier: is_cap:=true; else: is_cap:=false; fi %!!! + numeric accent_hpos; + accent_hpos=.5w + if is_cap: .75 else: .5 fi\\ u + if known hpos_corr: +hpos_corr fi; + fix_grav_pairs; % |fix_grav_pairs| uses private values of |w|, |h| \& |u| + numeric hpos_corr; % |hpos_corr| is local: forget its value +% draw the diagonal: + if serifs: + pickup crisp.nib; filldraw circ_stroke (z[jj]e--z[ii]e); + z[jj].right=directionpoint down of (z[jj]r{z[jj]r-z[ii]r}..{z[ii]l-z[jj]l}z[jj]l); + z[jj].top=directionpoint left of (z[jj]r{z[jj]r-z[ii]r}..{z[ii]l-z[jj]l}z[jj]l); + else: + pickup fine.nib; filldraw stroke (z[jj]e--z[ii]e); + z[jj].right=z[jj].top=z[jj]r; + fi +% adjust and save height (tho the height is never needed): + h:=if is_cap: y[jj].top else: a_ht fi; + if known sharp_calc: saved_height:=h; fi + mark_height(a_ht#); + penlabels([ii],[jj]); +enddef; + +% +% DOT ACCENT ACCESSORIES +% + +%%% good penkind +% is_cap checked by modifier +def put_dot (suffix penkind) (expr dd_) % dot of the lowercase letter `i' + suffix modifier = %!!! + if cyrcaph.modifier: is_cap:=true; else: is_cap:=false; fi %!!! + fix_virgin z; + numeric dd#; % sharp dot diameter + dd#=dd_; define_whole_blacker_pixels(dd); +% adjust height temporarily: + h:=vround(if is_cap: (cap_height#+1.5u#+dd#) + else: i_ht#(dd) + fi\\ *hppp); + pickup penkind.nib; pos[jj](dd,90); pos[ii](dd,0); + x[jj]=x[ii]=good.x(.5w+.25u if known hpos_corr: +hpos_corr fi); %!!! + numeric hpos_corr; %!!! |hpos_corr| is local: forget its value !!! + top y[jj]r=h+1; y[ii]=.5[y[jj]l,y[jj]r]; +% draw the dot: + dot([ii],[jj]); +% dotted `Z' inherits the recently saved height (if known; usually the height +% of the accented `Z') which allows to decrease by one the number of different +% heights in a font; dotted `z' has the height of a lowercase `i' (exception: +% caps and small caps) + if known saved_height: h:=saved_height; fi\\ mark_height(i_ht#(dd)); + penlabels([ii],[jj]); +enddef; + +% +% CYRCROSS ACCESSORIES +% (redefined L's CROSS ACCESSORIES) +% + +% is_cap checked by modifier +def put_cyrcross(expr x_center,y_move,left_jut,right_jut) suffix modifier = %!!! + if cyrcaph.modifier: is_cap:=true; else: is_cap:=false; fi %!!! + fix_virgin z; + numeric dd; dd=if serifs:if is_cap: cap_bar + else: bar fi + else: if is_cap: .2[vair,cap_band] + else: vair fi + fi; + pickup if serifs: crisp.nib else: fine.nib fi; + numeric theta; + if left_jut>0: + theta=angle(11u#,.3[x_height#,cap_height#]); + lft x[ii]r = hround(x_center-left_jut)-eps; + rt x[jj]l = hround(x_center+right_jut)+eps; + else: + theta=angle(11u#,-.3[x_height#,cap_height#]); + rt x[ii]r = hround(x_center-left_jut)-eps; + lft x[jj]l = hround(x_center+right_jut)+eps; + fi + pos[ii](dd,theta+90); pos[jj](dd,theta+90); + z[ii]-z[jj]=whatever*dir theta; + % |.52| is one of CM (Computer Magic) numbers appearing in many CM programs, + % among others in the programs for B, F, and H: + whatever[z[ii],z[jj]]=if not is_cap and hefty: top fi\\ + (x_center,if is_cap:.52cap_height else: bar_height fi\\+y_move); + % before drawing the stroke improve discretization: + save eps_; + eps_:=y[ii]l-good.y(y[ii]l); + forsuffixes $:=l, ,r: y[ii]$:=y[ii]$-eps_; endfor + eps_:=y[jj]r-good.y(y[jj]r); + forsuffixes $:=l, ,r: y[jj]$:=y[jj]$-eps_; endfor + filldraw stroke z[ii]e--z[jj]e; % now draw the stroke + corrital z[jj]l; % correct italic correction + penlabels([ii],[jj]); +enddef; + +% +% EASY OGONEK ACCESSORIES +% simplified ogonek +% there are used some macros from put_ogonek stuff (ec fonts) +% + +% ogonek defaults: +vardef the_ogonek_depth# = % sharp value + if known depth_corr: depth_corr* fi\\ desc_depth# +enddef; + +vardef the_tip_pos = + (if monospace: 1.9 elseif serifs: if hefty: 1.85 + elseif is_bold: 1.75 else: 2 fi\\ else: % sansserif + if is_bold: 2.1 else: 1.95 fi\\ fi\\ hi.u, + if serifs: + if monospace: 1.25 elseif hefty: 1 elseif is_bold: .75 else: 1.45 fi + else: % sansserif + .45 fi\\ hi.u) + if known tip_xcorr: xscaled\\ tip_xcorr fi + if known tip_ycorr: yscaled\\ tip_ycorr fi +enddef; + +vardef the_pre_angle = % refers to the outer edge + if known pre_angle: pre_angle else: + if serifs: if hefty: 208 elseif is_bold: 211 else: 214 fi\\ else: 211 fi + fi +enddef; + +vardef the_post_angle = % refers to the outer edge + if known post_angle: post_angle else: + if serifs: if monospace: 60 elseif hefty: 66 elseif is_bold: 55 else: 74 fi + else: 25 fi\\ fi +enddef; + +% parameters to |put_ogonek|: +numeric join_angle; % starting (inner) ogonek direction, if known + +% common ogonek breath (because of slab changed in a few letters) +numeric ogonek_breadth; % ogonek breadth at the tip +ogonek_breadth=if serifs and is_bold: slab else: xvair fi; + +pair ogonek_pos; % starting (inner for `e' with ogonek, otherwise outer) ogonek position: + +vardef easy_ogonek (suffix penkind)(expr _one,_two,_three)= + pickup penkind.nib; + if monospace: + % excerpt from |mono_adjust|: + save u_; numeric u_; u_:=hi.u#; save u; u#:=u_; + numeric expansion_faktor; + mono_charwd#=2hi.letter_fit#+expansion_faktor*cap_A_wd#; % cap_A_wd=13u + hi.u:=u#*expansion_faktor*hppp; + % now |u| is like in the letter `A' + fi + y_right:=-vround(d+hi.o); % bottom bound + if unknown ogonek_breadth: + ogonek_breadth=if serifs and is_bold: slab else: xvair fi; + fi + if known ogonek_pos: + z[_one]'l=ogonek_pos+(0,eps); + pos[_one]'(max(ogonek_breadth,penkind+eps),0); + z[_one]l=whatever[ogonek_pos, ogonek_pos+dir the_pre_angle]; + bot y[_one]l=0 if known ogonek_move:+ogonek_move fi+eps; + numeric ogonek_move; % it's local + else: + bot z[_one]l=(.5w,0+eps); + fi + pos[_one](max(ogonek_breadth,penkind+eps),0); + bot z[_three]'=(xpart z[_one]l-.5penkind,y_right-eps)+the_tip_pos; + z[_three]l=if is_small_cap: + z[_one]+((z[_three]'-z[_one]) + scaled sqrt(body_height#/higher.body_height#)) + else: + z[_three]' + fi; + pos[_three](max(ogonek_breadth,penkind+eps), + the_post_angle+if serifs: 90 else: 80 fi); + z[_two]l=if serifs: + if monospace: 2/3[z[_one],z[_three]]+ + else: .52[z[_one],z[_three]]+ + fi + else: 3/5[z[_one],z[_three]]+7/8 + fi + (y[_three]-y[_one],x[_one]-x[_three]-eps) + -penoffset (z[_three]-z[_one]) of currentpen; + pos[_two](max(penkind+eps, + if serifs: 7/8 else: 2/3 fi [bar,fudged.stem-2stem_corr]), %from ukreve + angle(z[_one]-z[_three]) - if serifs: 90 else: 80 fi); + if known ogonek_pos: + if y[_one]'<y[_one]: path p; numeric t; + if known join_angle: + prim_angle:=join_angle; + else: + p=z[_one]{dir the_pre_angle}...{(z[_three]-z[_one])}z[_two] + ...{dir (the_post_angle)}z[_three]; + t=ypart (((0,y[_one]')--(w,y[_one]')) intersectiontimes p); + prim_angle:=angle(direction t of p); + fi + filldraw stroke + z[_one]'e{dir prim_angle}...{(z[_three]-z[_one])}z[_two]e + ...{dir (the_post_angle)}z[_three]e; % ogonek stroke + else: + prim_angle:=if known join_angle: join_angle else: the_pre_angle fi; + filldraw stroke + z[_one]'e{dir prim_angle}...z[_one]e{dir the_pre_angle} + ...{(z[_three]-z[_one])}z[_two]e + ...{dir (the_post_angle)}z[_three]e; % ogonek stroke + fi + else: + filldraw stroke + z[_one]e{dir the_pre_angle}... + {(z[_three]-z[_one])}z[_two]e...{dir (the_post_angle)}z[_three]e; % ogonek stroke + fi + numeric join_angle,ogonek_breadth; pair ogonek_pos; % all they are local + penlabels([_one],[_one]',[_two],[_three],ogonek);. +enddef; + +% +% HACHEK ACCESSORIES +% +% This was csaccent.mf in text format, as of 89/05/08 +% written by P. Novak, Prague +% +%!!! edited +def lc_hachek_accent(expr ref) = + if serifs: + pickup crisp.nib; + pos52'(0.75[vair,curve],90); + pos52(0.75[vair,curve],90); + x52=good.x ref; + x52-x51=x53-x52=good.x if hach_sharp:2.5 else:3 fi + accent_u-accent_thin; + top y52' = top y51 = top y53 = lc_hachek_height; + if hach_sharp: + y52=max(2/3[h,hi.x_height],hi.x_height+o+hair); % lower point + pos51(1.5stem,0); pos53(accent_thin,180); + else: + 0.5[y52,y52r] = 0.5[hi.x_height,y52']; + pos51(accent_thin,angle(z52-z51)+90); + pos53(accent_thin,angle(z53-z52)+90); + fi + filldraw stroke z51e -- z52e -- z53e; + else: + pickup fine.nib; + pos51(vair,0); + pos53(vair,0); + x52=good.x ref; + x52-lft x51=rt x53-x52= hround(1.25accent_u + vair); + pos52(stem,0); + bot y52=vround(max(2/3[h,hi.x_height],hi.x_height+o+hair)); + top y51 = top y53 = max(lc_hachek_height,top y52+eps); %!!! + z50 = whatever[z51r,z52r] = whatever[z52l,z53l]; + y54l=y54r=y52; + x54l=good.x .2[x52l,x52]; + x54r-x52 = x52-x54l; + filldraw z54l -- z51l-- z51r -- z50 -- z53l -- z53r -- z54r -- cycle; + fi + penlabels(50,51,52,52',53,54); +enddef; + +def dtl_hachek(text x_ref,y_ref) = +pickup fine.nib; + pickup fine.nib; + x51=hround(x_ref); y51=vround(y_ref); + comma(51,q,pdot_diam,.25accent_u,2/3comma_depth); + penlabels(51); +enddef; + +def uc_hachek_accent(expr ref) = + if serifs: + pickup crisp.nib; + pos52'(0.5[vair,cap_curve],90); + pos52(0.5[vair,cap_curve],90); + x52=good.x ref; + x52-x51=x53-x52=good.x 3accent_u-accent_thin; + top y52' = top y51 = top y53 = % upper points + uc_acc_height-.5[vair,cap_curve]+eps + -max(2/3[uc_acc_height,hi.x_height],hi.x_height+o+hair)+cap_height; + if hach_sharp: + y52=max(2/3[uc_acc_height,hi.x_height],hi.x_height+o+hair) + -hi.x_height+cap_height; % lower point + pos51(cap_stem,0); pos53(2accent_thin,180); + else: + 0.5[y52,y52r] = + if not hefty: + max(2/3[uc_acc_height,hi.x_height],hi.x_height+o+hair) + -hi.x_height+cap_height; + else: + max(2/3[uc_acc_height,hi.x_height],hi.x_height+o) + -hi.x_height+cap_height-hair; + fi + pos51(accent_thin,angle(z52-z51)+90); + pos53(accent_thin,angle(z53-z52)+90); + fi + filldraw stroke z51e -- z52e -- z53e; + else: + pickup fine.nib; + pos51(vair,0); + pos53(vair,0); + x52=good.x ref; + x52-x51=x53-x52= 1.75accent_u + .5vair; + pos52(cap_stem,0); + bot y52= cap_height + .5 accent_gap; + top y51 = top y53 = cap_height + acc_height; + z50 = whatever[z51r,z52r] = whatever[z52l,z53l]; + y54l=y54r=y52; + x54l=good.x .2[x52l,x52]; + x54r-x52 = x52-x54l; + filldraw z54l -- z51l-- z51r -- z50 -- z53l -- z53r -- z54r -- cycle; + fi +penlabels(50,51,52,52',53,54); +enddef; + +endinput; +% end-of-file |