summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/fonts/source/public/cmbright/ebaccess.mf
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-01-09 23:38:21 +0000
committerKarl Berry <karl@freefriends.org>2006-01-09 23:38:21 +0000
commit215012a8d684889983ec2c0629e1c704e6853d9c (patch)
treeebf1271bd71869069824935ae8a5678745bf8bce /Master/texmf-dist/fonts/source/public/cmbright/ebaccess.mf
parent1af3d19d6dbcbf309667d9cb4aa3cdda914914a9 (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/public/cmbright/ebaccess.mf')
-rw-r--r--Master/texmf-dist/fonts/source/public/cmbright/ebaccess.mf893
1 files changed, 893 insertions, 0 deletions
diff --git a/Master/texmf-dist/fonts/source/public/cmbright/ebaccess.mf b/Master/texmf-dist/fonts/source/public/cmbright/ebaccess.mf
new file mode 100644
index 00000000000..32c88b4f753
--- /dev/null
+++ b/Master/texmf-dist/fonts/source/public/cmbright/ebaccess.mf
@@ -0,0 +1,893 @@
+% ebaccess.mf
+%
+% This file is part of ecfonts version 1.0
+%
+% Please read the files 00readme.txt, 00inst.txt, 00error.txt, and
+% copyrite.txt for further information
+%
+% You find some documentation in ecdoc.tex (needs LaTeX2e)
+%
+% Accessories and special definitions for polish letters
+% Adapted to the ec fonts by J\"org Knappen
+% Adapted to the cm bright fonts by Walter Schmidt, see (CMBR)
+%
+% Copyright (c) 1992 Bogus\l{}aw Jackowski \& Marek Ry\'cko
+% Copyright (c) 1995, 1996, 1997 J\"org Knappen
+% ---------------------------------------------------------------------------
+% This was PL_DOD.MF ({\bif{}dodatkowy}, i.e., additional file for the Polish
+% extension of CM family) in text format.
+% ---------------------------------------------------------------------------
+%%{\let\:\sl
+%\: This file provides accessories for making Polish diacritical characters:
+%\: acute accent for |"C"|, |"N"|, |"L"|, |"S"|, |"Z"|, dot accent for |"Z"|,
+%\: cross for |"L"| and ogonek for |"A"| and |"E"|. In order to avoid extra
+%\: parameters (62 should be enough) the macros do a lot of ``clever'' stuff,
+%\: trying to figure out needed dimensions. This is not always a trivial
+%\: task and in some cases such extra parameters may prove to be unavoidable.
+%\: Several additional parameters may be assigned a value, prior to reading
+%\: the driver file, in order to override the default behaviour.
+
+%\: One of them is
+%\: --- the factor controlling the slope of accents over majuscules,
+%\: |cap_flat|; if the default slope is, say, $\beta$, the resulting
+%\: slope is equal to |(1-cap_flat)*|$\beta$; this parameter is used
+%\: in the sources of the following fonts:
+%\ PLCSC10, PLDUNH10, PLTCSC10
+
+%\: Unexpectedly difficult to program turned out to be ogoneks. We decided
+%\: that the best looking are ogoneks such that a single B\`ezier segment
+%\: describes each of ogonek's edges. This necessitated introducing many
+%\: parameters controlling the positions of control points (for more details
+%\: see comments in the section ``OGONEK ACCESSORIES''). All these
+%\: (optional) parameters may be splitted into three groups of importance:
+%\: primary, secondary and tertiary. The primary parameters are intended
+%\: to be ``normally'' accessible to users, the secondary ones---only in
+%\: case of emergency, the tertiary ones---rather not at all.
+
+%\: The primary parameters are:
+
+%\: --- the factor controlling the depth of ogoneks, |depth_corr|; the
+%\: resulting depth is equal to |depth_corr*desc_depth#| if the value
+%\: of |depth_corr| is known, |desc_depth#| otherwise
+%\: --- the factor controlling the leftmost and tip positions
+%\: of an ogonek, |left_corr|, |tip_xcorr| and |tip_ycorr|;
+%\: the default distances are scaled using the values of the
+%\: corresponding parameters
+%\: --- the scaling factor for the top and tip breadths of an ogonek,
+%\: |top_breadth_corr|, |tip_breadth_corr|
+
+%\: Some of the primary parameters are used in the sources of the following
+%\: fonts:
+% PLB10, PLBX5, PLBX6, PLBX7, PLBX8, PLFI10, PLITT10, PLR5, PLR6, PLR7,
+% PLR8, PLR9, PLR12, PLR17, PLSL8, PLSL9, PLSL12, PLSSQ8, PLSSQI8, PLTI7,
+% PLTI8, PLTI12, PLVTT10
+
+%\: The following four parameters we regard as of a secondary importance:
+
+%\: --- the pen ogoneks are to be filled with, |ogonek_pen#| (this is
+%\: the only sharp ogonek parameter and is used in the sources of
+%\: the {\commfont{}PLFF10} and {\commfont{}PLFI10} fonts)
+%\: --- the darkness of ogoneks may be controlled using two parameters,
+%\: |0<pre_lightness<1| and |0<post_lightness<1|, referring to the top
+%\: and tip of an ogonek, respectively; used in {\commfont{}PLB10.MF}
+%\: --- next two parameters, |pre_deflexion| and |post_deflexion|, control
+%\: a rather small deflexion angle (in degrees) of the inner ogonek
+%\: outline as compared to the outer one; they refere to the top and
+%\: tip of an ogonek, respectively
+
+%\: The complete list of `ogonek' parameters can be found in the section
+%\: ``OGONEK ACCESSORIES.''
+
+%\: There is one more (rather unimportant) parameter, |is_smoke|. If this
+%\: variable is assigned a known value, `smoked' proofs will not contain
+%\: a rule marking the height of accented letters.
+%%}
+% ---------------------------------------------------------------------------
+% HISTORY
+% 7 Feb 1992: version 1.00
+% 11 Feb 1992: version 1.01
+% (no changes; the new version number due to changes in \MeX{} format)
+% 25 May 1992: version 1.02
+% The following two erroneous assignments:
+%| z_a:=(x_down+the_left_pos,.5penkind); %| starting point
+%| z_d:=(xpart(z_a)-.5penkind,y_right+.5penkind)+the_tip_pos; %| ending point
+% changed to the following ones:
+%| z_a:=(x_down+the_left_pos,ypart(ogonek_pos)); %| starting point
+%| z_d:=(xpart(z_a)-.5penkind,y_right+ypart(ogonek_pos))+|
+%| the_tip_pos; %| ending point
+% Some comments changed.
+% 18 Dec 1992: version 1.03
+% (no changes; the new version number due to changes in FIK_MIK.MF
+% and some cosmetic changes in CMBX11.MF, CMR11.MF, CMTI11.MF, CMSL11.MF,
+% CMSSBI10.MF, and POLAN.MF)
+% 21 Apr 1995: Adaption for dxbase and dcfonts:
+% Deleted character code (those are fixed by the Cork standard)
+% Deleted |improve_kerns|
+% Avoid double rounding in the definition of |fisp| by defining |fisp#|
+% Made |the_ogonek_depth| explicitly sharp (|the_ogonek_depth#|)
+% Changed definition of |is_cap|
+% Replaced all occurences of |ogonked_a| and |ogonked_e| with the
+% Cork code values |oct"241"| and |oct"246"| respectively
+% Replaced |dotted_Z| and |dotted_z| with |oct"233"| and |oct"273"|
+% respectively
+% Renamed |expansion_factor| to |expansion_faktor| because of
+% conflicting definition
+% 7 May 1995 Appended material from czechoslovak fonts (csaccent.mf)
+% 18 May 1995 Changed |put_accent| because I want to use it twice in
+% one character. To achieve this, the variables |z.top| and |z.right|
+% were renamed |z[jj].top| and |z[jj].right| respectively
+% Changed |is_cap| again (included |168| for l with acute)
+% 29 May 1995 Added accessories for the grave accent
+% Changes one comment to point to dxcsc.mf instead of polkap.mf
+% 18 Jun 1995 Made provision in |put_cross| for the blank symbol
+% Made provision in |put_dot| for turkish dotted `I'
+% 10 Jul 1995 Changed condition in |put_dot| to refer to |is_cap|. Needed
+% with the tc fonts.
+% 11 Jul 1995 Added another proviso to |put_dot| to produce floating dot
+% 23 Jul 1995 Added proviso in |put_cross| for recipe sign
+% 17 Aug 1995 Tuned height of accent again, added |hi.x_height@#+acc_height@#|
+% to the minimum condition
+% 14 Apr 1996 Buildt in Bogus\l{}aw Jackowski's fixes to avoid resolution
+% dependent font metrics.
+% I did not apply the change to the |put_dot| macro, because there is
+% no chance to keep it consistent for the floating dot accent
+% Macros for processing characters twice put to |exbase.mf|
+% 26 Apr 1996 Put in version checking
+% Moved last minute font setup to |expseudo.mf|
+% 10-MAY-1996 Corrected |corrital| to make use of the canonical sharp mode
+% Added |version_check|
+% 22-DEC-1996 Moved definition of |is_small_cap| and |hi.| to |exbase.mf|
+% Changed the documentation to know about ec fonts instead of dc fonts.
+% ---------------------------------------------------------------------------
+% VERSION CHECKING
+% ---------------------------------------------------------------------------
+version_check(1,0); % |version_check| was introduced in dc1.3
+% ---------------------------------------------------------------------------
+% LAYOUT SETUP:
+% (A MIXTURE OF EXTENDED CM, EXTENDED ASCII, AND ``LOCAL'')
+% ---------------------------------------------------------------------------
+% [deleted]
+% ---------------------------------------------------------------------------
+% EXTRA PARAMETERS
+% ---------------------------------------------------------------------------
+% [deleted and/or moved]
+%
+% The variable |limit_dist| is set to |5/4u| in PL_DL.MF, PL_ML.MF and
+% PL_MLK.MF, and used in |put_accent| and |put_cross|. It was introduced
+% because of some funny (although troublesome) fonts. The value of |u| is
+% changed by |mono_adjust|, hence it is set outside |beginchar| ... |endchar|
+% rather than inside.
+numeric limit_dist;
+% ---------------------------------------------------------------------------
+% 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;
+
+vardef is_cap =
+ (((127 < charcode) and (charcode < 158)) or\\
+ ((191 < charcode) and (charcode < 224))) or\\
+ (charcode = 168) % true for l with acute
+enddef;
+
+%%% 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@# =
+ 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;
+ 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;
+
+def put_accent=
+ 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;
+
+def put_gravis=
+ 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
+def put_dot (suffix penkind) (expr dd_) = % dot of the lowercase letter `i'
+ 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#)
+ elseif (charcode=oct"273") or (charcode=oct"012"): i_ht#(dd)
+ fi\\ *hppp);
+ pickup penkind.nib; pos[jj](dd,90); pos[ii](dd,0);
+ x[jj]=x[ii]=good.x(.5w+if charcode=oct"233": .5 else: if charcode=oct"235": 0
+ else: .25 fi\\fi\\ u);
+ 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;
+% ---------------------------------------------------------------------------
+% L's CROSS ACCESSORIES
+% ---------------------------------------------------------------------------
+def put_cross(expr l_jut,r_jut) =
+ fix_virgin z;
+ numeric dd; dd=if is_cap: cap_bar else: bar fi;
+ numeric theta; theta=angle(11u#,.3[x_height#,cap_height#]);
+ pickup crisp.nib; pos[ii](dd,theta+90); pos[jj](dd,theta+90);
+ lft x[ii]r = hround(x1-l_jut)-eps;
+ rt x[jj]l = hround(x1+r_jut)+eps;
+ 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\\
+ (x1,if charcode=32: .3[x_height,asc_height-serif_drop] % tc blank sign
+ elseif charcode=147: .3x_height % tc recipe sign
+ else: .52cap_height fi\\);
+% 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;
+% ---------------------------------------------------------------------------
+% OGONEK ACCESSORIES
+% ---------------------------------------------------------------------------
+% This part is admittedly sophisticated, however, a wide spectrum of
+% different ogonek shapes is in fact to be programmed: one shape is needed
+% for caps, another for `a' with ogonek, yet another for `e' with ogonek,
+% as they all have different joins. Moreover, a sansserif ogonek differs
+% significantly from a serif one, a bold ogonek from a non-bold, an ogonek
+% for hefty fonts should still be different. And if you take into account
+% that the basic font unit |u| may change during one session of font
+% generation (monospace and caps-small-caps) and that a few different
+% pens may be used to draw a single letter, you'll understand why so many
+% |if| ... |else:| ... |fi| commands are used in the following code.
+%
+% Outer and inner edges of an ogonek (suffixed with |l| and |r|, resp.)
+% are single B\`ezier segments; the outer one, a path
+% |p=z_a..controls z_b and z_c ..z_d|
+% is constructed as follows: given pairs |z_a|, |z_d|, angles |alpha_a|,
+% |alpha_d| and two numbers |x_down|, |y_right|, find pairs |z_b| and |z_c|
+% such that the path |p| has the following properties:
+% (a) |direction p(z_a)=alpha_a|
+% (b) |direction p(z_d)=alpha_d-180|
+% (c) |direction p(x_down,some_y)=down|
+% (d) |direction p(some_x,y_right)=right|
+% The problem is solved using a ``double'' bisection method, provided
+% that appropriate limits |z_b'|, |z_b''| and |z_c'|, |z_c''| for |z_b|
+% and |z_c|, respectively, are given; more precisely,
+% |z_b=|$\lambda_b$|[z_b',zb'']| and |z_c=|$\lambda_c$|[z_c',zc'']|
+% is supposed to hold for given |z_b'|, |z_b''|, |z_c'|, |z_c''| and
+% some $0<\lambda_b,\lambda_c<1$.
+%
+% The inner edge is constructed by a careful modification of the outer one.
+%
+% If a default behaviour of our program is not satisfying, the user may
+% assign a value to the following ``emergency'' parameters (provided E knows
+% what E is doing):
+% |depth_corr|, |left_corr|, |top_breadth_corr|, |tip_breadth_corr|,
+% |tip_xcorr|, |tip_ycorr|, |pre_angle|, |post_angle|,
+% |pre_limit|, |post_limit|, |pre_lightness|, |post_lightness|,
+% |pre_deflexion|, and |post_deflexion|.
+% Any of these parameters, if known while generating a font, is used instead
+% of a default setting. The parameters are accessed only via macros:
+% |the_ogonek_depth#|, |the_left_pos|, |the_top_breadth_corr|,
+% |the_tip_breadth_corr|, |the_tip_pos|,
+% |the_pre_angle|, |the_post_angle|, |the_pre_limit|, |the_post_limit|,
+% |the_pre_lightness|, |the_post_lightness|,
+% |the_pre_deflexion|, and |the_post_deflexion|.
+% There is one sharp ogonek parameter, |ogonek_pen#|; a respective pen is
+% defined at the end of this file (and once again in POLKAP.MF after
+% |font_setup|) and used in the files PL_DL.MF, PL_ML.MF, PL_MLK.MF.
+% Any parameter may have its |lower| variant (see the file POLKAP.MF).
+% ---------------------------------------------------------------------------
+% two handy macros:
+vardef cross_point(expr a,b) (expr c,d) =
+ save z_; pair z_; z_=whatever[a,b]; z_=whatever[c,d]; z_
+% the crossing point of lines (not segments) |a--b| and |c--d| is returned
+enddef;
+
+vardef touch_time(expr p,q) = % a variant of |intersectionpoint|
+ save x_,y_; (x_,y_)=p intersectiontimes q; if x_<0: 0 else: y_ fi
+enddef;
+% ---------------------------------------------------------------------------
+% the kernel routine for the ogonek:
+numeric x_down,x_down',y_right,y_right',alpha_a,alpha_d;
+pair z_a,z_b,z_b',z_b'',z_c,z_c',z_c'',z_d;
+
+pair nz_,pz_;
+% with plain's |solve| embeded calls are not allowed, hence a bit tricky
+% variation:
+%%% known zsolve
+vardef zsolve@#(suffix z_)=
+% |@#| is the name of a real monotonic function; it is assumed that
+% |@#(z_')<=0|, |@#(z_'')>0| holds for given |z_'| and |z_''|
+ save nz_,pz_; pair nz_,pz_; % recursive calls are possible
+ nz_:=z_'; pz_:=z_'';
+ forever:
+ z_:=.5[nz_,pz_]; exitif abs(nz_-pz_)<=tolerance; % by default |tolerance=.1|
+ if @#(z_)<=0: nz_ else: pz_ fi :=z_;
+ endfor
+% on exit |z_| is (hopefully) near the point where |@#| changes from
+% negative to positive
+enddef;
+
+vardef down_dir(expr z_b)=
+ zsolve right_dir(z_c); % here |z_c| is computed
+ lft(xpart(directionpoint down of (z_a..controls z_b and z_c..z_d)))-x_down
+enddef;
+
+vardef right_dir(expr z_c)=
+ bot(ypart(directionpoint right of (z_a..controls z_b and z_c..z_d)))-y_right
+enddef;
+% ---------------------------------------------------------------------------
+% ogonek defaults:
+vardef the_ogonek_depth# = % sharp value
+ if known depth_corr: depth_corr* fi\\ desc_depth#
+enddef;
+
+vardef the_left_pos =
+ if known left_corr: left_corr* fi
+ if monospace: 3.75 elseif serifs:
+ if hefty: 2.3 elseif is_bold: 1.7 else: 1.9 fi
+ else: % sansserif
+ if is_bold: 1.65 else: 1.55 fi\\ fi\\ hi.u
+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_top_breadth_corr =
+ if known top_breadth_corr: top_breadth_corr else:
+ if serifs: 1 elseif is_bold: 1.12 elseif is_cap: 1.06 else: .96 fi\\ fi
+enddef;
+
+vardef the_tip_breadth_corr =
+ if known tip_breadth_corr: tip_breadth_corr else: 1 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;
+
+vardef the_pre_limit = % refers to the outer edge
+ if known pre_limit: pre_limit else: x_down-3.5hi.u fi
+enddef;
+
+vardef the_post_limit = % refers to the outer edge
+ if known post_limit: post_limit else: x_down-2hi.u fi
+enddef;
+
+vardef the_pre_lightness = % refers to the inner edge
+ if known pre_lightness: pre_lightness else:
+ if serifs and hefty: .97 elseif not serifs and is_bold: .6
+ elseif is_bold: .66 else: .78 fi\\ fi
+enddef;
+
+vardef the_post_lightness = % refers to the inner edge
+ if known post_lightness: post_lightness else:
+ if serifs:
+ if hefty: .95 elseif is_bold: .66 else: .82 fi
+ else: % sansserif
+ .75 fi\\ fi
+enddef;
+
+vardef the_post_deflexion = % refers to the inner edge
+ if known post_deflexion: post_deflexion elseif serifs and hefty: 0
+ else: -5 fi
+enddef;
+
+vardef the_pre_deflexion = % refers to the inner edge
+ if known pre_deflexion: pre_deflexion
+ elseif known join_angle and not serifs:
+ if is_bold: -4 else: -2 fi\\
+ elseif not serifs: if is_bold: -8 else: -4 fi\\ else: 0 fi
+enddef;
+% ---------------------------------------------------------------------------
+%%% fine lo
+vardef lo suffix z = % in a way |lo| is a counterpart to |hi|
+ if is_small_cap: z_a+((z-z_a) scaled sqrt(body_height#/higher.body_height#))
+ else: z fi
+enddef;
+% ---------------------------------------------------------------------------
+% parameters to |put_ogonek|:
+numeric join_angle; % starting (inner) ogonek direction, if known
+numeric ogonek_breadth; % ogonek breadth at the tip
+% starting (inner for `e' with ogonek, otherwise outer) ogonek position:
+pair ogonek_pos;
+% ---------------------------------------------------------------------------
+def put_ogonek(suffix penkind) =
+ begingroup
+ 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
+
+ fix_virgin z; pickup penkind.nib;
+
+% `a' with ogonek attached to the hook deserves a special treatment:
+ if\\ (not is_small_cap) and (charcode=oct"241") and serifs and not is_bold:
+ if ypart(ogonek_pos)>.5penkind:
+ z[ii]~l=ogonek_pos;
+ pos[ii]~(max(the_top_breadth_corr*ogonek_breadth,penkind+epsilon),0);
+ ogonek_pos:=cross_point((0,.5penkind),(1,.5penkind))
+ (z[ii]~l,z[ii]~l+dir(the_pre_angle));
+ fi
+ fi
+
+% similarly, `e' with ogonek deserves a special treatment:
+ if\\ (not is_small_cap) and (charcode=oct"246"):
+ if ypart(ogonek_pos)>.5penkind:
+ z[ii]~r=ogonek_pos;
+ pos[ii]~(max(the_top_breadth_corr*ogonek_breadth,penkind+epsilon),0);
+ ogonek_pos:=cross_point((0,.5penkind),(1,.5penkind))
+ (z[ii]~l,z[ii]~l+dir(join_angle));
+ fi
+ fi
+
+% invariant: |ypart(ogonek_pos)|$\le$|.5penkind|;
+% moreover, for `A' and `E': |ypart(ogonek_pos)=.5penkind|
+
+% OUTER EDGE:
+ alpha_a:=the_pre_angle; % starting direction
+ alpha_d:=180+the_post_angle; % ending direction
+ x_down:=if serifs: hround else: ceiling fi
+ (xpart(ogonek_pos)-the_left_pos); % left bound
+ y_right:=-vround(d+hi.o); % bottom bound
+ z_a:=(x_down+the_left_pos,ypart(ogonek_pos)); % starting point
+ z_d:=(xpart(z_a)-.5penkind,y_right+ypart(ogonek_pos))+
+ the_tip_pos; % ending point
+% guess the boundaries for control points:
+ z_b':=cross_point (z_a,z_a+dir alpha_a)
+ ((the_pre_limit,0),(the_pre_limit,1));
+ z_b'':=cross_point (z_b',z_a)\\ ((x_down,0),(x_down,1));
+ z_c':=cross_point (z_d,z_d+dir alpha_d)
+ ((the_post_limit,0),(the_post_limit,1));
+ z_c'':=cross_point (z_c',z_d)\\ ((0,y_right),(1,y_right));
+% THE PIVOT STEP OF THE OGONEK PROCEDURE, i.e.,
+% determine the control points (|z_b| and |z_c|) of the outer path:
+ zsolve down_dir(z_b); % |down_dir| calls `|zsolve right_dir(z_c)|'
+ x_down':=xpart(lft(directionpoint down of
+ (z_a..controls z_b and z_c..z_d)));
+ y_right':=ypart(bot(directionpoint right of
+ (z_a..controls z_b and z_c..z_d)));
+ if abs(x_down'-x_down,y_right'-y_right)>sqrt2:
+ message "ERROR: `ogonek' iteration hasn't converged! Final values:";
+ message "x_down="&decimal x_down'&" (should be "&decimal x_down&")";
+ message "y_right="&decimal y_right'&" (should be "&decimal y_right&")";
+ errhelp "Maybe Jackowski knows how to change them...";
+ errmessage "Probably, you have to change somehow the boundary values";
+ fi
+
+% small caps have ogoneks a bit smaller:
+ z[ii]l=z_a; z[ii]'l=lo.z_b; z[jj]'l=lo.z_c; z[jj]l=lo.z_d;
+
+% INNER EDGE:
+ pos[ii](max(the_top_breadth_corr*ogonek_breadth,penkind+epsilon),0);
+ pos[jj](max(the_tip_breadth_corr*ogonek_breadth,penkind+epsilon),
+ angle(direction 1 of (z_a..controls z_b and z_c..z_d))+
+ if serifs: 90 else: 80 fi);
+
+ z[ii]'r=z[ii]r+((z[ii]'l-z[ii]l) scaled the_pre_lightness
+ rotated the_pre_deflexion);
+ z[jj]'r=z[jj]r+((z[jj]'l-z[jj]l) scaled the_post_lightness
+ rotated the_post_deflexion);
+
+% trim the top of the ogonek, if necessary:
+ path ogonek.l, ogonek.r; numeric tt.r, tt.l;
+
+ ogonek.l=if is_known z[ii]~: % minuscule with ogonek
+ z[ii]~l{dir if charcode=oct"241": the_pre_angle else: join_angle fi}..fi
+ z[ii]l..controls z[ii]'l and z[jj]'l..z[jj]l;
+ ogonek.r=if is_known z[ii]~: % ditto
+ z[ii]~r{dir if charcode=oct"241": the_pre_angle else: join_angle fi}..fi
+ z[ii]r..controls z[ii]'r and z[jj]'r..z[jj]r;
+
+ tt.r=if serifs and (not is_small_cap) and (charcode=oct"241"):
+ touch_time(p.l,ogonek.r) else: 0 fi;
+ tt.l=if\\ (not is_small_cap) and (charcode=oct"246"):
+ touch_time(p.r,ogonek.l) else: 0 fi;
+% at last, draw the ogonek:
+ if ogonek_breadth>.5:
+ interim turningcheck:=0; filldraw
+ if\\ (not is_small_cap) and (charcode=oct"246"):
+ (point tt.r of ogonek.r){direction tt.r of ogonek.r}..{curl 1} fi
+ subpath (tt.l,length ogonek.l) of ogonek.l--
+ reverse(subpath (tt.r,length ogonek.r) of ogonek.r)
+ if is_small_cap or (charcode<>oct"246"): -- else: & fi\\ cycle;
+% the |draw| command covers with ink unwanted breaks:
+ pickup pensquare scaled (.5*sqrt2) rotated 45;
+ draw .5[z[ii]l,z[ii]r]..controls .5[z[ii]'l,z[ii]'r] and
+ .5[z[jj]'l,z[jj]'r].. .5[z[jj]l,z[jj]r];
+ else: % poor resolution:
+ pickup pensquare scaled (.5*sqrt2) rotated 45;
+ draw z[ii]l..controls z[ii]'l and z[jj]'l..z[jj]l;
+ fi
+
+ numeric join_angle, ogonek_breadth; pair ogonek_pos; % all they are local
+
+ penlabels([ii],[jj]);
+
+ endgroup
+enddef;
+%*******************************************************************************
+%
+% This was csaccent.mf in text format, as of 89/05/08
+% written by P. Novak, Prague
+% Czech and Slovak letters with accents
+% Changed paths for acute and hachek accent added 26/04/92, 11/08/92
+% Accent definitions |lc_circle_accent| modified
+% |uc_Circle_accent| added for Duerer font
+%
+% 7 May 1995 did whole sale surgery to this part. Moved parameters to
+% dxpseudo.mf to be able to manipulate them from there. The Acute
+% accent is done the polish way, therefore removed all acute related
+% macros. Pseudoparametrised all kinds of |dot_diam|.
+% 17 Jun 1995 adjusted hachek height parameters to blend better with acute
+% parameters. Removed lots of stuff not used by the dc and tc fonts.
+% 17 Jul 1995 corrected uppercase hachek height for sans serif case
+% Removed many macros, which aren't used anymore
+% 23 Aug 1996 Adjusted |lc_hachek_accent| for dcsx font
+% 23 Dec 1996 Done provisions for small caps fonts, consequently
+% applied |hi.|, replaced |curve| by |cap_curve| for |uc_hachek_accent|,
+% adjusted numeric factors to the usually higher value of |cap_curve|.
+% 19 Jan 1997 The |uc_hacheck_accent| comes out too high, because of
+% unwanted white space above it. Changed appropriately.
+% 26 May 1997 Adjusted |lc_hachek_accent| for CM Bright (CMBR).
+%===============================================================================
+
+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(0.33[x_height,lc_hachek_height]);% (CMBR)
+% bot y52=vround(max(2/3[h,hi.x_height],hi.x_height+o+hair));
+ top y51 = top y53 = lc_hachek_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;
+
+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;
+%%