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

279 lines
21 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Building accents</title>
<link href="../default.css" type="text/css" rel="stylesheet" />
</head><body>
<script type="text/javascript" src="http://www.google-analytics.com/urchin.js"></script>
<script type="text/javascript">
_uacct = "UA-2044310-2";
urchinTracker();
</script>
<div id="modellogo">
<img src="../img/drawmodel_header.jpg" width="595" height="112" />
</div>
<div class="leftcontent">
<h1 class="crb-seealso">
RoboFab
</h1>
<p class="menu">
<a href="../index.html">
Home
</a>
<br />
<a href="../download/index.html">
Download v1.1.1
</a>
<br />
<a href="../intro.html">
Intro
</a>
<br />
<a href="../install.html">
Install Notes
</a>
<br />
<a href="../history.html">
History
</a>
<br />
<a href="../executive.html">
Summary
</a>
</p>
<p class="menu">
<a href="index.html">
How to's
</a>
<br />
<a href="../talks/index.html">
Step by step
</a>
<br />
<a href="../tools/dialogs.html">
Fab Dialogs
</a>
<br />
<a href="../objects/index.html">
Object reference
</a>
<br />
<a href="../objects/model.html">
Object map
</a>
<br />
<a href="../tools/index.html">
Tools
</a>
<br />
<a href="../ufo/index.html">
UFO Overview
</a>
<br />
<a href="../ufo/specification.html">
UFO Spec
</a>
<br />
<a href="../limitations.html">
Fab Limitations
</a>
<a href="../links/index.html">
Links
</a>
<br />
<a href="../credits.html">
Credits
</a>
</p>
<h1 class="crb-seealso">
Support RoboFab
</h1>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but21.gif" border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
<input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----MIIHRwYJKoZIhvcNAQcEoIIHODCCBzQCAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYCwSKfv3n+m7gMAQttRdiUdaGxSHt2oKSNvYzSFsBPjNsxmwva6gPCPUFV5sfJY1QJQuzQk8iXLqxb/mKmdoWc8Z2Eq7+rUtgo0149vBg35woLGv8zoMkgbghCcHJjdclAl/KOSqhjCOblpCsXpJwy9fs1wuxSOrbDwO5C26bXOkzELMAkGBSsOAwIaBQAwgcQGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQItAyVpzgCAg2AgaA4Sx/oMTU9S7iN3M25nZ1ebqx2vt1UMGcUGtDmk13jLL1IO4lXmG1Lb/lTKJSg1d2Aj/OQJrOpL7T2yEGFkqK0yojO8+CUXHOihCJ+ovr2r7VkBi2C425JSRjRh5wPc4LN2UxCn2FhMrZwc6Mnq9Emuh2Mf35oEQ2ZfKZs37yDlB6RL4hTfmUEMibLwrQPwD+NmpihgZ6LrWvPrIDLeWFdoIIDhzCCA4MwggLsoAMCAQICAQAwDQYJKoZIhvcNAQEFBQAwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMB4XDTA0MDIxMzEwMTMxNVoXDTM1MDIxMzEwMTMxNVowgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBR07d/ETMS1ycjtkpkvjXZe9k+6CieLuLsPumsJ7QC1odNz3sJiCbs2wC0nLE0uLGaEtXynIgRqIddYCHx88pb5HTXv4SZeuv0Rqq4+axW9PLAAATU8w04qqjaSXgbGLP3NmohqM6bV9kZZwZLR/klDaQGo1u9uDb9lr4Yn+rBQIDAQABo4HuMIHrMB0GA1UdDgQWBBSWn3y7xm8XvVk/UtcKG+wQ1mSUazCBuwYDVR0jBIGzMIGwgBSWn3y7xm8XvVk/UtcKG+wQ1mSUa6GBlKSBkTCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb22CAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCBXzpWmoBa5e9fo6ujionW1hUhPkOBakTr3YCDjbYfvJEiv/2P+IobhOGJr85+XHhN0v4gUkEDI8r2/rNk1m0GA8HKddvTjyGw/XqXa+LSTlDYkqI8OwR8GEYj4efEtcRpRYBxV8KxAW93YDWzFGvruKnnLbDAF6VR5w/cCMn5hzGCAZowggGWAgEBMIGUMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbQIBADAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDYwNTA1MDk0MDI3WjAjBgkqhkiG9w0BCQQxFgQUuGyd1NYqa4RVlKQ48vrRVsRjTXYwDQYJKoZIhvcNAQEBBQAEgYC6ZiJbUzbugBCir8QnRYRas0tJrdMXcUXQnO3HlO5Zj7+F9cGT2NI73VgB5Vhpu+OaMjBcmc8f0LSP6/ns48YZiIki3+nilxKt/sEq3R0B9XeoB21nHxLmlWkFGMGKxPexWEkjJq0v3UNhS6mYDAIdLkrLE6RHRYAVvKET8hkzDw==-----END PKCS7-----
">
</form>
<h2 class="crb-seealso">
Up
</h2>
<p class="menu">
<p class="bonbon_uplink"><a href="index.html">Back to How To</a></p>
</p>
<h2 class="crb-seealso">
See also
</h2>
<p class="menu">
<a href="../objects/component.html">RComponent</a><br /><a href="../objects/contour.html">RContour</a><br /><a href="../talks/robofab_session3.html">Kerning object and glyph building</a><br /><a href="fontlabremote.html">FontLab Remote</a><br /><a href="generatefonts.html">Generate Fonts</a><br /><a href="index.html">How To</a><br /><a href="interpolate.html">How to interpolate</a><br /><a href="lowlevel.html">How to get to FontLab stuff</a><br /><a href="scripting.html">Scripting</a><br /><a href="understandcontours.html">Understanding Contours</a><br /><a href="usepens.html">Using Pens</a><br /><a href="usethelib.html">Using the lib</a><br /><a href="world.html">The world module</a><br />
</p>
</div>
<div class="footer">
<a href="../feedback.html">
Feedback
</a>
<br />
<a href="../map.html">
Sitemap
</a>
<br />
Please also refer to the
<a href="../download/license.html">
Legal
</a>
<br />
Copyright 2003-2006 RoboFab
<br />
version 1.1.1
</div>
<div class="google">
<h2>RoboFab Mailinglist</h2>
<p>
Join the RoboFab users community at Google groups.
</p>
<img src="http://groups.google.com/groups/img/3nb/groups_bar.gif" alt="Google Groups" height="26" width="132" />
<p>
<form action="http://groups.google.com/group/robofab/boxsubscribe">
Email: <input type="text" name="../email" />
<input type="submit" name="../sub" value="Subscribe" />
</form>
</p>
<p>
<a href="http://groups.google.com/group/robofab">Visit this group</a>
</p>
<h2>RoboFab Sponsors</h2>
<script type="text/javascript">
google_ad_client = "pub-3703953449723704";
google_ad_width = 120;
google_ad_height = 600;
google_ad_format = "120x600_as";
google_ad_type = "text_image";
google_ad_channel ="";
google_color_border = "336699";
google_color_bg = "FFFFFF";
google_color_link = "0000FF";
google_color_url = "008000";
google_color_text = "000000";
</script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
</div>
<div class="content">
<h1>Building accents</h1>
<p>
Making accented glyphs is a job where scripting can help save some time. When you have prepared all the parts, the base glyphs and the accents, a script can help to assemble the combinations. There are various ways of doing it, let's start with a simple one.
</p>
<div class="pythonsource"><pre># robofab manual<br>#&nbsp; &nbsp;&nbsp; Buildingaccents howto<br>#&nbsp; &nbsp; usage examples<br> <br><br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">world</span> <span class="py_res">import</span> <span class="py_key">CurrentFont</span><br> <br><span class="py_key">f</span> = <span class="py_key">CurrentFont</span>()<br><span class="py_key">f</span>.<span class="py_key">newGlyph</span>(<span class="py_str">"aacute"</span>)<br><span class="py_key">f</span>[<span class="py_str">"aacute"</span>].<span class="py_key">appendComponent</span>(<span class="py_str">"a"</span>)<br><span class="py_key">f</span>[<span class="py_str">"aacute"</span>].<span class="py_key">appendComponent</span>(<span class="py_str">"acute"</span>, (<span class="py_num">200</span>, <span class="py_num">0</span>))<br><span class="py_key">f</span>[<span class="py_str">"aacute"</span>].<span class="py_key">width</span> = <span class="py_key">f</span>[<span class="py_str">"a"</span>].<span class="py_key">width</span><br><span class="py_key">f</span>.<span class="py_key">update</span>()<br></pre></div><div class="pythonsourcetitle"><a href="examples/usageBuildaccents.py" target="new">download examples/usageBuildaccents.py</a></div>
<p>
In this example the script creates a new glyph, <strong>aacute</strong>, then proceeds to add components, references to other glyphs rather than the glyphs themselves. The glyph method <strong>appendComponent</strong> is used to do this. See how the <strong>acute</strong> component has an extra argument, (200, 0) - this the offset for the accent. Finally the new glyph is given the width of the base <strong>a</strong>.
</p>
<p>
This example illustrates the use of the very basic <strong>appendComponent</strong> method. But it's not a very useful way to make glyphs. For instance, the string <strong>"aacute"</strong> could easily be made into a variable taken from a list. And dealing with the offsets when placing the accent isn't going to be efficient either when you want to make a large list of accented glyphs. How to go about it that?
</p>
<h2>Building accents automagically</h2>
<p>
RoboFab has its own database which connects glyphnames to components. In the RoboFab distribution folder, go to Data/GlyphConstruction.txt. This text file contains a list of glyphnames and from which components they should be built. The RoboFab Glyph Construction database was based on FontLab's glyph list. This list contains information about where components should be connected.
</p>
<div class="pythonoutput"><pre><span class="py_key">Acircumflexdotaccent</span>: <span class="py_key">A</span> <span class="py_key">circumflex</span>.<span class="py_key">top</span> <span class="py_key">dotaccent</span>.<span class="py_key">bottom</span></pre></div>
<p>
This entry shows that Acircumflexdotaccent is constructed with components from A, a circumflex using the top anchor, and dotaccent using the bottom anchor.
</p>
<h2>Generate a glyph</h2>
<p>
RoboFab's Font object has several ways of starting component glyphs and adding stuff to them. There are different strategies possible for different kinds of problems.
</p>
<h3>font.generateGlyph(glyphName, replace, preflight, printErrors)</h3>
<p>
The easiest method to add an assembled glyph to a font is using the font's <strong>generateGlyph</strong> method. This will look for the glyphname in the glyph construction database and attempt to get all the components and place them at the anchors listed in the database. Let's have a look at its parameters.
<ul>
<li><strong>glyphName</strong>: the name of the glyph, has to correspond to a name in the glyph construction database.</li>
<li><strong>replace</strong>: default set to True, the new glyph will replace the old one if it exists.</li>
<li><strong>preflight</strong>: default set to False, preflight gives you the opportunity to run the glyph creation process without actually adding it to the font. This is useful if you're building the characterset and you don't have all the parts yet. Preflight will return a list of missing anchor points, missing accents, components, etc. Note that it can take several iterations of fixing problems and discovering new ones. If for instance a glyph for a componnent can't be found, it also means that some problems with that glyph are hidden. i.e. when a glyph "A" can't be found, preflight can't tell you that this glyph is missing a required anchor point either.</li>
<li><strong>printErrors</strong>: default set to True, print any errors and problems to the standard output window.</li>
</ul>
</p>
<h3>font.compileGlyph(glyphName, baseName, accentNames, adjustWidth=False, preflight=False, printErrors=True)</h3>
<p>
Compile a glyph with specified components. If you want to assemble accents that are not the glyph construction database, using compileGlyph.
<ul>
<li><strong>glyphName</strong>: the name of the glyph where it all needs to go.</li>
<li><strong>baseName</strong>: the name of the base glyph. accentNames: a list of accentName, anchorName tuples, [('acute', 'top'), etc]</li>
<li><strong>preflight</strong>: default set to False, preflight gives you the opportunity to run the glyph creation process without actually adding it to the font. This is useful if you're building the characterset and you don't have all the parts yet. Preflight will return a list of missing anchor points, missing accents, components, etc.</li>
<li><strong>printErrors</strong>: default set to True, print any errors and problems to the standard output window.</li>
</ul>
</p>
<h2>AccentBuilder</h2>
<p>
RoboFab comes with a versatile accent building tool, AccentBuilder. Have a look at robofab.tools.accentbuilder. AccentBuilder deals with components, anchorpoints.
</p>
<div class="pythonsource"><pre># robofab manual<br># Buildingaccents howto<br>#&nbsp; &nbsp; AccentBuilder examples<br> <br><br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">accentBuilder</span> <span class="py_res">import</span> <span class="py_key">AccentTools</span>, <span class="py_key">buildRelatedAccentList</span><br><span class="py_key">font</span> = <span class="py_key">CurrentFont</span><br> <br># a list of accented glyphs that you want to build<br><span class="py_key">myList</span>=[<span class="py_str">'Aacute'</span>, <span class="py_str">'aacute'</span>]<br> <br># search for glyphs related to glyphs in myList and add them to myList<br><span class="py_key">myList</span>=<span class="py_key">buildRelatedAccentList</span>(<span class="py_key">font</span>, <span class="py_key">myList</span>)+<span class="py_key">myList</span><br> <br># start the class<br><span class="py_key">at</span>=<span class="py_key">AccentTools</span>(<span class="py_key">font</span>, <span class="py_key">myList</span>)<br> <br># clear away any anchors that exist (this is optional)<br><span class="py_key">at</span>.<span class="py_key">clearAnchors</span>()<br> <br># add necessary anchors if you want to<br><span class="py_key">at</span>.<span class="py_key">buildAnchors</span>(<span class="py_key">ucXOffset</span>=<span class="py_num">20</span>, <span class="py_key">ucYOffset</span>=<span class="py_num">40</span>, <span class="py_key">lcXOffset</span>=<span class="py_num">15</span>, <span class="py_key">lcYOffset</span>=<span class="py_num">30</span>)<br> <br># print a report of any errors that occured<br><span class="py_key">at</span>.<span class="py_key">printAnchorErrors</span>()<br> <br># build the accented glyphs if you want to<br><span class="py_key">at</span>.<span class="py_key">buildAccents</span>()<br> <br># print a report of any errors that occured<br><span class="py_key">at</span>.<span class="py_key">printAccentErrors</span>()<br></pre></div><div class="pythonsourcetitle"><a href="examples/buildaccentsBuilder.py" target="new">download examples/buildaccentsBuilder.py</a></div>
<h2>Building your own accentbuilders</h2>
<p>
For typeface production it is a good idea to build a set of standardised tools with which you finalise the font data. Here's an example of a script which adds a standardised list of accents to a font. It does not do automatic anchor placement because the scripter wanted to do this manually. But the rest is done automatically. The script also deals correctly with smallcap glyphnames with .sc.
</p>
<div class="pythonsource"><pre># robofab manual<br># Buildingaccents howto<br>#&nbsp; &nbsp; attribute examples<br> <br><br># a script to generate all necessary accented characters.<br># this assumes all anchor points are set correctly.<br># including doublelayer accents. so, add anchorpoints <br># on the accents too!<br># (c) evb<br> <br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">world</span> <span class="py_res">import</span> <span class="py_key">CurrentFont</span><br><span class="py_res">from</span> <span class="py_key">robofab</span>.<span class="py_key">tools</span>.<span class="py_key">toolsAll</span> <span class="py_res">import</span> <span class="py_key">readGlyphConstructions</span><br> <br><span class="py_key">f</span> = <span class="py_key">CurrentFont</span>()<br> <br><span class="py_res">import</span> <span class="py_key">string</span><br> <br><span class="py_key">theList</span> = [<br>&nbsp; &nbsp; # caps<br>&nbsp; &nbsp; <span class="py_str">'AEacute'</span>,<br>&nbsp; &nbsp; <span class="py_str">'AEmacron'</span>,<br>&nbsp; &nbsp; <span class="py_str">'Aacute'</span>,<br>&nbsp; &nbsp; <span class="py_str">'Abreve'</span>,<br>&nbsp; &nbsp; # add all the accents you want in this list<br>]<br> <br><br><span class="py_key">con</span> = <span class="py_key">readGlyphConstructions</span>()<br><span class="py_key">theList</span>.<span class="py_key">sort</span>()<br> <br><span class="py_res">def</span> <span class="py_def">accentify</span>(<span class="py_key">f</span>, <span class="py_key">preflight</span>=<span class="py_key">False</span>):<br>&nbsp; &nbsp; <span class="py_res">print</span> <span class="py_str">'start accentification'</span>, <span class="py_key">f</span>.<span class="py_key">info</span>.<span class="py_key">fullName</span><br>&nbsp; &nbsp; <span class="py_key">slots</span> = <span class="py_key">con</span>.<span class="py_key">keys</span>()<br>&nbsp; &nbsp; <span class="py_key">slots</span>.<span class="py_key">sort</span>()<br>&nbsp; &nbsp; <span class="py_res">for</span> <span class="py_key">k</span> <span class="py_res">in</span> <span class="py_key">theList</span>:<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_res">if</span> <span class="py_key">k</span>[-<span class="py_num">3</span>:] <span class="py_res">in</span> [<span class="py_str">".sc"</span>]:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">isSpecial</span> = <span class="py_key">True</span><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">tag</span> = <span class="py_key">k</span>[-<span class="py_num">3</span>:]<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">name</span> = <span class="py_key">k</span>[:-<span class="py_num">3</span>]<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_res">else</span>:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">isSpecial</span> = <span class="py_key">False</span><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">tag</span> = <span class="py_str">""</span><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">name</span> = <span class="py_key">k</span><br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">parts</span> = <span class="py_key">con</span>.<span class="py_key">get</span>(<span class="py_key">name</span>, <span class="py_key">None</span>)<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_res">if</span> <span class="py_key">parts</span> <span class="py_res">is</span> <span class="py_key">None</span>:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_res">print</span> <span class="py_key">k</span>, <span class="py_str">"not defined?"</span><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="py_res">continue</span><br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">base</span> = <span class="py_key">parts</span>[<span class="py_num">0</span>]<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">accents</span> = <span class="py_key">parts</span>[<span class="py_num">1</span>:]<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">f</span>.<span class="py_key">generateGlyph</span>(<span class="py_key">k</span>, <span class="py_key">preflight</span>=<span class="py_key">preflight</span>)<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">f</span>[<span class="py_key">k</span>].<span class="py_key">mark</span> = <span class="py_num">100</span> + <span class="py_key">randint</span>(-<span class="py_num">20</span>, <span class="py_num">20</span>)<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">f</span>[<span class="py_key">k</span>].<span class="py_key">autoUnicodes</span>()<br>&nbsp; &nbsp; &nbsp; &nbsp; <span class="py_key">f</span>[<span class="py_key">k</span>].<span class="py_key">update</span>()<br>&nbsp; &nbsp; <span class="py_key">f</span>.<span class="py_key">update</span>()<br> <br><span class="py_key">accentify</span>(<span class="py_key">f</span>)<br><span class="py_res">print</span> <span class="py_str">'done'</span><br> <br></pre></div><div class="pythonsourcetitle"><a href="examples/buildaccentsCustom.py" target="new">download examples/buildaccentsCustom.py</a></div>
</div>
</body></html>