Erik van Blokland 3646055ea2 initial import
git-svn-id: http://svn.robofab.com/trunk@1 b5fa9d6c-a76f-4ffd-b3cb-f825fc41095c
2008-01-07 17:40:34 +00:00

163 lines
6.6 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<xml>
<synopsis description="" keywords="" generate="0" name="RoboThon 2006" />
<h1>
Kerning and building Glyphs
</h1>
<img src="http://letterror.com/code/robofab/img/ondrawmodel_11.gif"/>
<h2>Kerning</h2>
<p>
All kerning data of a font is represented by the <strong>Kerning</strong> object. This object behaves like a Python dictionary: the key is a tuple of two glyph or groupnames, the dictionary value is the kern distance.
</p>
<p>In FontLab, font.kerning should not be called repeatedly like a normal attribute. Nothing will go wrong if you do, it will just be slow. The reason for this is that font.kerning is an attribute which (under the hood) has to do a lot of work to collect the data from the underlying FontLab file. Kerning in FontLab is stored at the glyph level, so to pull it up to the RoboFab level a massive iteration must occur when the kerning object is created. This happens each time you ask for the font.kerning attribute. But there's a simple way to work with that efficiently: cache the kerning object. Like so:
</p>
<pythonsource src="examples/workWithKerning1.py"/>
<python type="output"><![CDATA[<RKerning for MyFont Normal>
3141
[('F', 'L'), ('D', 'G'), ('N', 'Eacute'), ..etc.. ]
]]></python>
<p>
The Kerning object has some useful methods to transform and analyse the data.
</p>
<pythonsource src="examples/workWithKerning2.py"/>
<python type="output"><![CDATA[<RKerning for MyFont Normal>
-20.5953517988
{'a': 82, 'b': 52}
(-191, 184)
font has 3141 kerning pairs
('F', 'L') -7
('D', 'G') 31
('N', 'Eacute') -34
('agrave.sc', 'z') -7
('K', 'v') -111
('Z', 'N') -15
..etc..
]]></python>
<p>
In the example above you see the Kerning object as attribute of a font object, then it is cached by storing it in a new variable. <strong>len(kerning)</strong> gives you the length of the kerning dictionary, the number of kern pairs. Have a look at the attributes and methods of the <a href="http://letterror.com/code/robofab/objects/kerning.html" target="new" class="reference">Kerning object here.</a> It has some very useful methods for interpolating, sorting, combining and splitting kern tables. Back to the example, did you note that the kern pairs appear in random order? It's that Python dictionary thing again: keys of a dictionary have no particular order. Just like the example of the glyphnames in a font object.
</p>
<pythonsource src="examples/workWithKerning3.py"/>
<python type="output"><![CDATA[K v -111
N Atilde -114
W o -118
W odieresis -118
Acircumflex Y -103
T e -153
T adieresis -126
T odieresis -133
T aacute -126
W eacute -141
..etc..
]]></python>
<p>
Another example of iterating through the kerning dictionary. This time each kern is tested if the value is less than -100, and only when this is the case the pair is printed. This shows you how you can write code which responds to particular kinds of kerns.
</p>
<pythonsource src="examples/workWithKerning4.py"/>
<python type="output"><![CDATA[acircumflex k -7
acircumflex v -38
acircumflex r -4
acircumflex u -4
acircumflex y -31
acircumflex j -26
..etc..
]]></python>
<p>
This script prints all kerns with <strong>acircumflex</strong> as first glyph.
</p>
<h3>Building glyphs</h3>
<img src="http://letterror.com/code/robofab/img/ondrawmodel_20.gif"/>
<img src="http://letterror.com/code/robofab/img/ondrawmodel_26.gif"/>
<p>
A particularly interesting topic of scripting is building glyphs out of component parts. If a font already has all the parts, a script can, in many cases, assemble the accented versions. An overview of <a href="http://letterror.com/code/robofab/howto/buildingaccents.html" class="reference" target="docs">glyph building options is in the how-to section of the Robofab docs</a>. The first example takes a look at all necessary ingredients: making a new glyph, adding parts and finishing it. Then we'll look at more efficient ways.
</p>
<pythonsource src="examples/buildingAccents1.py"/>
<p>
Let's have a look at that line by line. <strong>f.newGlyph("aacute")</strong>. The <strong>newGlyph()</strong> of the <strong>Font</strong> object creates a new glyph and names it <strong>"aacute"</strong>. Then we can get to the new glyph by asking the font. The <strong>Glyph</strong> object has a <strong>appendComponent()</strong> method, which takes a glyphName of the glyph you want to add as a component and optionally an offset coordinate. This you can see in the line where the <strong>acute</strong> glyph is added. Then the width of the new glyph is set to the width of the original glyph. Finally FontLab is told to update.
</p>
<p>
Well, that's going to be an awful lot of code if you have to write 4 lines of code for each new letter. There are other ways of going about this, using FontLab's <strong>Anchor</strong> points. </p>
<h3>glyph.generateGlyph()</h3>
<p>
RoboFab has a database of glyph constructions based on the Adobe Glyph List. Have a look in your RoboFab code folder, <strong>robofab/Data/GlyphConstruction.txt</strong>. The RoboFab list contains information about where components should be connected and what the anchor points are called.
</p>
<python><![CDATA[Acircumflexdotaccent: A circumflex.top dotaccent.bottom]]></python>
<p>
This entry shows that Acircumflexdotaccent is constructed with components from A, a circumflex using the <strong>top</strong> anchor, and dotaccent using the <strong>bottom</strong> anchor. In order to make this work, you need to add anchor points to your glyphs and accents. Check the FontLab manual for instructions. For instance the "a" has an anchor point named "top", the "acute" glyph has one named "_top".
</p>
<python><![CDATA[# building a glyph from parts
from robofab.world import CurrentFont
f = CurrentFont()
font.generateGlyph("aacute")
]]></python>
<p>
This creates a new glyph at "aacute", it puts all the components in the right place and sets the width.
</p>
<h3>glyph.compileGlyph()</h3>
<p>
Suppose you want to create glyphs using anchor points, but the glyphs don't have entries in Robofab's <strong>GlyphConstruction.txt</strong> list. What to do? Editing GlyphConstruction.txt is not recommended because you will loose your changes when you install a new version of RoboFab. Glyph has another method: <strong>compileGlyph()</strong>. This method, like generateGlyph, builds a new glyph with components, but you get to provide the list and tell which anchor points you want to use. CompileGlyph takes a list of accents and anchors. It will follow the list and allow "stacking" of accents.
</p>
<pythonsource src="examples/compileGlyph.py"/>
<h2>Next</h2>
<p>
The Robofab stuff will continue with:
<a href="talks/robofab_session5.html">Scripting for interpolation</a>
</p>
</xml>