CINXE.COM
GDL Code Snippets | Graphite
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <link rel="stylesheet" href="/assets/css/just-the-docs-default.css"> <script src="/assets/js/vendor/lunr.min.js"></script> <script src="/assets/js/just-the-docs.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" href="/assets/images/favicon.ico" type="image/x-icon"> <!-- Begin Jekyll SEO tag v2.8.0 --> <title>GDL Code Snippets | Graphite</title> <meta name="generator" content="Jekyll v4.3.2" /> <meta property="og:title" content="GDL Code Snippets" /> <meta property="og:locale" content="en_US" /> <meta name="description" content="Site for Graphite" /> <meta property="og:description" content="Site for Graphite" /> <link rel="canonical" href="https://silnrsi.github.io/graphite/graphite_codeSnippets.html" /> <meta property="og:url" content="https://silnrsi.github.io/graphite/graphite_codeSnippets.html" /> <meta property="og:site_name" content="Graphite" /> <meta property="og:type" content="website" /> <meta name="twitter:card" content="summary" /> <meta property="twitter:title" content="GDL Code Snippets" /> <script type="application/ld+json"> {"@context":"https://schema.org","@type":"WebPage","description":"Site for Graphite","headline":"GDL Code Snippets","url":"https://silnrsi.github.io/graphite/graphite_codeSnippets.html"}</script> <!-- End Jekyll SEO tag --> </head> <body> <a class="skip-to-main" href="#main-content">Skip to main content</a> <svg xmlns="http://www.w3.org/2000/svg" class="d-none"> <symbol id="svg-link" viewBox="0 0 24 24"> <title>Link</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"> <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path> </svg> </symbol> <symbol id="svg-menu" viewBox="0 0 24 24"> <title>Menu</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu"> <line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line> </svg> </symbol> <symbol id="svg-arrow-right" viewBox="0 0 24 24"> <title>Expand</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right"> <polyline points="9 18 15 12 9 6"></polyline> </svg> </symbol> <!-- Feather. MIT License: https://github.com/feathericons/feather/blob/master/LICENSE --> <symbol id="svg-external-link" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-external-link"> <title id="svg-external-link-title">(external link)</title> <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line> </symbol> <symbol id="svg-doc" viewBox="0 0 24 24"> <title>Document</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"> <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline> </svg> </symbol> <symbol id="svg-search" viewBox="0 0 24 24"> <title>Search</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"> <circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line> </svg> </symbol> <!-- Bootstrap Icons. MIT License: https://github.com/twbs/icons/blob/main/LICENSE.md --> <symbol id="svg-copy" viewBox="0 0 16 16"> <title>Copy</title> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-clipboard" viewBox="0 0 16 16"> <path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z"/> <path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z"/> </svg> </symbol> <symbol id="svg-copied" viewBox="0 0 16 16"> <title>Copied</title> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-clipboard-check-fill" viewBox="0 0 16 16"> <path d="M6.5 0A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3Zm3 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3Z"/> <path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1A2.5 2.5 0 0 1 9.5 5h-3A2.5 2.5 0 0 1 4 2.5v-1Zm6.854 7.354-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 0 1 .708-.708L7.5 10.793l2.646-2.647a.5.5 0 0 1 .708.708Z"/> </svg> </symbol> </svg> <div class="side-bar"> <div class="site-header" role="banner"> <a href="/" class="site-title lh-tight"> Graphite </a> <button id="menu-button" class="site-button btn-reset" aria-label="Toggle menu" aria-pressed="false"> <svg viewBox="0 0 24 24" class="icon" aria-hidden="true"><use xlink:href="#svg-menu"></use></svg> </a> </div> <nav aria-label="Main" id="site-nav" class="site-nav"> <ul class="nav-list"><li class="nav-list-item"><a href="/" class="nav-list-link">Home</a></li><li class="nav-list-item"><button class="nav-list-expander btn-reset" aria-label="toggle items in About Graphite category" aria-pressed="false"> <svg viewBox="0 0 24 24" aria-hidden="true"><use xlink:href="#svg-arrow-right"></use></svg> </button><a href="/graphite_about.html" class="nav-list-link">About Graphite</a><ul class="nav-list"><li class="nav-list-item "><a href="/graphite_aboutWhy.html" class="nav-list-link">Why was Graphite developed?</a></li><li class="nav-list-item "><button class="nav-list-expander btn-reset" aria-label="toggle items in Graphite and OpenType category" aria-pressed="false"> <svg viewBox="0 0 24 24" aria-hidden="true"><use xlink:href="#svg-arrow-right"></use></svg> </button><a href="/graphite_aboutOT.html" class="nav-list-link">Graphite and OpenType</a><ul class="nav-list"><li class="nav-list-item "> <a href="/graphite_otcompare.html" class="nav-list-link">Comparison of OpenType and Graphite shaping speeds in a Nastaliq context</a> </li></ul></li><li class="nav-list-item "><a href="/graphite_techAbout.html" class="nav-list-link">Graphite technical overview</a></li></ul></li><li class="nav-list-item"><a href="/graphite_news.html" class="nav-list-link">News</a></li><li class="nav-list-item"><button class="nav-list-expander btn-reset" aria-label="toggle items in Using Graphite category" aria-pressed="false"> <svg viewBox="0 0 24 24" aria-hidden="true"><use xlink:href="#svg-arrow-right"></use></svg> </button><a href="/graphite_appsParent.html" class="nav-list-link">Using Graphite</a><ul class="nav-list"><li class="nav-list-item "><a href="/graphite_apps.html" class="nav-list-link">Applications that support Graphite</a></li><li class="nav-list-item "><a href="/graphite_firefox.html" class="nav-list-link">Graphite and Firefox</a></li><li class="nav-list-item "><a href="/graphite_fontdemo.html" class="nav-list-link">Graphite Font Demo</a></li><li class="nav-list-item "><a href="/graphite_fonts.html" class="nav-list-link">Graphite-enabled Fonts</a></li></ul></li><li class="nav-list-item active"><button class="nav-list-expander btn-reset" aria-label="toggle items in Developers category" aria-pressed="true"> <svg viewBox="0 0 24 24" aria-hidden="true"><use xlink:href="#svg-arrow-right"></use></svg> </button><a href="/graphite_dev.html" class="nav-list-link">Developers</a><ul class="nav-list"><li class="nav-list-item "><a href="/graphite_devFont.html" class="nav-list-link">Font Development</a></li><li class="nav-list-item "><a href="/graide.html" class="nav-list-link">Graide</a></li><li class="nav-list-item "><button class="nav-list-expander btn-reset" aria-label="toggle items in Graphite Tutorial category" aria-pressed="false"> <svg viewBox="0 0 24 24" aria-hidden="true"><use xlink:href="#svg-arrow-right"></use></svg> </button><a href="/graide_tutorial.html" class="nav-list-link">Graphite Tutorial</a><ul class="nav-list"><li class="nav-list-item "> <a href="/tutorial/graide_tutorial1.html" class="nav-list-link">Unit 1</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial2.html" class="nav-list-link">Unit 2</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial3.html" class="nav-list-link">Unit 3</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial4.html" class="nav-list-link">Unit 4</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial5.html" class="nav-list-link">Unit 5</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial6.html" class="nav-list-link">Unit 6</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial7.html" class="nav-list-link">Unit 7</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial8.html" class="nav-list-link">Unit 8</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial8a.html" class="nav-list-link">Intermission</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial9.html" class="nav-list-link">Unit 9</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial10.html" class="nav-list-link">Unit 10</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial11.html" class="nav-list-link">Unit 11</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial12.html" class="nav-list-link">Unit 12</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial13.html" class="nav-list-link">Unit 13</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial14.html" class="nav-list-link">Unit 14</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial15.html" class="nav-list-link">Unit 15</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial16.html" class="nav-list-link">Unit 16</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial17.html" class="nav-list-link">Unit 17</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial18.html" class="nav-list-link">Unit 18</a> </li><li class="nav-list-item "> <a href="/tutorial/graide_tutorial_end.html" class="nav-list-link">Conclusion</a> </li><li class="nav-list-item "> <a href="/tutorial/graphite_tut_solutions.html" class="nav-list-link">Solutions to Tutorial Exercises</a> </li></ul></li><li class="nav-list-item active"><a href="/graphite_codeSnippets.html" class="nav-list-link active">GDL Code Snippets</a></li><li class="nav-list-item "><a href="/graphite_devApp.html" class="nav-list-link">Adding Graphite to Your Application</a></li></ul></li><li class="nav-list-item"><a href="/graphite_download.html" class="nav-list-link">Download</a></li><li class="nav-list-item"><a href="/graphite_support.html" class="nav-list-link">Support</a></li><li class="nav-list-item"><a href="/graphite_contact.html" class="nav-list-link">Contact</a></li></ul> </nav> <footer class="site-footer"> This site uses <a href="https://github.com/just-the-docs/just-the-docs">Just the Docs</a>, a documentation theme for Jekyll. </footer> </div> <div class="main" id="top"> <div id="main-header" class="main-header"> <div class="search" role="search"> <div class="search-input-wrap"> <input type="text" id="search-input" class="search-input" tabindex="0" placeholder="Search Graphite site" aria-label="Search Graphite site" autocomplete="off"> <label for="search-input" class="search-label"><svg viewBox="0 0 24 24" class="search-icon"><use xlink:href="#svg-search"></use></svg></label> </div> <div id="search-results" class="search-results"></div> </div> <nav aria-label="Auxiliary" class="aux-nav"> <ul class="aux-nav-list"> <li class="aux-nav-list-item"> <a href="https://github.com/silnrsi/graphite" class="site-button" > Repository </a> </li> </ul> </nav> </div> <div id="main-content-wrap" class="main-content-wrap"> <nav aria-label="Breadcrumb" class="breadcrumb-nav"> <ol class="breadcrumb-nav-list"> <li class="breadcrumb-nav-list-item"><a href="/graphite_dev.html">Developers</a></li> <li class="breadcrumb-nav-list-item"><span>GDL Code Snippets</span></li> </ol> </nav> <div id="main-content" class="main-content"> <main> <h1 id="gdl-code-snippets"> <a href="#gdl-code-snippets" class="anchor-heading" aria-labelledby="gdl-code-snippets"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> GDL Code Snippets </h1> <ul> <li><a href="graphite_codeSnippets#diacritic-attachment">Diacritic attachment</a> <ul> <li><a href="graphite_codeSnippets#diacritics-with-calculated-attachment-points">Diacritics with calculated attachment points</a></li> <li><a href="graphite_codeSnippets#stacking-diacritics">Stacking diacritics</a></li> <li><a href="graphite_codeSnippets#bridging-diacritics">Bridging diacritics</a></li> </ul> </li> <li><a href="graphite_codeSnippets#ligatures-conjuncts">Ligatures (conjuncts)</a> <ul> <li><a href="graphite_codeSnippets#ligatures-with-components">Ligatures with components</a></li> </ul> </li> <li><a href="graphite_codeSnippets#contextual-shaping">Contextual shaping</a> <ul> <li><a href="graphite_codeSnippets#word-contextual-shaping">Word-contextual shaping</a></li> </ul> </li> <li><a href="graphite_codeSnippets#reordering">Reordering</a></li> <li><a href="graphite_codeSnippets#splitting">Splitting</a></li> <li><a href="graphite_codeSnippets#font-features-variations">Font features (variations)</a> <ul> <li><a href="graphite_codeSnippets#boolean-feature">Boolean feature</a></li> <li><a href="graphite_codeSnippets#multi-valued-feature">Multi-valued feature</a></li> </ul> </li> </ul> <p>These snippets are intended as a quick reference. For complete documentation of the GDL language, download the reference paper:</p> <p><a href="assets/resources/GDL.pdf" class="btn btn-blue">Download GDL.pdf</a></p> <h2 id="diacritic-attachment"> <a href="#diacritic-attachment" class="anchor-heading" aria-labelledby="diacritic-attachment"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Diacritic attachment </h2> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>table(glyph) // These can also be classes, in which case the attachment point(s) // must be defined on each element of the class: base = glyphid(34) {TopS = point(130m, 512m); BottomS = point(130m, 0m)}; upperdiac = glyphid(101) {TopM = point(86m, -12m)} lowerdiac = glyphid(102) {BottomM = point(86m, 43m)}; endtable; // glyph table(positioning) base upperdiac {attach {to=@1; at=TopS; with=TopM}}; base lowerdiac {attach {to=@1; at=BottomS; with=BottomM}}; endtable; // positioning </code></pre></div></div> <h3 id="diacritics-with-calculated-attachment-points"> <a href="#diacritics-with-calculated-attachment-points" class="anchor-heading" aria-labelledby="diacritics-with-calculated-attachment-points"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Diacritics with calculated attachment points </h3> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>table(glyph) base = glyphid(...) {TopS = point(bb.lsb + bb.width/2, bb.top); BottomS = point(bb.lsb + bb.width/2, bb.bottom)}; upperdiac = glyphid(...) {TopM = point(bb.width/2, bb.bottom - 10m)} lowerdiac = glyphid(...) {BottomM = point(bb.width/2, bb.top + 10m)}; endtable; // glyph table(positioning) base upperdiac {attach {to=@1; at=TopS; with=TopM}}; base lowerdiac {attach {to=@1; at=BottomS; with=BottomM}}; endtable; // positioning </code></pre></div></div> <h3 id="stacking-diacritics"> <a href="#stacking-diacritics" class="anchor-heading" aria-labelledby="stacking-diacritics"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Stacking diacritics </h3> <p>The following example shows how to handle a stack/chain of both upper and lower diacritic attachments. Note that, as specified by the Unicode standard, lower diacritics are first.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>table(glyph) base1 = glyphid(34) {TopS = point(130m, 512m); BottomS = point(130m, 0m)}; base1 = glyphid(35) {TopS = point(130m, 5108m); BottomS = point(130m, -18m)}; upperdiac1 = glyphid(101) {TopM = point(86m, -12m); TopS = point(86m, 43m)}; upperdiac2 = glyphid(105) {TopM = point(81m, -10m); TopS = point(81m, 52m)}; lowerdiac1 = glyphid(102) {BottomM = point(79m, 43m); BottomS = point(79m, -3m)}; lowerdiac2 = glyphid(103) {BottomM = point(77m, 48m); BottomS = point(77m, -5m)}; // etc. base = (base1, base2, ...); upperdiac = (upperdiac1, upperdiac2, ...); lowerdiac = (lowerdiac1, lowerdiac2, ...); takes_lower = (base, lowerdiac); // lower diacritics can be attached to bases or other lower diacs takes_upper = (base, upperdiac); // upper diacritics can be attached to bases or other upper diacs endtable; // glyph table(positioning) // Optionally permit up to three intervening lower diacritics: #define LOWERSEQ [ lowerdiac [ lowerdiac lowerdiac? ]? ]? takes_lower lowerdiac {attach {to=@1; at=BottomS; with=BottomM}} / _ ^ _; takes_upper upperdiac {attach {to=@1; at=TopS; with=TopM}} / _ LOWERSEQ ^ _; endtable; // positioning </code></pre></div></div> <h3 id="bridging-diacritics"> <a href="#bridging-diacritics" class="anchor-heading" aria-labelledby="bridging-diacritics"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Bridging diacritics </h3> <p>Bridging diacritics must be centered over the two bases they bridge and must be higher than the tallest.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>table(glyph) base1 = ...; base2 = ...; bridgediac = ...; endtable; // glyph table(positioning) bridgediac {shift.y = max(@B1.boundingbox.top, @B2.boundingbox.top) - @D.boundingbox.bottom + 100m ; // gap of 100m shift.x = (@B2.boundingbox.width - @B1.boundingbox.width)/2} / base1=B1 _=D base2=B2; endtable; // positioning If the base glyphs have other diacritics attached, using @B1.boundingbox.top.1 will give the bounding box of the base plus diacritics. </code></pre></div></div> <h2 id="ligatures-conjuncts"> <a href="#ligatures-conjuncts" class="anchor-heading" aria-labelledby="ligatures-conjuncts"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Ligatures (conjuncts) </h2> <p>Ligatures or conjuncts occur when multiple characters combine to form a single glyph shape.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>table(glyph) char1 = ...; char2 = ...; ligature = ...; endtable; // glyph table(substitution) char1 char2 > ligature:(1 2) _ ; endtable; // substitution </code></pre></div></div> <h3 id="ligatures-with-components"> <a href="#ligatures-with-components" class="anchor-heading" aria-labelledby="ligatures-with-components"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Ligatures with components </h3> <p>Ligature components correspond to sub-regions of the ligature glyph that visually correspond to the original characters. Selecting and manipulating the visual components allows manipulating the underlying characters.</p> <blockquote class="blue-note"> <p><strong>Note</strong></p> <p>This feature is only supported by the original Graphite engine; it is not supported by Graphite2.</p> </blockquote> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>table(glyph) char1 = ...; char2 = ...; ligature = ... // <-- specify which glyph // Define the visual components of the conjunct. // This conjunct has three components: // the top-left, the bottom-left, and the right side. { component {cTL= box(0, bb.height/2, aw/2, bb.top); cBL= box(0, bb.bottom, aw/2, bb.height/2); cR = box(aw/2, bb.bottom, aw, bb.top) } }; endtable; // glyph table(substitution) char1 char2 char3 > ligature:(1 2 3) {component {cTL.ref=@1; cBL.ref=@2; cR=@3}} _ _; endtable; // substitution </code></pre></div></div> <h2 id="contextual-shaping"> <a href="#contextual-shaping" class="anchor-heading" aria-labelledby="contextual-shaping"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Contextual shaping </h2> <p>Many scripts have characters that must use alternate forms depending on neighboring letters.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>table(glyph) // Define the glyphs and classes: matraI = ...; matraI_wide = ...; matraI_wider = ...; matraI_widest = ...; class_wide = ...; class_wider = ...; class_widest = ...; endtable; // glyph table(substitution) // Choose the width of the matra-I that matches the width of the neighboring letter: matraI class_wide > matraI_wide @2; matraI class_wider > matraI_wider @2; matraI class_widest > matraI_widest @2; endtable; </code></pre></div></div> <h3 id="word-contextual-shaping"> <a href="#word-contextual-shaping" class="anchor-heading" aria-labelledby="word-contextual-shaping"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Word-contextual shaping </h3> <p>Arabic is an example of a script whose characters take on alternate forms depending on their location within the word: initial, medial, final, isolate.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>table(glyph) // All characters are initially isolate forms. // Define the individual glyphs: beh = ...; behInit = ...; // etc. // Elements of these four classes must correspond: class_isolate = (beh, teh, theh, peh, teheh, ...); class_initial = (behInit, tehInit, thehInit, pehInit, tehehInit, ...); class_medial = (behMed, behMed, thehMed, pehMed, tehehMed, ...); class_final = (behFin, behFin, thehFin, pehFin, tehehFin, ...); endtable; // glyph table(substitution) // For any contiguous pair of word-forming letters: // turn the first from isolate to initial, or from final to medial // turn the second to final // back up and treat the second as the first of the next pair to consider // Any unprocessed letters are left as isolates. (class_isolate class_final) (class_isolate) > (class_initial class_medial) (class_final) / _ ^ _; endtable; // substitution </code></pre></div></div> <h2 id="reordering"> <a href="#reordering" class="anchor-heading" aria-labelledby="reordering"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Reordering </h2> <p>Many scripts of south and southeast Asia have characters that are rendered in an order that is different from their order in the data.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>table(glyph) // Define the glyphs or classes: consonants = ...; vowelLeftSide = ...; endtable; // glyph table(substitution) consonant vowelLeftSide > @2 @1; endtable; // substitution </code></pre></div></div> <h2 id="splitting"> <a href="#splitting" class="anchor-heading" aria-labelledby="splitting"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Splitting </h2> <p>Many scripts of south and southeast Asia have characters that are rendered by two or more non-contiguous glyphs.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>table(glyph) // Define the glyphs or classes: consonants = ...; // If these are classes, the elements of the classes must correspond: vowelSplit = (vowel1, vowel2, vowel3, ...); vowelLeftHalf = (vowel1Left, vowel2Left, vowel3Left, ...); vowelRightHalf = (vowel1Right, vowel2Right, vowel3Right, ...); endtable; // glyph table(substitution) _ consonant vowelSplit > vowelLeftHalf$3:3 @2 vowelRightHalf:3; end-table; // substitution </code></pre></div></div> <h2 id="font-features-variations"> <a href="#font-features-variations" class="anchor-heading" aria-labelledby="font-features-variations"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Font features (variations) </h2> <p>Font features provide a way to define alterative renderings that can be selected by the user.</p> <h3 id="boolean-feature"> <a href="#boolean-feature" class="anchor-heading" aria-labelledby="boolean-feature"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Boolean feature </h3> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>table(feature) altk { id = "altk"; // can be integer or 4-char string name.1033 = string("Alternate K"); // 1033 = LG_USENG, US English default = 0; settings { off { value = 0; name.1033 = string("False"); } on { value = 1; name.1033 = string("True"); } } }; endtable; // feature table(glyph) g_k = ...; g_k_alt = ...; endtable; // glyph table(substitution) if (altk) g_k > g_k_alt endif; endtable; // substitution </code></pre></div></div> <h3 id="multi-valued-feature"> <a href="#multi-valued-feature" class="anchor-heading" aria-labelledby="multi-valued-feature"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Multi-valued feature </h3> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>table(feature) altk { id = "altk"; // can be integer or 4-char string name.1033 = string("Alternate K"); // 1033 = LG_USENG, US English default = 0; settings { form1 { value = 0; name.1033 = string("Form 1"); } form2 { value = 1; name.1033 = string("Form 2"); } form3 { value = 2; name.1033 = string("Form 3"); } form4 { value = 3; name.1033 = string("Form 4"); } } }; endtable; // feature table(glyph) g_k = ...; g_k1 = ...; g_k2 = ...; g_k3 = ...; g_k4 = ...; endtable; // glyph table(substitution) // Note that for mutually exclusive conditions, successive // 'if' statements are more efficient than 'elseif'. if (altk == form1) g_k > g_k1; endif; if (altk == form2) g_k > g_k2; endif; if (altk == form3) g_k > g_k3; endif; if (altk == form4) g_k > g_k3; endif; endtable; // substitution </code></pre></div></div> </main> <hr> <footer> <p class="text-small text-grey-dk-100 mb-0">Copyright © 2012-2023 SIL International and released under the <a href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 license (CC-BY-SA)</a> unless noted otherwise.</p> </footer> </div> </div> <div class="search-overlay"></div> </div> </body> </html>