Sophie

Sophie

distrib > Mageia > 5 > i586 > media > core-release > by-pkgid > 6b465285c9860724a695461ac61807f4 > files > 350

fontforge-1.0-1.20120731.9.mga5.i586.rpm

<HTML>
<HEAD>
  <!-- Created with AOLpress/2.0 -->
  <!-- AP: Created on: 21-Mar-2005 -->
  <!-- AP: Last modified: 11-Nov-2009 -->
  <TITLE>Contextual features</TITLE>
  <LINK REL="icon" href="fftype16.png">
  <LINK REL="stylesheet" TYPE="text/css" HREF="FontForge.css">
</HEAD>
<BODY>
<P ALIGN=CENTER>
<IMG SRC="fontforge-banner-420.jpeg" WIDTH=420 HEIGHT=80>
<DIV id="in">
  <H1 ALIGN=Center>
    Tutorial #7
  </H1>
  <UL>
    <LI>
      <A HREF="editexample.html#FontCreate">Font Creation</A>
    <LI>
      <A HREF="editexample.html#CharCreate">Creating a glyph (tracing outlines)</A>
    <LI>
      <A HREF="editspiro.html">Create glyph outlines using spiro points</A>
    <LI>
      <A HREF="importexample.html">Importing a glyph from Inkscape (or Illustrator,
      or some other vector editor)</A>
    <LI>
      <A HREF="editexample2.html#Navigating">Navigating to other glyphs</A>
    <LI>
      <A HREF="editexample2.html#Creating-o">On to the next glyph (consistent
      directions)</A>
    <LI>
      <A HREF="editexample3.html#consistent-stems">Consistent serifs and stem
      widths</A>
    <LI>
      <A HREF="editexample4.html#accents">Building accented glyphs</A>
    <LI>
      <A HREF="editexample4.html#ligature">Building a ligature</A>
    <LI>
      <A HREF="editexample4.html#lookups">Lookups and features</A>
    <LI>
      <A HREF="editexample5.html#metrics">Examining metrics</A>
    <LI>
      <A HREF="editexample5.html#Kerning">Kerning</A>
    <LI>
      <A HREF="editexample6.html#Variants">Glyph variants</A>
    <LI>
      <A HREF="editexample6.html#Marks">Anchoring marks</A>
    <LI>
      <A HREF="editexample6-5.html">Conditional features</A>
      <UL>
	<LI>
	  <A HREF="editexample6-5.html#OpenType">OpenType</A> (behavior needed in latin
	  for script joins)
	<LI>
	  <A HREF="editexample6-5.html#Apple">Apple</A> (behavior needed in latin for
	  script joins)
	<LI>
	  <A HREF="editexample6-5.html#Greek">OpenType</A> (Greek ligatures)
      </UL>
    <LI>
      <A HREF="editexample7.html#checking">Checking your font</A>
    <LI>
      <A HREF="editexample7.html#generating">Generating it</A>
    <LI>
      <A HREF="editexample7.html#Families">Font Families</A>
    <LI>
      <A HREF="editexample7.html#summary">Final Summary</A>
    <LI>
      <A HREF="editexample8.html">Bitmap strikes</A>
    <LI>
      <A HREF="scripting-tutorial.html">Scripting Tutorial</A>
    <LI>
      <A HREF="scriptnotes.html#Special">Notes on various scripts</A>
    <LI>
      <FORM method=GET action="http://www.google.com/search">
	Searching the documentation:
	<INPUT type=hidden name="as_sitesearch" value="fontforge.sourceforge.net">
	<INPUT type=text name="as_q">
	<INPUT type=submit name="btnG" value="Search">(Powered by
	<A HREF="http://www.google.com/">Google</A>)
      </FORM>
  </UL>
  <H2>
    <A NAME="Conditional">Conditional</A> Features
  </H2>
  <P>
  OpenType and Apple fonts both provide contextual features. These are features
  which only take place in a given context and are essential for typesetting
  Indic and Arabic scripts. In OpenType a context is specified by a set of
  patterns that are tested against the glyph stream of a document. If a pattern
  matches then any substitutions it defines will be applied. In an Apple font,
  the context is specified by a state machine -- a mini program which parses
  and transforms the glyph stream.
  <P>
  Conditional features may involve substitutions, ligatures or kerning (and
  some more obscure behaviors). First I shall provide an example of a contextual
  substitution, later of <A HREF="editexample6-5.html#Greek">contextual
  ligatures</A>.
  <P>
  <IMG SRC="bed-script.png" WIDTH="259" HEIGHT="81" ALIGN="Right">Instead of
  an Indic or Arabic example, let us take something I'm more familiar with,
  the problem of typesetting a latin script font where the letters ``b,'' ``o,''
  ``v'' and ``w'' join their following letter near the x-height, while all
  other letters join near the baseline. Thus we need two variants for each
  glyph, one that joins (on the left) at the baseline (the default variant)
  and one which joins at the x-height. Let us call this second set of letters
  the ``high'' letters and name them ``a.high,'' ``b.high'' and so forth.
  <H3>
    <A NAME="OpenType">OpenType</A> Example
  </H3>
  <P>
  <TABLE BORDER CELLPADDING="2" ALIGN="Center" BGCOLOR="#ffffa0" WIDTH="80%">
    <CAPTION>
      <FONT COLOR="Red"> <STRONG>Warning</STRONG></FONT>
    </CAPTION>
    <TR>
      <TD >The following example may not work! The font tables produced by it are
	all correct, but early implementations of OpenType did not support decided
	the "Contextual Alternative" ('calt') feature for the latin script.
	<P>
	Why do I provide an example which might not work? It's the best I can do. If
	I knew enough about Indic or Arabic typesetting I would provide an example
	for those scripts. But I don't. The procedures are the same. If you follow
	them for some other scripts they will work.
	<P>
	As time has gone on 'calt' has been supported by more applications for latn and
	this warning is no longer as applicable as it once was.</TD>
    </TR>
  </TABLE>
  <P>
  We divide the set of possible glyphs into three classes: the letters ``bovw'',
  all other letters, and all other glyphs. We need to create two patterns,
  the first will match a glyph in the ``bovw'' class followed by another glyph
  in the ``bovw'' class, while the second will match a glyph in the ``bovw''
  class followed by any other letter. If either of these matches the second
  glyph should be transformed into its high variant.
  <UL>
    <LI>
      [bovw] [bovw] =&gt; Apply a substitution to second letter
    <LI>
      [bovw] &lt;any other letter&gt; =&gt; Apply a substitution to the second
      letter
  </UL>
  <P>
  (You might wonder why I don't just have a class of all letters and use one
  rule instead of two? Because in this case all my classes must be disjoint,
  I mayn't have one glyph appearing in two classes).
  <P>
  The first thing we must do is create a simple substitution mapping each low
  letter to its high variant. This is a "Simple Substitution" lookup, but it
  will not be attached to any feature, instead it will be invoked by a contextual
  lookup. Let us call this lookup "high". We must (of course) create a subtable
  to go with our lookup, and we can use the [Default with Suffix:] button to
  fill it up with the high variants.
  <P>
  The tricky part is defining the context. This is done by defining yet another
  lookup, a contextual chaining lookup which should be associated with a 'calt'
  feature. And of course we want an associated subtable). This will pop up
  a series of dialogs to edit a contextual subtable
  <P>
  <IMG SRC="contextchain-format.png" WIDTH="476" HEIGHT="503" ALIGN="Left">
  The first dialog
  allows you to specify the overall format of the substitution. We want a class
  based system -- we've already mentioned what the glyph classes will
  be.<BR CLEAR=ALL>
  <P>
  <IMG SRC="contextchain-simpleclasses.png" WIDTH="476" HEIGHT="503" ALIGN="Right">
  The next dialog
  finally shows something interesting. At the top is a pattern
  to match and substitutions that will be applied if the string matches. Underneath
  that are the glyph classes that this substitution uses. A contextual chaining
  dialog divides the glyph stream into three sections: those glyphs before
  the current glyph (these are called backtracking glyphs), the current glyph(s)
  itself (themselves), which may have
  simple substitutions applied to them, and finally glyphs after the current
  glyph (these are called lookahead glyphs).
  <P>
  Each category of glyphs may divide glyphs into a different set of classes,
  but in this example we use the same classes for all categories (this makes
  it easier to convert the substitution to Apple's format). The first line
  (in the ``Matching rules'' field) should be read thus: If a backtracking glyph
  (the glyph before the current one) in class "high-after" is followed by the
  current glyph in class "letter", then that letter in the match string
  (that is the current glyph) should have simple substitution `To-TopJoin'
  applied to it.
  <P>
  If you look at the glyph class definitions you will see that class "high-afters"
  includes those glyphs which must be followed by a high variant, so this seems reasonable.
  <P>
  Now there should be a second line which would look like
  <CODE>"high-after | high-after @&lt;To-TopJoin&gt; |"</CODE> to handle
  the second case mentioned above. Unfortunately that doesn't seem to work.
  The OpenType spec allows for it, but implementations of OpenType don't
  seem to support it. Instead that line must be in a separate sub-table in
  the same lookup.<BR CLEAR=ALL>
  To edit a glyph class simply click on it and type. To create a new one press
  the &lt;New&gt; button (at the bottom of the list). You can also click on
  the little box thingy off on the right. This produces another dialog showing
  a font view. You can select glyphs in the font view if that is easier than
  remembering their names.
  <P>
  You may edit a pattern in the obvious way. As you enter glyph names they will
  be auto completed for you. There are two buttons down at the bottom of the
  pattern list, one to start a new section (go from back tracking to active, or
  from active to lookahead), and one to add a new lookup reference.
  <P>
  <FONT COLOR="Red"><STRONG>A warning about contextual
  behavior:</STRONG></FONT> Not all software supports them. And even more confusing
  software may support them for some scripts and not for others.
  <H3>
    <A NAME="Apple">Apple</A> advanced typography
  </H3>
  <P>
  Apple specifies a context with a finite state machine, which is essentially
  a tiny program that looks at the glyph stream and decides what substitutions
  to apply. Each state machine has a set of glyph class definitions (just as
  in the OpenType example), and a set of states. The process begins in state
  0 at the start of the glyph stream. The computer determines what class the
  current glyph is in and then looks at the current state to see how it will
  behave when given input from that class. The behavior includes the ability
  to change to a different state, advancing the input to the next glyph, applying
  a substitution to either the current glyph or a previous one (the ``marked''
  glyph).
  <P>
  <IMG SRC="sm-picture.png" WIDTH="386" HEIGHT="130" ALIGN="Right">Using the
  same example of a latin script font... We again need a simple substitution
  to convert each letter into its high alternate. The process is the same as
  it was for OpenType, and indeed we can use the same substitution. Again we
  divide the glyphs into three classes (Apple gives us some extra classes whether
  we want them or no, but conceptually we use the same three classes as in
  the OpenType example). We want a state machine with two states (again Apple
  gives us an extra state for free, but we shall ignore that), one is the start
  state (the base state -- where nothing changes), and the other is the state
  where we've just read a glyph from the ``bovw'' class. <BR CLEAR=ALL>
  <P>
  <IMG SRC="asm1.png" WIDTH="439" HEIGHT="427" ALIGN="Left"> Apple Advanced
  Typography does not quite fit into the OpentType concepts of lookups and
  features, but it is close enough that I sort of force it to. So once again
  we create a GSUB lookup. This time the lookup type is "Mac Contextual State
  Machine", and the feature is actually a mac feature/setting, two numbers.
  When we create a new subtable of this type we get a state machine dialog,
  as shown below.
  <P>
  <IMG SRC="asm2.png" WIDTH="309" HEIGHT="381" ALIGN="Right"> At the top of
  the dialog we see a set of class definitions, and at the bottom is a
  representation of the state machine itself. <BR CLEAR=Left>
  <P>
  <IMG SRC="asm3.png" WIDTH="309" HEIGHT="206" ALIGN="Left">Double clicking
  on a class brings up a dialog similar to that used in OpenType<BR CLEAR=Right>
  <P>
  <IMG SRC="asm4.png" WIDTH="196" HEIGHT="307" ALIGN="Right"> Clicking on a
  transition in the state machine (there is a transition for each state / class
  combination) produces a transition dialog. This controls how the state machine
  behaves when it is in a given state and receives a glyph in a given class.
  In this example it is in state 2 (which means it has already read a ``bovw''
  glyph), and it has received a glyph in class 4 (which is another ``bovw''
  glyph). In this case the next state will be state 2 again (we will have just
  read a new ``bovw'' glyph), read another glyph and apply the ``high''
  substitution to the current glyph.
  <P>
  At the bottom of the dialog are a series of buttons that allow you to navigate
  through the transitions of the state machine.
  <P>
  Pressing [OK] many times will extract you from this chain of dialogs and
  add a new state machine to your font.<BR CLEAR=ALL>
  <H2>
    OpenType, <A NAME="Greek">Greek</A> ligatures
  </H2>
  <P>
  Greek has a character (U+03D7) which is equivalent to the Latin ampersand.
  Just as the ampersand is (originally) a ligature of "E" and "t", so U+03D7
  is a ligature of "kappa" and "iota". However this ligature should only be
  used if "kappa" and "iota" make up a word unto themselves, it should not
  be used for more normal occurances of the two within a longer word.
  <P>
  <IMG SRC="kappa_iota-lookup.png" WIDTH="239" HEIGHT="315" ALIGN="Right">So
  the first thing to do is create the ligature itself. Add the glyph for U+03D7,
  and then create a ligature lookup and subtable (with
  <CODE><A HREF="fontinfo.html#Lookups">Element-&gt;Font
  Info-&gt;Lookups)</A></CODE> to bind U+03D7 to be a ligature of "kappa" and
  "iota". This lookup will never be used directly -- only under the control
  of another, a conditional feature -- so we don't give it a feature tag.<BR>
  <IMG SRC="kappa_iota-subtable.png" WIDTH="292" HEIGHT="172">
  <P>
  Next the conditional bit.
  <P>
  I'm going to use the notation &lt;letters&gt; to represent a class consisting
  of all greek letters.
  <OL>
    <LI>
      &lt;letters&gt; kappa iota =&gt; no substitution
    <LI>
      kappa iota &lt;letters&gt; =&gt; no substitution
    <LI>
      kappa iota =&gt; apply the ligature "WORD"
  </OL>
  <P>
  <SMALL>(Now as I read the standard all these rules could be put into one
  subtable, and the font validation tools I have agree with me -- but the layout
  engines do not. The layout engines seem to insist that each rule live in
  its own subtable. This is inconvenient (the classes must be defined in each
  subtable) but it seems to work.)</SMALL>
  <P>
  These rules will be executed in order, and the first one that matches the
  input text will be the (one and only) rule applied. Consider these three
  strings, <IMG SRC="alphakappaiota.png" WIDTH="23" HEIGHT="12">,
  <IMG SRC="kappaiotatheta.png" WIDTH="24" HEIGHT="12">,
  <IMG SRC="alphakappaiotatheta.png" WIDTH="30" HEIGHT="12"> all contain kappa
  and iota but each contains more letters around them, so none should be replaced
  by the ligature.
  <UL>
    <LI>
      The first string, <IMG SRC="alphakappaiota.png" WIDTH="23" HEIGHT="12">,
      will match the first rule above (it contains letters before the kappa iota
      sequence) and no substitution will be done. It also matches the third rule,
      but we never get that far.
    <LI>
      The second string, <IMG SRC="kappaiotatheta.png" WIDTH="24" HEIGHT="12">,
      will match the second rule above (it contains letters after the sequence)
      and again no substitution will be done. It would match the third rule, but
      we stop with the first match.
    <LI>
      The third string, <IMG SRC="alphakappaiotatheta.png" WIDTH="30" HEIGHT="12">,
      matches all the rules, but since the search stops at the first match, only
      the first rule will be applied, and no substitution will be done.
    <LI>
      The string, <IMG SRC="spacekappaiotaspace.png" WIDTH="29" HEIGHT="12">, matches
      neither of the first two rules but does match the last, so here the ligature
      will be formed.
  </UL>
  <P>
  You might wonder why I don't just have one rule
  <OL>
    <LI>
      &lt;any non-letter&gt; kappa iota &lt;any non-letter&gt; =&gt; apply our
      ligature
  </OL>
  <P>
  It seems much simpler.
  <P>
  Well there's one main reason:
  <UL>
    <LI>
      This does not work if the kappa is at the beginning of the input stream (it
      will not be preceded by any glyphs, but might still need replacing), or iota
      at the end.
  </UL>
  <P>
  Now how do we convert these rules into a contextual lookup?
  <P>
  <IMG SRC="kappa_iota-context.png" WIDTH="246" HEIGHT="315" ALIGN="Left">We
  use <CODE><A HREF="fontinfo.html#Contextual">Element-&gt;Font
  Info-&gt;Lookups-&gt;Add Lookup</A></CODE> to create a new contextual chaining
  lookup. This is the top level lookup and should be bound to a feature tag
  in the Greek script.
  <P>
  We have three rules, each rule lives in its own subtable, so we will create
  three subtables, one for each. The order in which these subtables n the Lookups
  pane is important because that is the order in which the rules they contain
  will be executed. We must insure that that final rule which actually invokes
  the ligature is the last one executed (and the last one in the
  list).<BR CLEAR=ALL>
  <TABLE BORDER CELLPADDING="2">
    <TR VALIGN="Top">
      <TD><IMG SRC="hligbyclasses.png" WIDTH="330" HEIGHT="248"><BR>
	Since we are planning on using the class of all greek letters we will want
	to use a class format for this feature. Then we press the <CODE>[Next&gt;]
	</CODE>button.</TD>
      <TD><IMG SRC="emptyhlig.png" WIDTH="330" HEIGHT="337"><BR>
	The main match will be on the letters kappa and iota in all three rules,
	so we need one class for each of them. So in the Match Classes area we press
	the <CODE>[New]</CODE> button...</TD>
    </TR>
    <TR VALIGN="Top">
      <TD><IMG SRC="hligkappaclass.png" WIDTH="330" HEIGHT="195"><BR>
	And type in the word "kappa" and press <CODE>[Next&gt;]</CODE></TD>
      <TD><IMG SRC="hligkappa.png" WIDTH="330" HEIGHT="362"><BR>
	Now we have a class containing the single glyph "kappa". We want to do the
	same thing for "iota" so we press <CODE>[New] </CODE>again.</TD>
    </TR>
    <TR VALIGN="Top">
      <TD><IMG SRC="hligiotaclass.png" WIDTH="330" HEIGHT="195"><BR>
	Again type in "iota" and press <CODE>[Next&gt;]</CODE></TD>
      <TD><IMG SRC="hligkappaiota.png" WIDTH="330" HEIGHT="362"><BR>
	Now we have all the classes we need here. We still need to create classes
	for the lookahead and backtrack. We only need one class for these groups
	and that class will consist of all greek letters.</TD>
    </TR>
    <TR VALIGN="Top">
      <TD><IMG SRC="hligback.png" WIDTH="330" HEIGHT="362"><BR>
	The check box <CODE>[*] Same as Match Classes</CODE> is set, but we don't
	want that, we want our own classes here. So uncheck it.</TD>
      <TD><IMG SRC="hligbacknomatch.png" WIDTH="330" HEIGHT="362"><BR>
	Now the buttons become active and we can create a new class by pressing
	<CODE>[New]</CODE></TD>
    </TR>
    <TR VALIGN="Top">
      <TD><IMG SRC="allgreek.png" WIDTH="313" HEIGHT="276"><BR>
	Now you could go back to the font view and select all of the greek letters,
	and then press the [Set From Font] button in the class dialog.</TD>
      <TD><IMG SRC="hliggreekclass.png" WIDTH="330" HEIGHT="228"><BR>
	But in this case the class we are interested in (all the greek letters) is
	built it, and you can select it from the Standard Class pulldown list (Letters
	in script(s)) Then press <CODE>[Next&gt;]</CODE>.</TD>
    </TR>
    <TR VALIGN="Top">
      <TD><IMG SRC="hliggreekback.png" WIDTH="330" HEIGHT="357"></TD>
      <TD VALIGN="Top"><IMG SRC="hliggreekahead.png" WIDTH="330" HEIGHT="357"><BR>
	Then go through the same process for the look ahead classes (adding one class
	which consists of all the greek letters.</TD>
    </TR>
    <TR VALIGN="Top">
      <TD>Now we have all our classes defined and are finally ready to create the
	patterns for our rules. So underneath "List of lists of class numbers" press
	the <CODE>[New] </CODE>button.<BR>
	<IMG SRC="hlignewrule.png" WIDTH="330" HEIGHT="357"></TD>
      <TD>The first rule begins with all the greek letters in the backtrack area,
	so click on the "Backtrack" tab, and then press on the class consisting of
	all the greek letters. This puts the class number into the pattern area (the
	List of class numbers)<BR>
	<IMG SRC="hligbackrule.png" WIDTH="330" HEIGHT="357"></TD>
    </TR>
    <TR VALIGN="Top">
      <TD>In the match area we want to match kappa and then iota, so click on the
	Match tab, and then on the entries for "kappa" and "iota".<BR>
	<IMG SRC="hligrule.png" WIDTH="330" HEIGHT="357"><BR>
	This rule has no substitutions, so leave the bottom area blank and press
	<CODE>[Next&gt;]</CODE>.</TD>
      <TD>We are done with the first rule. It says:
	<UL>
	  <LI>
	    The previous character should match class 1 of the backtrack classes (and
	    that class contains all greek letters, which is what we want)
	  <LI>
	    The current character should match class 1 of the match classes (and that
	    class contains "kappa")
	  <LI>
	    The next character should match class 2 of the match classes (which is iota)
	  <LI>
	    And if the match is successful, do absolutely nothing.
	</UL>
	<P>
	<IMG SRC="hligbackruledone.png" WIDTH="330" HEIGHT="357"><BR>
	We've got two more rules though, so press <CODE>[OK] </CODE>and then <CODE>[Add
	Subtable]</CODE>. Then go through the process of adding all the classes,
	and then add the match string for this rule.</TD>
    </TR>
    <TR VALIGN="Top">
      <TD>We are done with the second rule. It says:
	<UL>
	  <LI>
	    The current character should match class 1 of the match classes (and that
	    class contains "kappa")
	  <LI>
	    The next character should match class 2 of the match classes (which is iota)
	  <LI>
	    The character after that should match class 1 of the lookahead classes (and
	    that class contains all the greek letters)
	  <LI>
	    And if the match is successful, do absolutely nothing.
	</UL>
	<P>
	<IMG SRC="hligaheadruledone.png"><BR>
	Press <CODE>[OK] </CODE>and<CODE> [Add Subtable] </CODE>for the final rule.</TD>
      <TD><IMG SRC="hligrule.png" WIDTH="330" HEIGHT="357"><BR>
	This rule does have substitutions -- we want to take the two characters and
	convert them into a ligature. So Press <CODE>[New] </CODE>under the sequence
	position list, we want to start at the first character (sequence position
	0) and apply the ligature we called "WORD":<BR>
	<IMG SRC="hligseqdlg.png" WIDTH="177" HEIGHT="156"></TD>
    </TR>
    <TR VALIGN="Top">
      <TD>So if anything doesn't match the first two rules, and does contain a
	kappa followed by an iota, it must be a two letter stand-alone greek word.
	And we want to apply our ligature to it.<BR>
	<IMG SRC="hligallrulesdone.png" WIDTH="330" HEIGHT="357"></TD>
      <TD>Now we are done. Press a series of <CODE>[OK]</CODE>s until all the dialogs
	have been accepted.
	<P>
	<IMG SRC="kappaiota-lookups.png" WIDTH="422" HEIGHT="380"></TD>
    </TR>
  </TABLE>
  <P>
  Once you have created your lookups you may test the result in the
  <A HREF="metricsview.html">metrics view</A>.<BR>
  <IMG SRC="metrics-kappa_iota.png" WIDTH="527" HEIGHT="331">
  <P>
  (This example was provided by Apostolos Syropoulos)
  <P>
  <P ALIGN=Center>
  -- <A HREF="editexample6.html">Prev</A> -- <A HREF="overview.html">TOC</A>
  -- <A HREF="editexample7.html">Next</A> --
</DIV>
</BODY></HTML>