[gtk+/wip/matthiasc/font-variations: 44/62] Add a font variations demo



commit 8a4d53e7048df3f8030d63e405a4d97ea17f4e75
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Dec 19 12:04:37 2017 -0500

    Add a font variations demo
    
    Expand the font features demo to show off font variations.

 demos/gtk-demo/demo.gresource.xml |    2 +
 demos/gtk-demo/font-features.ui   | 1524 ++-----------------------------------
 demos/gtk-demo/font_features.c    | 1242 +++++++++++++++++++++++++++++--
 demos/gtk-demo/fontplane.c        |  315 ++++++++
 demos/gtk-demo/fontplane.h        |   65 ++
 demos/gtk-demo/meson.build        |    2 +-
 demos/gtk-demo/open-type-layout.h |  155 ++++
 7 files changed, 1789 insertions(+), 1516 deletions(-)
---
diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml
index 4539b40..2d69cda 100644
--- a/demos/gtk-demo/demo.gresource.xml
+++ b/demos/gtk-demo/demo.gresource.xml
@@ -163,6 +163,7 @@
     <file>flowbox.c</file>
     <file>foreigndrawing.c</file>
     <file>font_features.c</file>
+    <file>fontplane.c</file>
     <file>gestures.c</file>
     <file>glarea.c</file>
     <file>headerbar.c</file>
@@ -224,6 +225,7 @@
   </gresource>
   <gresource prefix="/font_features">
     <file>font-features.ui</file>
+    <file>fontplane.c</file>
   </gresource>
   <gresource prefix="/spinbutton">
     <file>spinbutton.ui</file>
diff --git a/demos/gtk-demo/font-features.ui b/demos/gtk-demo/font-features.ui
index aae2615..bae29dc 100644
--- a/demos/gtk-demo/font-features.ui
+++ b/demos/gtk-demo/font-features.ui
@@ -9,18 +9,18 @@
       <object class="GtkHeaderBar">
         <property name="visible">1</property>
         <property name="show-title-buttons">1</property>
-        <property name="title">Font Features</property>
+        <property name="title">Font Explorer</property>
         <child>
           <object class="GtkButton" id="reset">
             <property name="visible">1</property>
-            <property name="can_focus">1</property>
-            <property name="receives_default">1</property>
+            <property name="can-focus">1</property>
+            <property name="receives-default">1</property>
             <property name="tooltip-text">Reset</property>
             <signal name="clicked" handler="reset" swapped="no"/>
             <child>
               <object class="GtkImage">
                 <property name="visible">1</property>
-                <property name="icon_name">view-refresh-symbolic</property>
+                <property name="icon-name">view-refresh-symbolic</property>
               </object>
             </child>
           </object>
@@ -33,8 +33,8 @@
         <child>
           <object class="GtkScrolledWindow">
             <property name="visible">1</property>
-            <property name="can_focus">1</property>
-            <property name="hscrollbar_policy">never</property>
+            <property name="can-focus">1</property>
+            <property name="hscrollbar-policy">never</property>
             <child>
               <object class="GtkViewport">
                 <property name="visible">1</property>
@@ -47,16 +47,24 @@
                     <child>
                       <object class="GtkFontButton" id="font">
                         <property name="visible">1</property>
-                        <property name="can_focus">1</property>
-                        <property name="receives_default">1</property>
+                        <property name="can-focus">1</property>
+                        <property name="receives-default">1</property>
                         <property name="font">Sans 12</property>
                         <signal name="font-set" handler="font_changed" swapped="no"/>
                       </object>
                     </child>
                     <child>
+                      <object class="GtkLabel">
+                        <property name="label" translatable="yes">Script &amp; Language</property>
+                        <property name="xalign">0</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                    </child>
+                    <child>
                       <object class="GtkComboBox" id="script_lang">
-                        <property name="visible">1</property>
-                        <property name="can_focus">1</property>
+                        <property name="can-focus">1</property>
                         <signal name="changed" handler="script_changed" swapped="no"/>
                         <child>
                           <object class="GtkCellRendererText"/>
@@ -68,197 +76,19 @@
                     </child>
                     <child>
                       <object class="GtkExpander">
-                        <property name="visible">1</property>
-                        <property name="can_focus">1</property>
-                        <child>
-                          <object class="GtkBox">
-                            <property name="visible">1</property>
-                            <property name="margin_start">10</property>
-                            <property name="margin_end">10</property>
-                            <property name="margin_top">10</property>
-                            <property name="orientation">vertical</property>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="kern_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="kern_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="kern">
-                                    <property name="label" translatable="yes">Enabled</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="kern_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
                         <child type="label">
                           <object class="GtkLabel">
                             <property name="visible">1</property>
-                            <property name="label" translatable="yes">Kerning</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Font Features</property>
+                            <attributes>
+                              <attribute name="weight" value="bold"/>
+                            </attributes>
                           </object>
                         </child>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkExpander">
-                        <property name="visible">1</property>
-                        <property name="can_focus">1</property>
                         <child>
-                          <object class="GtkBox">
-                            <property name="visible">1</property>
-                            <property name="margin_start">10</property>
-                            <property name="margin_end">10</property>
-                            <property name="margin_top">10</property>
+                          <object class="GtkBox" id="feature_list">
                             <property name="orientation">vertical</property>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="liga_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="liga_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="liga">
-                                    <property name="label" translatable="yes">Common Ligatures</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="liga_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="dlig_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="dlig_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="dlig">
-                                    <property name="label" translatable="yes">Discretionary 
Ligatures</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="dlig_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="hlig_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="hlig_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="hlig">
-                                    <property name="label" translatable="yes">Historical Ligatures</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="hlig_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="clig_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="clig_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="clig">
-                                    <property name="label" translatable="yes">Contextual Ligatures</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="clig_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                        <child type="label">
-                          <object class="GtkLabel">
-                            <property name="visible">1</property>
-                            <property name="label" translatable="yes">Ligatures</property>
                           </object>
                         </child>
                       </object>
@@ -266,1273 +96,21 @@
                     <child>
                       <object class="GtkExpander">
                         <property name="visible">1</property>
-                        <property name="can_focus">1</property>
-                        <child>
-                          <object class="GtkBox">
-                            <property name="visible">1</property>
-                            <property name="margin_start">10</property>
-                            <property name="margin_end">10</property>
-                            <property name="margin_top">10</property>
-                            <property name="orientation">vertical</property>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="smcp_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="smcp_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="smcp">
-                                    <property name="label" translatable="yes">Small Caps</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="valign">baseline</property>
-                                    <property name="sensitive" bind-source="smcp_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="c2sc_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="c2sc_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="c2sc">
-                                    <property name="label" translatable="yes">Small Caps from Caps</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="c2sc_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="pcap_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="pcap_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="pcap">
-                                    <property name="label" translatable="yes">Petite Caps</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="pcap_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="c2pc_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="c2pc_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="c2pc">
-                                    <property name="label" translatable="yes">Caps to Petite Caps</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="c2pc_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="unic_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="unic_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="unic">
-                                    <property name="label" translatable="yes">Unicase</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="unic_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="cpsp_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="cpsp_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="cpsp">
-                                    <property name="label" translatable="yes">Capital Spacing</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="cpsp_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="case_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="case_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="case">
-                                    <property name="label" translatable="yes">Case-sensitive Forms</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="case_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
                         <child type="label">
-                          <object class="GtkLabel">
+                          <object class="GtkLabel" id="variations_heading">
                             <property name="visible">1</property>
-                            <property name="label" translatable="yes">Letter Case</property>
+                            <property name="label" translatable="yes">Font Variations</property>
+                            <property name="xalign">0</property>
+                            <attributes>
+                              <attribute name="weight" value="bold"/>
+                            </attributes>
                           </object>
                         </child>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkExpander">
-                        <property name="visible">1</property>
-                        <property name="can_focus">1</property>
                         <child>
-                          <object class="GtkBox">
+                          <object class="GtkGrid" id="variations_grid">
                             <property name="visible">1</property>
-                            <property name="margin_start">10</property>
-                            <property name="margin_end">10</property>
-                            <property name="margin_top">10</property>
-                            <property name="orientation">vertical</property>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="numcasedefault_pres">
-                                    <property name="visible">1</property>
-                                    <property name="opacity">0</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkRadioButton" id="numcasedefault">
-                                    <property name="label" translatable="yes">Default</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="active">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="lnum_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkRadioButton" id="lnum">
-                                    <property name="label" translatable="yes">Lining</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="active">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <property name="group">numcasedefault</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="onum_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkRadioButton" id="onum">
-                                    <property name="label" translatable="yes">Old-Style</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="active">1</property>
-                                    <property name="valign">baseline</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="group">numcasedefault</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                        <child type="label">
-                          <object class="GtkLabel">
-                            <property name="visible">1</property>
-                            <property name="label" translatable="yes">Number Case</property>
-                          </object>
-                        </child>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkExpander">
-                        <property name="visible">1</property>
-                        <property name="can_focus">1</property>
-                        <child>
-                          <object class="GtkBox">
-                            <property name="visible">1</property>
-                            <property name="margin_start">10</property>
-                            <property name="margin_end">10</property>
-                            <property name="margin_top">10</property>
-                            <property name="orientation">vertical</property>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="numspacedefault_pres">
-                                    <property name="visible">1</property>
-                                    <property name="opacity">0</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkRadioButton" id="numspacedefault">
-                                    <property name="label" translatable="yes">Default</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="active">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="pnum_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkRadioButton" id="pnum">
-                                    <property name="label" translatable="yes">Proportional</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="active">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="group">numspacedefault</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="tnum_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkRadioButton" id="tnum">
-                                    <property name="label" translatable="yes">Tabular</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="active">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="group">numspacedefault</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                        <child type="label">
-                          <object class="GtkLabel">
-                            <property name="visible">1</property>
-                            <property name="label" translatable="yes">Number Spacing</property>
-                          </object>
-                        </child>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkExpander">
-                        <property name="visible">1</property>
-                        <property name="can_focus">1</property>
-                        <child>
-                          <object class="GtkBox">
-                            <property name="visible">1</property>
-                            <property name="margin_start">10</property>
-                            <property name="margin_end">10</property>
-                            <property name="margin_top">10</property>
-                            <property name="orientation">vertical</property>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="fractiondefault_pres">
-                                    <property name="visible">1</property>
-                                    <property name="opacity">0</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkRadioButton" id="fractiondefault">
-                                    <property name="label" translatable="yes">Off</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="active">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="frac_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkRadioButton" id="frac">
-                                    <property name="label" translatable="yes">Normal</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="active">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="group">fractiondefault</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="afrc_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkRadioButton" id="afrc">
-                                    <property name="label" translatable="yes">Alternate</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="active">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="group">fractiondefault</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                        <child type="label">
-                          <object class="GtkLabel">
-                            <property name="visible">1</property>
-                            <property name="label" translatable="yes">Fractions</property>
-                          </object>
-                        </child>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkExpander">
-                        <property name="visible">1</property>
-                        <property name="can_focus">1</property>
-                        <child>
-                          <object class="GtkBox">
-                            <property name="visible">1</property>
-                            <property name="margin_start">10</property>
-                            <property name="margin_end">10</property>
-                            <property name="margin_top">10</property>
-                            <property name="orientation">vertical</property>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="zero_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="zero_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="zero">
-                                    <property name="label" translatable="yes">Slashed Zero</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="zero_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="nalt_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="nalt_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="nalt">
-                                    <property name="label" translatable="yes">Alternative 
Annotations</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="nalt_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="sinf_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="sinf_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="sinf">
-                                    <property name="label" translatable="yes">Scientific Inferiors</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="sinf_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                        <child type="label">
-                          <object class="GtkLabel">
-                            <property name="visible">1</property>
-                            <property name="label" translatable="yes">Numeric Extras</property>
-                          </object>
-                        </child>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkExpander">
-                        <property name="visible">1</property>
-                        <property name="can_focus">1</property>
-                        <child>
-                          <object class="GtkBox">
-                            <property name="visible">1</property>
-                            <property name="margin_start">10</property>
-                            <property name="margin_end">10</property>
-                            <property name="margin_top">10</property>
-                            <property name="orientation">vertical</property>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="swsh_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="swsh_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="swsh">
-                                    <property name="label" translatable="yes">Swash Glyphs</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="swsh_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="cswh_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="cswh_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="cswh">
-                                    <property name="label" translatable="yes">Contextual Swash</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="cswh_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="locl_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="locl_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="locl">
-                                    <property name="label" translatable="yes">Localized Forms</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="locl_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="calt_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="calt_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="calt">
-                                    <property name="label" translatable="yes">Contextual 
Alternatives</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="calt_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="hist_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="hist_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="hist">
-                                    <property name="label" translatable="yes">Historical 
Alternatives</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="hist_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="salt_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="salt_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="salt">
-                                    <property name="label" translatable="yes">Stylistic 
Alternatives</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="salt_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="titl_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="titl_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="titl">
-                                    <property name="label" translatable="yes">Titling Alternatives</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="titl_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="rand_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="rand_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="rand">
-                                    <property name="label" translatable="yes">Randomize</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="rand_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="subs_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="subs_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="subs">
-                                    <property name="label" translatable="yes">Subscript</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="subs_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="sups_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="sups_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="sups">
-                                    <property name="label" translatable="yes">Superscript</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="sups_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                        <child type="label">
-                          <object class="GtkLabel">
-                            <property name="visible">1</property>
-                            <property name="label" translatable="yes">Character Alternatives</property>
-                          </object>
-                        </child>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkExpander">
-                        <property name="visible">1</property>
-                        <property name="can_focus">1</property>
-                        <child>
-                          <object class="GtkBox">
-                            <property name="visible">1</property>
-                            <property name="margin_start">10</property>
-                            <property name="margin_end">10</property>
-                            <property name="margin_top">10</property>
-                            <property name="orientation">vertical</property>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="init_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="init_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="init">
-                                    <property name="label" translatable="yes">Initial Forms</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="init_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="medi_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="medi_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="medi">
-                                    <property name="label" translatable="yes">Medial Forms</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="medi_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="fina_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="fina_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="fina">
-                                    <property name="label" translatable="yes">Final Forms</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="fina_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="isol_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="isol_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="isol">
-                                    <property name="label" translatable="yes">Isolated Forms</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="isol_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                        <child type="label">
-                          <object class="GtkLabel">
-                            <property name="visible">1</property>
-                            <property name="label" translatable="yes">Positional Alternatives</property>
-                          </object>
-                        </child>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkExpander">
-                        <property name="visible">1</property>
-                        <property name="can_focus">1</property>
-                        <child>
-                          <object class="GtkBox">
-                            <property name="visible">1</property>
-                            <property name="margin_start">10</property>
-                            <property name="margin_end">10</property>
-                            <property name="margin_top">10</property>
-                            <property name="orientation">vertical</property>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="ss01_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="ss01_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="ss01">
-                                    <property name="label" translatable="yes">Set 1</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="ss01_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="ss02_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="ss02_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="ss02">
-                                    <property name="label" translatable="yes">Set 2</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="ss02_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="ss03_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="ss03_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="ss03">
-                                    <property name="label" translatable="yes">Set 3</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="ss03_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="ss04_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="ss04_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="ss04">
-                                    <property name="label" translatable="yes">Set 4</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="ss04_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">1</property>
-                                <child>
-                                  <object class="GtkImage" id="ss05_pres">
-                                    <property name="visible">1</property>
-                                    <property name="icon-name">object-select-symbolic</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="ss05_dflt">
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="ss05">
-                                    <property name="label" translatable="yes">Set 5</property>
-                                    <property name="visible">1</property>
-                                    <property name="can_focus">1</property>
-                                    <property name="draw_indicator">1</property>
-                                    <property name="valign">baseline</property>
-                                    <signal name="notify::active" handler="update_display" swapped="no"/>
-                                    <property name="sensitive" bind-source="ss05_dflt" 
bind-property="active" bind-flags="sync-create|bidirectional"/>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                        <child type="label">
-                          <object class="GtkLabel">
-                            <property name="visible">1</property>
-                            <property name="label" translatable="yes">Alternative Stylistic Sets</property>
+                            <property name="column-spacing">10</property>
+                            <property name="row-spacing">10</property>
                           </object>
                         </child>
                       </object>
@@ -1553,10 +131,10 @@
             <child>
               <object class="GtkStack" id="stack">
                 <property name="visible">1</property>
-                <property name="margin_start">20</property>
-                <property name="margin_end">20</property>
-                <property name="margin_top">20</property>
-                <property name="margin_bottom">20</property>
+                <property name="margin-start">20</property>
+                <property name="margin-end">20</property>
+                <property name="margin-top">20</property>
+                <property name="margin-bottom">20</property>
                 <child>
                   <object class="GtkLabel" id="label">
                     <property name="visible">1</property>
@@ -1592,15 +170,37 @@
             <child>
               <object class="GtkLabel" id="settings">
                 <property name="visible">1</property>
-                <property name="margin_start">20</property>
-                <property name="margin_end">20</property>
-                <property name="margin_bottom">20</property>
+                <property name="wrap">1</property>
+                <property name="margin-start">20</property>
+                <property name="margin-end">20</property>
+                <property name="margin-bottom">20</property>
                 <property name="xalign">0</property>
                 <property name="valign">end</property>
                 <property name="width-chars">50</property>
                 <property name="max-width-chars">50</property>
                 <property name="hexpand">1</property>
                 <property name="vexpand">1</property>
+                <style>
+                  <class name="monospace"/>
+                </style>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel" id="description">
+                <property name="visible">1</property>
+                <property name="wrap">1</property>
+                <property name="margin-start">20</property>
+                <property name="margin-end">20</property>
+                <property name="margin-bottom">20</property>
+                <property name="xalign">0</property>
+                <property name="valign">end</property>
+                <property name="width-chars">50</property>
+                <property name="max-width-chars">50</property>
+                <property name="hexpand">1</property>
+                <property name="vexpand">0</property>
+                <style>
+                  <class name="monospace"/>
+                </style>
               </object>
             </child>
             <property name="hexpand">1</property>
diff --git a/demos/gtk-demo/font_features.c b/demos/gtk-demo/font_features.c
index b75508f..42985f2 100644
--- a/demos/gtk-demo/font_features.c
+++ b/demos/gtk-demo/font_features.c
@@ -1,4 +1,4 @@
-/* Pango/Font Features
+/* Pango/Font Explorer
  *
  * This example demonstrates support for OpenType font features with
  * Pango attributes. The attributes can be used manually or via Pango
@@ -6,6 +6,9 @@
  *
  * It can also be used to explore available features in OpenType fonts
  * and their effect.
+ *
+ * If the selected font supports OpenType font variations, then the
+ * axes are also offered for customization.
  */
 
 #include <gtk/gtk.h>
@@ -13,28 +16,179 @@
 #include <hb.h>
 #include <hb-ot.h>
 #include <hb-ft.h>
+#include <freetype/ftmm.h>
+#include <freetype/ftsnames.h>
+#include <freetype/ttnameid.h>
+#include <glib/gi18n.h>
+
+#include "open-type-layout.h"
+#include "fontplane.h"
+
+
+#define MAKE_TAG(a,b,c,d) (unsigned int)(((a) << 24) | ((b) << 16) | ((c) <<  8) | (d))
 
 static GtkWidget *label;
 static GtkWidget *settings;
+static GtkWidget *description;
 static GtkWidget *font;
 static GtkWidget *script_lang;
 static GtkWidget *resetbutton;
-static GtkWidget *numcasedefault;
-static GtkWidget *numspacedefault;
-static GtkWidget *fractiondefault;
 static GtkWidget *stack;
 static GtkWidget *entry;
+static GtkWidget *variations_heading;
+static GtkWidget *variations_grid;
+static GtkWidget *instance_combo;
 
-#define num_features 40
+typedef struct {
+  unsigned int tag;
+  const char *name;
+  GtkWidget *icon;
+  GtkWidget *dflt;
+  GtkWidget *feat;
+} FeatureItem;
 
-static GtkWidget *toggle[num_features];
-static GtkWidget *icon[num_features];
-static const char *feature_names[num_features] = {
-  "kern", "liga", "dlig", "hlig", "clig", "smcp", "c2sc", "pcap", "c2pc", "unic",
-  "cpsp", "case", "lnum", "onum", "pnum", "tnum", "frac", "afrc", "zero", "nalt",
-  "sinf", "swsh", "cswh", "locl", "calt", "hist", "salt", "titl", "rand", "subs",
-  "sups", "init", "medi", "fina", "isol", "ss01", "ss02", "ss03", "ss04", "ss05"
-};
+static GList *feature_items;
+
+static void add_font_variations (GString *s);
+
+static const char *
+get_feature_display_name (unsigned int tag)
+{
+  int i;
+
+  for (i = 0; i < G_N_ELEMENTS (open_type_layout_features); i++)
+    {
+      if (tag == open_type_layout_features[i].tag)
+        return g_dpgettext2 (NULL, "OpenType layout", open_type_layout_features[i].name);
+    }
+
+  return NULL;
+}
+
+static void update_display (void);
+
+static void
+add_check_group (GtkWidget   *box,
+                 const char  *title,
+                 const char **tags)
+{
+  GtkWidget *label;
+  GtkWidget *group;
+  int i;
+
+  label = gtk_label_new (title);
+  gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+  gtk_widget_set_halign (label, GTK_ALIGN_START);
+  g_object_set (label, "margin-top", 10, NULL);
+  gtk_container_add (GTK_CONTAINER (box), label);
+
+  group = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+  gtk_widget_set_halign (group, GTK_ALIGN_START);
+  g_object_set (group,
+                "margin-start", 20,
+                "margin-end", 20,
+                "margin-top", 10,
+                "margin-top", 10,
+                NULL);
+  for (i = 0; tags[i]; i++)
+    {
+      unsigned int tag;
+      GtkWidget *row;
+      GtkWidget *icon;
+      GtkWidget *dflt;
+      GtkWidget *feat;
+      FeatureItem *item;
+
+      tag = hb_tag_from_string (tags[i], -1);
+
+      row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+      icon = gtk_image_new_from_icon_name ("object-select-symbolic");
+      dflt = gtk_check_button_new ();
+      feat = gtk_check_button_new_with_label (get_feature_display_name (tag));
+
+      g_signal_connect (feat, "notify::active", G_CALLBACK (update_display), NULL);
+      g_object_bind_property (dflt, "active", feat, "sensitive", G_BINDING_SYNC_CREATE | 
G_BINDING_BIDIRECTIONAL);
+      g_signal_connect (dflt, "notify::active", G_CALLBACK (update_display), NULL);
+
+      gtk_container_add (GTK_CONTAINER (row), icon);
+      gtk_container_add (GTK_CONTAINER (row), dflt);
+      gtk_container_add (GTK_CONTAINER (row), feat);
+      gtk_container_add (GTK_CONTAINER (group), row);
+
+      item = g_new (FeatureItem, 1);
+      item->name = tags[i];
+      item->tag = tag;
+      item->icon = icon;
+      item->dflt = dflt;
+      item->feat = feat;
+
+      feature_items = g_list_prepend (feature_items, item);
+    }
+
+  gtk_container_add (GTK_CONTAINER (box), group);
+}
+
+static void
+add_radio_group (GtkWidget *box,
+                 const char  *title,
+                 const char **tags)
+{
+  GtkWidget *label;
+  GtkWidget *group;
+  int i;
+  GtkWidget *group_button = NULL;
+
+  label = gtk_label_new (title);
+  gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+  gtk_widget_set_halign (label, GTK_ALIGN_START);
+  g_object_set (label, "margin-top", 10, NULL);
+  gtk_container_add (GTK_CONTAINER (box), label);
+
+  group = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+  gtk_widget_set_halign (group, GTK_ALIGN_START);
+  g_object_set (group,
+                "margin-start", 20,
+                "margin-end", 20,
+                "margin-top", 10,
+                "margin-top", 10,
+                NULL);
+  for (i = 0; tags[i]; i++)
+    {
+      unsigned int tag;
+      GtkWidget *row;
+      GtkWidget *icon;
+      GtkWidget *feat;
+      FeatureItem *item;
+      const char *name;
+
+      tag = hb_tag_from_string (tags[i], -1);
+      name = get_feature_display_name (tag);
+
+      row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+      icon = gtk_image_new_from_icon_name ("object-select-symbolic");
+      feat = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (group_button),
+                                                          name ? name : _("Default"));
+      if (group_button == NULL)
+        group_button = feat;
+
+      g_signal_connect (feat, "notify::active", G_CALLBACK (update_display), NULL);
+
+      gtk_container_add (GTK_CONTAINER (row), icon);
+      gtk_container_add (GTK_CONTAINER (row), feat);
+      gtk_container_add (GTK_CONTAINER (group), row);
+
+      item = g_new (FeatureItem, 1);
+      item->name = tags[i];
+      item->tag = tag;
+      item->icon = icon;
+      item->dflt = NULL;
+      item->feat = feat;
+
+      feature_items = g_list_prepend (feature_items, item);
+    }
+
+  gtk_container_add (GTK_CONTAINER (box), group);
+}
 
 static void
 update_display (void)
@@ -44,41 +198,58 @@ update_display (void)
   char *font_settings;
   const char *text;
   gboolean has_feature;
-  int i;
   hb_tag_t lang_tag;
   GtkTreeModel *model;
   GtkTreeIter iter;
   const char *lang;
+  PangoFontDescription *desc;
+  char *tmp;
+  GList *l;
 
   text = gtk_entry_get_text (GTK_ENTRY (entry));
 
-  font_desc = gtk_font_chooser_get_font (GTK_FONT_CHOOSER (font));
+  desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (font));
+  pango_font_description_unset_fields (desc, PANGO_FONT_MASK_VARIATIONS);
+  tmp = pango_font_description_to_string (desc);
+
+  s = g_string_new (tmp);
+
+  g_free (tmp);
+  pango_font_description_free (desc);
+
+  add_font_variations (s);
+  font_desc = g_string_free (s, FALSE);
+
+  gtk_label_set_text (GTK_LABEL (description), font_desc);
 
   s = g_string_new ("");
 
   has_feature = FALSE;
-  for (i = 0; i < num_features; i++)
+  for (l = feature_items; l; l = l->next)
     {
-      if (!gtk_widget_is_sensitive (toggle[i]))
+      FeatureItem *item = l->data;
+
+      if (!gtk_widget_is_sensitive (item->feat))
         continue;
 
-      if (GTK_IS_RADIO_BUTTON (toggle[i]))
+      if (GTK_IS_RADIO_BUTTON (item->feat))
         {
-          if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle[i])))
+          if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (item->feat)) &&
+              strcmp (item->name, "xxxx") != 0)
             {
               if (has_feature)
                 g_string_append (s, ", ");
-              g_string_append (s, gtk_buildable_get_name (GTK_BUILDABLE (toggle[i])));
+              g_string_append (s, item->name);
               g_string_append (s, " 1");
               has_feature = TRUE;
             }
         }
-      else
+      else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (item->dflt)))
         {
           if (has_feature)
             g_string_append (s, ", ");
-          g_string_append (s, gtk_buildable_get_name (GTK_BUILDABLE (toggle[i])));
-          if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle[i])))
+          g_string_append (s, item->name);
+          if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (item->feat)))
             g_string_append (s, " 1");
           else
             g_string_append (s, " 0");
@@ -90,7 +261,6 @@ update_display (void)
 
   gtk_label_set_text (GTK_LABEL (settings), font_settings);
 
-
   if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (script_lang), &iter))
     {
       model = gtk_combo_box_get_model (GTK_COMBO_BOX (script_lang));
@@ -122,13 +292,11 @@ get_pango_font (void)
 {
   PangoFontDescription *desc;
   PangoContext *context;
-  PangoFontMap *map;
 
   desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (font));
   context = gtk_widget_get_pango_context (font);
-  map = pango_context_get_font_map (context);
 
-  return pango_font_map_load_font (map, context, desc);
+  return pango_context_load_font (context, desc);
 }
 
 static struct { const char *name; hb_script_t script; } script_names[] = {
@@ -341,16 +509,20 @@ update_script_combo (void)
 static void
 update_features (void)
 {
-  gint i, j, k;
+  gint i, j;
   GtkTreeModel *model;
   GtkTreeIter iter;
   guint script_index, lang_index;
   PangoFont *pango_font;
   FT_Face ft_face;
   hb_font_t *hb_font;
+  GList *l;
 
-  for (i = 0; i < num_features; i++)
-    gtk_widget_set_opacity (icon[i], 0);
+  for (l = feature_items; l; l = l->next)
+    {
+      FeatureItem *item = l->data;
+      gtk_widget_set_opacity (item->icon, 0);
+    }
 
   /* set feature presence checks from the font features */
 
@@ -389,10 +561,11 @@ update_features (void)
 
           for (j = 0; j < count; j++)
             {
-              for (k = 0; k < num_features; k++)
+              for (l = feature_items; l; l = l->next)
                 {
-                  if (hb_tag_from_string (feature_names[k], -1) == features[j])
-                    gtk_widget_set_opacity (icon[k], 0.5);
+                  FeatureItem *item = l->data;
+                  if (item->tag == features[j])
+                    gtk_widget_set_opacity (item->icon, 0.5);
                 }
             }
         }
@@ -404,10 +577,884 @@ update_features (void)
   g_object_unref (pango_font);
 }
 
+#define FixedToFloat(f) (((float)(f))/65536.0)
+
+static void
+adjustment_changed (GtkAdjustment *adjustment,
+                    GtkEntry      *entry)
+{
+  char *str;
+
+  str = g_strdup_printf ("%g", gtk_adjustment_get_value (adjustment));
+  gtk_entry_set_text (GTK_ENTRY (entry), str);
+  g_free (str);
+
+  update_display ();
+}
+
+static void
+entry_activated (GtkEntry *entry,
+                 GtkAdjustment *adjustment)
+{
+  gdouble value;
+  gchar *err = NULL;
+
+  value = g_strtod (gtk_entry_get_text (entry), &err);
+  if (err != NULL)
+    gtk_adjustment_set_value (adjustment, value);
+}
+
+static void unset_instance (GtkAdjustment *adjustment);
+
+typedef struct {
+  guint32 tag;
+  GtkAdjustment *adjustment;
+} Axis;
+
+static GHashTable *axes;
+
+static void
+add_font_variations (GString *s)
+{
+  GHashTableIter iter;
+  Axis *axis;
+  char buf[G_ASCII_DTOSTR_BUF_SIZE];
+  char *sep = " @";
+
+  g_hash_table_iter_init (&iter, axes);
+  while (g_hash_table_iter_next (&iter, (gpointer *)NULL, (gpointer *)&axis))
+    {
+      char tag[5];
+      double value;
+
+      hb_tag_to_string (axis->tag, tag);
+      tag[4] = '\0';
+      value = gtk_adjustment_get_value (axis->adjustment);
+
+      g_string_append_printf (s, "%s%s=%s", sep, tag, g_ascii_dtostr (buf, sizeof (buf), value));
+      sep = ",";
+    }
+}
+
+static guint
+axes_hash (gconstpointer v)
+{
+  const Axis *p = v;
+
+  return p->tag;
+}
+
+static gboolean
+axes_equal (gconstpointer v1, gconstpointer v2)
+{
+  const Axis *p1 = v1;
+  const Axis *p2 = v2;
+
+  return p1->tag == p2->tag;
+}
+
+static void
+add_axis (FT_Var_Axis *ax, FT_Fixed value, int i)
+{
+  GtkWidget *axis_label;
+  GtkWidget *axis_entry;
+  GtkWidget *axis_scale;
+  GtkAdjustment *adjustment;
+  Axis *axis;
+
+  axis_label = gtk_label_new (ax->name);
+  gtk_widget_set_halign (axis_label, GTK_ALIGN_START);
+  gtk_widget_set_valign (axis_label, GTK_ALIGN_BASELINE);
+  gtk_grid_attach (GTK_GRID (variations_grid), axis_label, 0, i, 1, 1);
+  adjustment = gtk_adjustment_new ((double)FixedToFloat(value),
+                                   (double)FixedToFloat(ax->minimum),
+                                   (double)FixedToFloat(ax->maximum),
+                                   1.0, 10.0, 0.0);
+  axis_scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
+  gtk_scale_add_mark (GTK_SCALE (axis_scale), (double)FixedToFloat(ax->def), GTK_POS_TOP, NULL);
+  gtk_widget_set_valign (axis_scale, GTK_ALIGN_BASELINE);
+  gtk_widget_set_hexpand (axis_scale, TRUE);
+  gtk_widget_set_size_request (axis_scale, 100, -1);
+  gtk_scale_set_draw_value (GTK_SCALE (axis_scale), FALSE);
+  gtk_grid_attach (GTK_GRID (variations_grid), axis_scale, 1, i, 1, 1);
+  axis_entry = gtk_entry_new ();
+  gtk_widget_set_valign (axis_entry, GTK_ALIGN_BASELINE);
+  gtk_entry_set_width_chars (GTK_ENTRY (axis_entry), 4);
+  gtk_grid_attach (GTK_GRID (variations_grid), axis_entry, 2, i, 1, 1);
+
+  axis = g_new (Axis, 1);
+  axis->tag = ax->tag;
+  axis->adjustment = adjustment;
+  g_hash_table_add (axes, axis);
+
+  adjustment_changed (adjustment, GTK_ENTRY (axis_entry));
+
+  g_signal_connect (adjustment, "value-changed", G_CALLBACK (adjustment_changed), axis_entry);
+  g_signal_connect (adjustment, "value-changed", G_CALLBACK (unset_instance), NULL);
+  g_signal_connect (axis_entry, "activate", G_CALLBACK (entry_activated), adjustment);
+}
+
+typedef struct {
+  char *name;
+  int n_axes;
+  guint32 *axes;
+  float   *coords;
+} Instance;
+
+static guint
+instance_hash (gconstpointer v)
+{
+  const Instance *p = v;
+
+  return g_str_hash (p->name);
+}
+
+static gboolean
+instance_equal (gconstpointer v1, gconstpointer v2)
+{
+  const Instance *p1 = v1;
+  const Instance *p2 = v2;
+
+  return g_str_equal (p1->name, p2->name);
+}
+
+static void
+free_instance (gpointer data)
+{
+  Instance *instance = data;
+
+  g_free (instance->name);
+  g_free (instance->axes);
+  g_free (instance->coords);
+  g_free (instance);
+}
+
+static GHashTable *instances;
+
+typedef struct {
+    const FT_UShort     platform_id;
+    const FT_UShort     encoding_id;
+    const char  fromcode[12];
+} FtEncoding;
+
+#define TT_ENCODING_DONT_CARE   0xffff
+
+static const FtEncoding   ftEncoding[] = {
+ {  TT_PLATFORM_APPLE_UNICODE,  TT_ENCODING_DONT_CARE,  "UTF-16BE" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_ID_ROMAN,        "MACINTOSH" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_ID_JAPANESE,     "SJIS" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_ID_SYMBOL_CS,     "UTF-16BE" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_ID_UNICODE_CS,    "UTF-16BE" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_ID_SJIS,          "SJIS-WIN" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_ID_GB2312,        "GB2312" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_ID_BIG_5,         "BIG-5" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_ID_WANSUNG,       "Wansung" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_ID_JOHAB,         "Johab" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_ID_UCS_4,         "UTF-16BE" },
+ {  TT_PLATFORM_ISO,            TT_ISO_ID_7BIT_ASCII,   "ASCII" },
+ {  TT_PLATFORM_ISO,            TT_ISO_ID_10646,        "UTF-16BE" },
+ {  TT_PLATFORM_ISO,            TT_ISO_ID_8859_1,       "ISO-8859-1" },
+};
+
+typedef struct {
+    const FT_UShort     platform_id;
+    const FT_UShort     language_id;
+    const char  lang[8];
+} FtLanguage;
+
+#define TT_LANGUAGE_DONT_CARE   0xffff
+
+static const FtLanguage   ftLanguage[] = {
+ {  TT_PLATFORM_APPLE_UNICODE,  TT_LANGUAGE_DONT_CARE,              "" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_ENGLISH,              "en" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_FRENCH,               "fr" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_GERMAN,               "de" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_ITALIAN,              "it" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_DUTCH,                "nl" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_SWEDISH,              "sv" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_SPANISH,              "es" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_DANISH,               "da" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_PORTUGUESE,           "pt" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_NORWEGIAN,            "no" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_HEBREW,               "he" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_JAPANESE,             "ja" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_ARABIC,               "ar" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_FINNISH,              "fi" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_GREEK,                "el" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_ICELANDIC,            "is" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_MALTESE,              "mt" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_TURKISH,              "tr" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_CROATIAN,             "hr" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_CHINESE_TRADITIONAL,  "zh-tw" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_URDU,                 "ur" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_HINDI,                "hi" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_THAI,                 "th" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_KOREAN,               "ko" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_LITHUANIAN,           "lt" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_POLISH,               "pl" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_HUNGARIAN,            "hu" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_ESTONIAN,             "et" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_LETTISH,              "lv" },
+/* {  TT_PLATFORM_MACINTOSH,    TT_MAC_LANGID_SAAMISK, ??? */
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_FAEROESE,             "fo" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_FARSI,                "fa" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_RUSSIAN,              "ru" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_CHINESE_SIMPLIFIED,   "zh-cn" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_FLEMISH,              "nl" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_IRISH,                "ga" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_ALBANIAN,             "sq" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_ROMANIAN,             "ro" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_CZECH,                "cs" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_SLOVAK,               "sk" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_SLOVENIAN,            "sl" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_YIDDISH,              "yi" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_SERBIAN,              "sr" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_MACEDONIAN,           "mk" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_BULGARIAN,            "bg" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_UKRAINIAN,            "uk" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_BYELORUSSIAN,         "be" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_UZBEK,                "uz" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_KAZAKH,               "kk" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_AZERBAIJANI,          "az" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT, "az" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT,    "ar" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_ARMENIAN,             "hy" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_GEORGIAN,             "ka" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_MOLDAVIAN,            "mo" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_KIRGHIZ,              "ky" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_TAJIKI,               "tg" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_TURKMEN,              "tk" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_MONGOLIAN,            "mo" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT,"mo" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT, "mo" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_PASHTO,               "ps" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_KURDISH,              "ku" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_KASHMIRI,             "ks" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_SINDHI,               "sd" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_TIBETAN,              "bo" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_NEPALI,               "ne" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_SANSKRIT,             "sa" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_MARATHI,              "mr" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_BENGALI,              "bn" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_ASSAMESE,             "as" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_GUJARATI,             "gu" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_PUNJABI,              "pa" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_ORIYA,                "or" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_MALAYALAM,            "ml" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_KANNADA,              "kn" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_TAMIL,                "ta" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_TELUGU,               "te" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_SINHALESE,            "si" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_BURMESE,              "my" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_KHMER,                "km" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_LAO,                  "lo" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_VIETNAMESE,           "vi" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_INDONESIAN,           "id" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_TAGALOG,              "tl" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_MALAY_ROMAN_SCRIPT,   "ms" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_MALAY_ARABIC_SCRIPT,  "ms" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_AMHARIC,              "am" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_TIGRINYA,             "ti" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_GALLA,                "om" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_SOMALI,               "so" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_SWAHILI,              "sw" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_RUANDA,               "rw" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_RUNDI,                "rn" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_CHEWA,                "ny" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_MALAGASY,             "mg" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_ESPERANTO,            "eo" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_WELSH,                "cy" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_BASQUE,               "eu" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_CATALAN,              "ca" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_LATIN,                "la" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_QUECHUA,              "qu" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_GUARANI,              "gn" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_AYMARA,               "ay" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_TATAR,                "tt" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_UIGHUR,               "ug" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_DZONGKHA,             "dz" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_JAVANESE,             "jw" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_SUNDANESE,            "su" },
+
+#if 0  /* these seem to be errors that have been dropped */
+
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_SCOTTISH_GAELIC },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_IRISH_GAELIC },
+
+#endif
+
+  /* The following codes are new as of 2000-03-10 */
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_GALICIAN,             "gl" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_AFRIKAANS,            "af" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_BRETON,               "br" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_INUKTITUT,            "iu" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_SCOTTISH_GAELIC,      "gd" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_MANX_GAELIC,          "gv" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_IRISH_GAELIC,         "ga" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_TONGAN,               "to" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_GREEK_POLYTONIC,      "el" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_GREELANDIC,           "ik" },
+ {  TT_PLATFORM_MACINTOSH,      TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT,"az" },
+
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_SAUDI_ARABIA,       "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_IRAQ,               "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_EGYPT,              "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_LIBYA,              "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_ALGERIA,            "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_MOROCCO,            "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_TUNISIA,            "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_OMAN,               "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_YEMEN,              "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_SYRIA,              "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_JORDAN,             "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_LEBANON,            "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_KUWAIT,             "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_UAE,                "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_BAHRAIN,            "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_QATAR,              "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_BULGARIAN_BULGARIA,        "bg" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_CATALAN_SPAIN,             "ca" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_CHINESE_TAIWAN,            "zh-tw" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_CHINESE_PRC,               "zh-cn" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_CHINESE_HONG_KONG,         "zh-hk" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_CHINESE_SINGAPORE,         "zh-sg" },
+
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_CHINESE_MACAU,             "zh-mo" },
+
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_CZECH_CZECH_REPUBLIC,      "cs" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_DANISH_DENMARK,            "da" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_GERMAN_GERMANY,            "de" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_GERMAN_SWITZERLAND,        "de" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_GERMAN_AUSTRIA,            "de" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_GERMAN_LUXEMBOURG,         "de" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_GERMAN_LIECHTENSTEI,       "de" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_GREEK_GREECE,              "el" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_UNITED_STATES,     "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_UNITED_KINGDOM,    "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_AUSTRALIA,         "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_CANADA,            "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_NEW_ZEALAND,       "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_IRELAND,           "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_SOUTH_AFRICA,      "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_JAMAICA,           "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_CARIBBEAN,         "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_BELIZE,            "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_TRINIDAD,          "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_ZIMBABWE,          "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_PHILIPPINES,       "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT,"es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_MEXICO,            "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT,"es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_GUATEMALA,         "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_COSTA_RICA,        "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_PANAMA,            "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC,"es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_VENEZUELA,         "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_COLOMBIA,          "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_PERU,              "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_ARGENTINA,         "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_ECUADOR,           "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_CHILE,             "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_URUGUAY,           "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_PARAGUAY,          "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_BOLIVIA,           "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_EL_SALVADOR,       "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_HONDURAS,          "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_NICARAGUA,         "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_PUERTO_RICO,       "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FINNISH_FINLAND,           "fi" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_FRANCE,             "fr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_BELGIUM,            "fr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_CANADA,             "fr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_SWITZERLAND,        "fr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_LUXEMBOURG,         "fr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_MONACO,             "fr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_HEBREW_ISRAEL,             "he" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_HUNGARIAN_HUNGARY,         "hu" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ICELANDIC_ICELAND,         "is" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ITALIAN_ITALY,             "it" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ITALIAN_SWITZERLAND,       "it" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_JAPANESE_JAPAN,            "ja" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA,"ko" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_KOREAN_JOHAB_KOREA,        "ko" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_DUTCH_NETHERLANDS,         "nl" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_DUTCH_BELGIUM,             "nl" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL,   "no" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK,  "nn" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_POLISH_POLAND,             "pl" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_PORTUGUESE_BRAZIL,         "pt" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_PORTUGUESE_PORTUGAL,       "pt" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND,"rm" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ROMANIAN_ROMANIA,          "ro" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_MOLDAVIAN_MOLDAVIA,        "mo" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_RUSSIAN_RUSSIA,            "ru" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_RUSSIAN_MOLDAVIA,          "ru" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_CROATIAN_CROATIA,          "hr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SERBIAN_SERBIA_LATIN,      "sr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC,   "sr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SLOVAK_SLOVAKIA,           "sk" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ALBANIAN_ALBANIA,          "sq" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SWEDISH_SWEDEN,            "sv" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SWEDISH_FINLAND,           "sv" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_THAI_THAILAND,             "th" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_TURKISH_TURKEY,            "tr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_URDU_PAKISTAN,             "ur" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_INDONESIAN_INDONESIA,      "id" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_UKRAINIAN_UKRAINE,         "uk" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_BELARUSIAN_BELARUS,        "be" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SLOVENE_SLOVENIA,          "sl" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ESTONIAN_ESTONIA,          "et" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_LATVIAN_LATVIA,            "lv" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_LITHUANIAN_LITHUANIA,      "lt" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA,"lt" },
+
+#ifdef TT_MS_LANGID_MAORI_NEW_ZELAND
+    /* this seems to be an error that have been dropped */
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_MAORI_NEW_ZEALAND,         "mi" },
+#endif
+
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FARSI_IRAN,                "fa" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_VIETNAMESE_VIET_NAM,       "vi" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARMENIAN_ARMENIA,          "hy" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN,    "az" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC, "az" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_BASQUE_SPAIN,              "eu" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SORBIAN_GERMANY,           "wen" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_MACEDONIAN_MACEDONIA,      "mk" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SUTU_SOUTH_AFRICA,         "st" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_TSONGA_SOUTH_AFRICA,       "ts" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_TSWANA_SOUTH_AFRICA,       "tn" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_VENDA_SOUTH_AFRICA,        "ven" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_XHOSA_SOUTH_AFRICA,        "xh" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ZULU_SOUTH_AFRICA,         "zu" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA,    "af" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_GEORGIAN_GEORGIA,          "ka" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS,   "fo" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_HINDI_INDIA,               "hi" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_MALTESE_MALTA,             "mt" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SAAMI_LAPONIA,             "se" },
+
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM,"gd" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_IRISH_GAELIC_IRELAND,      "ga" },
+
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_MALAY_MALAYSIA,            "ms" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM,   "ms" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_KAZAK_KAZAKSTAN,           "kk" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SWAHILI_KENYA,             "sw" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN,    "uz" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC, "uz" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_TATAR_TATARSTAN,           "tt" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_BENGALI_INDIA,             "bn" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_PUNJABI_INDIA,             "pa" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_GUJARATI_INDIA,            "gu" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ORIYA_INDIA,               "or" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_TAMIL_INDIA,               "ta" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_TELUGU_INDIA,              "te" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_KANNADA_INDIA,             "kn" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_MALAYALAM_INDIA,           "ml" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ASSAMESE_INDIA,            "as" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_MARATHI_INDIA,             "mr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SANSKRIT_INDIA,            "sa" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_KONKANI_INDIA,             "kok" },
+
+  /* new as of 2001-01-01 */
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ARABIC_GENERAL,            "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_CHINESE_GENERAL,           "zh" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_GENERAL,           "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_WEST_INDIES,        "fr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_REUNION,            "fr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_CONGO,              "fr" },
+
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_SENEGAL,            "fr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_CAMEROON,           "fr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_COTE_D_IVOIRE,      "fr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_MALI,               "fr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA,"bs" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_URDU_INDIA,                "ur" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_TAJIK_TAJIKISTAN,          "tg" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_YIDDISH_GERMANY,           "yi" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN,       "ky" },
+
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_TURKMEN_TURKMENISTAN,      "tk" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_MONGOLIAN_MONGOLIA,        "mn" },
+
+  /* the following seems to be inconsistent;
+     here is the current "official" way: */
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_TIBETAN_BHUTAN,            "bo" },
+  /* and here is what is used by Passport SDK */
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_TIBETAN_CHINA,             "bo" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_DZONGHKA_BHUTAN,           "dz" },
+  /* end of inconsistency */
+
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_WELSH_WALES,               "cy" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_KHMER_CAMBODIA,            "km" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_LAO_LAOS,                  "lo" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_BURMESE_MYANMAR,           "my" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_GALICIAN_SPAIN,            "gl" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_MANIPURI_INDIA,            "mni" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SINDHI_INDIA,              "sd" },
+  /* the following one is only encountered in Microsoft RTF specification */
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_KASHMIRI_PAKISTAN,         "ks" },
+  /* the following one is not in the Passport list, looks like an omission */
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_KASHMIRI_INDIA,            "ks" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_NEPALI_NEPAL,              "ne" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_NEPALI_INDIA,              "ne" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRISIAN_NETHERLANDS,       "fy" },
+
+  /* new as of 2001-03-01 (from Office Xp) */
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_HONG_KONG,         "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_INDIA,             "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_MALAYSIA,          "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_ENGLISH_SINGAPORE,         "en" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SYRIAC_SYRIA,              "syr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SINHALESE_SRI_LANKA,       "si" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_CHEROKEE_UNITED_STATES,    "chr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_INUKTITUT_CANADA,          "iu" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_AMHARIC_ETHIOPIA,          "am" },
+#if 0
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_TAMAZIGHT_MOROCCO },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN },
+#endif
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_PASHTO_AFGHANISTAN,        "ps" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FILIPINO_PHILIPPINES,      "phi" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_DHIVEHI_MALDIVES,          "div" },
+
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_OROMO_ETHIOPIA,            "om" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_TIGRIGNA_ETHIOPIA,         "ti" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_TIGRIGNA_ERYTHREA,         "ti" },
+
+  /* New additions from Windows Xp/Passport SDK 2001-11-10. */
+
+  /* don't ask what this one means... It is commented out currently. */
+#if 0
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_GREEK_GREECE2 },
+#endif
+
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_UNITED_STATES,     "es" },
+  /* The following two IDs blatantly violate MS specs by using a */
+  /* sublanguage >,.                                         */
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SPANISH_LATIN_AMERICA,     "es" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_NORTH_AFRICA,       "fr" },
+
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_MOROCCO,            "fr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FRENCH_HAITI,              "fr" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_BENGALI_BANGLADESH,        "bn" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN,   "ar" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN,"mn" },
+#if 0
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_EDO_NIGERIA },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_FULFULDE_NIGERIA },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_IBIBIO_NIGERIA },
+#endif
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_HAUSA_NIGERIA,             "ha" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_YORUBA_NIGERIA,            "yo" },
+  /* language codes from, to, are (still) unknown. */
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_IGBO_NIGERIA,              "ibo" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_KANURI_NIGERIA,            "kau" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_GUARANI_PARAGUAY,          "gn" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_HAWAIIAN_UNITED_STATES,    "haw" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_LATIN,                     "la" },
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_SOMALI_SOMALIA,            "so" },
+#if 0
+  /* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */
+  /*       not written (but OTOH the peculiar writing system is worth     */
+  /*       studying).                                                     */
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_YI_CHINA },
+#endif
+ {  TT_PLATFORM_MICROSOFT,      TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES,"pap" },
+};
+
+static const char *
+FcSfntNameLanguage (FT_SfntName *sname)
+{
+    int i;
+    FT_UShort platform_id = sname->platform_id;
+    FT_UShort language_id = sname->language_id;
+
+    for (i = 0; i < G_N_ELEMENTS (ftLanguage); i++)
+        if (ftLanguage[i].platform_id == platform_id &&
+            (ftLanguage[i].language_id == TT_LANGUAGE_DONT_CARE ||
+             ftLanguage[i].language_id == language_id))
+        {
+            if (ftLanguage[i].lang[0] == '\0')
+              return NULL;
+            else
+              return ftLanguage[i].lang;
+        }
+    return NULL;
+}
+
+static char *
+FcSfntNameTranscode (FT_SfntName *name)
+{
+    int        i;
+    const char *fromcode;
+
+    for (i = 0; i < G_N_ELEMENTS (ftEncoding); i++)
+        if (ftEncoding[i].platform_id == name->platform_id &&
+            (ftEncoding[i].encoding_id == TT_ENCODING_DONT_CARE ||
+             ftEncoding[i].encoding_id == name->encoding_id))
+            break;
+    if (i == G_N_ELEMENTS (ftEncoding))
+        return  NULL;
+    fromcode = ftEncoding[i].fromcode;
+
+    return g_convert ((const char *)name->string, name->string_len, "UTF-8", fromcode, NULL, NULL, NULL);
+}
+
+static char *
+get_sfnt_name (FT_Face ft_face,
+               guint   nameid)
+{
+  guint count;
+  guint i, j;
+  const char * const *langs = g_get_language_names ();
+  char *res = NULL;
+  guint pos = G_MAXUINT;
+
+  count = FT_Get_Sfnt_Name_Count (ft_face);
+  for (i = 0; i < count; i++)
+    {
+      FT_SfntName name;
+      const char *lang;
+
+      if (FT_Get_Sfnt_Name (ft_face, i, &name) != 0)
+        continue;
+
+      if (name.name_id != nameid)
+        continue;
+
+      lang = FcSfntNameLanguage (&name);
+      for (j = 0; j < pos && langs[j]; j++)
+        {
+          if (strcmp (lang, langs[j]) == 0)
+            {
+              pos = j;
+              g_free (res);
+              res = FcSfntNameTranscode (&name);
+            }
+        }
+
+      if (pos == 0)
+        break;
+    }
+
+  return res;
+}
+
+static gboolean
+is_valid_subfamily_id (guint id)
+{
+  return id == 2 || id == 17 || (255 < id && id < 32768);
+}
+
+static void
+add_instance (FT_Face             ft_face,
+              FT_MM_Var          *ft_mm_var,
+              FT_Var_Named_Style *ns,
+              GtkWidget          *combo,
+              int                 pos)
+{
+  Instance *instance;
+  int i;
+
+  instance = g_new0 (Instance, 1);
+
+  if (is_valid_subfamily_id (ns->strid))
+    instance->name = get_sfnt_name (ft_face, ns->strid);
+  if (!instance->name)
+    instance->name = g_strdup_printf ("Instance %d", pos);
+
+  g_hash_table_add (instances, instance);
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), instance->name);
+
+  instance->n_axes = ft_mm_var->num_axis;
+  instance->axes = g_new (guint32, ft_mm_var->num_axis);
+  instance->coords = g_new (float, ft_mm_var->num_axis);
+
+  for (i = 0; i < ft_mm_var->num_axis; i++)
+    {
+      instance->axes[i] = ft_mm_var->axis[i].tag;
+      instance->coords[i] = FixedToFloat(ns->coords[i]);
+    }
+}
+
+static void
+unset_instance (GtkAdjustment *adjustment)
+{
+  if (instance_combo)
+    gtk_combo_box_set_active (GTK_COMBO_BOX (instance_combo), 0);
+}
+
+static void
+instance_changed (GtkComboBox *combo)
+{
+  char *text;
+  Instance *instance;
+  Instance ikey;
+  int i;
+
+  text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo));
+  if (text[0] == '\0')
+    goto out;
+
+  ikey.name = text;
+  instance = g_hash_table_lookup (instances, &ikey);
+  if (!instance)
+    {
+      g_print ("did not find instance %s\n", text);
+      goto out;
+    }
+
+  for (i = 0; i < instance->n_axes; i++)
+    {
+      Axis *axis;
+      Axis akey;
+      guint32 tag;
+      gdouble value;
+
+      tag = instance->axes[i];
+      value = instance->coords[i];
+
+      akey.tag = tag;
+      axis = g_hash_table_lookup (axes, &akey);
+      if (axis)
+        {
+          g_signal_handlers_block_by_func (axis->adjustment, unset_instance, NULL);
+          gtk_adjustment_set_value (axis->adjustment, value);
+          g_signal_handlers_unblock_by_func (axis->adjustment, unset_instance, NULL);
+        }
+    }
+
+out:
+  g_free (text);
+}
+
+static gboolean
+matches_instance (FT_Var_Named_Style *instance,
+                  FT_Fixed           *coords,
+                  FT_UInt             num_coords)
+{
+  FT_UInt i;
+
+  for (i = 0; i < num_coords; i++)
+    if (coords[i] != instance->coords[i])
+      return FALSE;
+
+  return TRUE;
+}
+
+static void
+add_font_plane (int i)
+{
+  GtkWidget *plane;
+  Axis *weight_axis;
+  Axis *width_axis;
+
+  Axis key;
+
+  key.tag = MAKE_TAG('w','g','h','t');
+  weight_axis = g_hash_table_lookup (axes, &key);
+  key.tag = MAKE_TAG('w','d','t','h');
+  width_axis = g_hash_table_lookup (axes, &key);
+
+  if (weight_axis && width_axis)
+    {
+      plane = gtk_font_plane_new (weight_axis->adjustment,
+                                  width_axis->adjustment);
+
+      gtk_widget_set_size_request (plane, 300, 300);
+      gtk_widget_set_halign (plane, GTK_ALIGN_CENTER);
+      gtk_grid_attach (GTK_GRID (variations_grid), plane, 0, i, 3, 1);
+    }
+}
+
+static void
+update_font_variations (void)
+{
+  GtkWidget *child, *next;
+  PangoFont *pango_font;
+  FT_Face ft_face;
+  FT_MM_Var *ft_mm_var;
+  FT_Error ret;
+
+  child = gtk_widget_get_first_child (variations_grid);
+  while (child != NULL)
+    {
+      next = gtk_widget_get_next_sibling (child);
+      gtk_widget_destroy (child);
+      child = next;
+    }
+
+  instance_combo = NULL;
+
+  g_hash_table_remove_all (axes);
+  g_hash_table_remove_all (instances);
+
+  pango_font = get_pango_font ();
+  ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
+
+  ret = FT_Get_MM_Var (ft_face, &ft_mm_var);
+  if (ret == 0)
+    {
+      unsigned int i;
+      FT_Fixed *coords;
+
+      coords = g_new (FT_Fixed, ft_mm_var->num_axis);
+      ret = FT_Get_Var_Design_Coordinates (ft_face, ft_mm_var->num_axis, coords);
+
+      if (ft_mm_var->num_namedstyles > 0)
+        {
+           GtkWidget *label;
+           GtkWidget *combo;
+
+           label = gtk_label_new ("Instance");
+           gtk_label_set_xalign (GTK_LABEL (label), 0);
+           gtk_widget_set_halign (label, GTK_ALIGN_START);
+           gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
+           gtk_grid_attach (GTK_GRID (variations_grid), label, 0, -1, 2, 1);
+
+           combo = gtk_combo_box_text_new ();
+           gtk_widget_set_valign (combo, GTK_ALIGN_BASELINE);
+           g_signal_connect (combo, "changed", G_CALLBACK (instance_changed), NULL);
+           gtk_grid_attach (GTK_GRID (variations_grid), combo, 1, -1, 2, 1);
+
+           gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "");
+
+           for (i = 0; i < ft_mm_var->num_namedstyles; i++)
+             add_instance (ft_face, ft_mm_var, &ft_mm_var->namedstyle[i], combo, i);
+           for (i = 0; i < ft_mm_var->num_namedstyles; i++)
+             {
+               if (matches_instance (&ft_mm_var->namedstyle[i], coords, ft_mm_var->num_axis))
+                 {
+                   gtk_combo_box_set_active (GTK_COMBO_BOX (combo), i + 1);
+                   break;
+                 }
+             }
+
+           instance_combo = combo;
+        }
+
+      if (ret == 0)
+        {
+          for (i = 0; i < ft_mm_var->num_axis; i++)
+            add_axis (&ft_mm_var->axis[i], coords[i], i);
+
+          add_font_plane (ft_mm_var->num_axis);
+        }
+      g_free (coords);
+      free (ft_mm_var);
+    }
+
+  pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
+  g_object_unref (pango_font);
+}
+
 static void
 font_changed (void)
 {
   update_script_combo ();
+  update_font_variations ();
 }
 
 static void
@@ -420,17 +1467,18 @@ script_changed (void)
 static void
 reset_features (void)
 {
-  int i;
+  GList *l;
 
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (numcasedefault), TRUE);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (numspacedefault), TRUE);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fractiondefault), TRUE);
-  for (i = 0; i < num_features; i++)
+  for (l = feature_items; l; l = l->next)
     {
-      if (!GTK_IS_RADIO_BUTTON (toggle[i]))
+      FeatureItem *item = l->data;
+
+      if (strcmp (item->name, "xxxx") == 0)
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item->feat), TRUE);
+      else if (GTK_IS_CHECK_BUTTON (item->feat))
         {
-          gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle[i]), FALSE);
-          gtk_widget_set_sensitive (toggle[i], FALSE);
+          gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item->feat), FALSE);
+          gtk_widget_set_sensitive (item->feat, FALSE);
         }
     }
 }
@@ -478,7 +1526,7 @@ do_font_features (GtkWidget *do_widget)
   if (!window)
     {
       GtkBuilder *builder;
-      int i;
+      GtkWidget *feature_list;
 
       builder = gtk_builder_new_from_resource ("/font_features/font-features.ui");
 
@@ -492,26 +1540,114 @@ do_font_features (GtkWidget *do_widget)
       gtk_builder_connect_signals (builder, NULL);
 
       window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
+      feature_list = GTK_WIDGET (gtk_builder_get_object (builder, "feature_list"));
       label = GTK_WIDGET (gtk_builder_get_object (builder, "label"));
       settings = GTK_WIDGET (gtk_builder_get_object (builder, "settings"));
+      description = GTK_WIDGET (gtk_builder_get_object (builder, "description"));
       resetbutton = GTK_WIDGET (gtk_builder_get_object (builder, "reset"));
       font = GTK_WIDGET (gtk_builder_get_object (builder, "font"));
       script_lang = GTK_WIDGET (gtk_builder_get_object (builder, "script_lang"));
-      numcasedefault = GTK_WIDGET (gtk_builder_get_object (builder, "numcasedefault"));
-      numspacedefault = GTK_WIDGET (gtk_builder_get_object (builder, "numspacedefault"));
-      fractiondefault = GTK_WIDGET (gtk_builder_get_object (builder, "fractiondefault"));
       stack = GTK_WIDGET (gtk_builder_get_object (builder, "stack"));
       entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
 
-      for (i = 0; i < num_features; i++)
-        {
-          char *iname;
+      add_check_group (feature_list, _("Kerning"), (const char *[]){ "kern", NULL });
+      add_check_group (feature_list, _("Ligatures"), (const char *[]){ "liga",
+                                                                       "dlig",
+                                                                       "hlig",
+                                                                       "clig",
+                                                                       "rlig", NULL });
+      add_check_group (feature_list, _("Letter Case"), (const char *[]){ "smcp",
+                                                                         "c2sc",
+                                                                         "pcap",
+                                                                         "c2pc",
+                                                                         "unic",
+                                                                         "cpsp",
+                                                                         "case",NULL });
+      add_radio_group (feature_list, _("Number Case"), (const char *[]){ "xxxx",
+                                                                         "lnum",
+                                                                         "onum", NULL });
+      add_radio_group (feature_list, _("Number Spacing"), (const char *[]){ "xxxx",
+                                                                            "pnum",
+                                                                            "tnum", NULL });
+      add_radio_group (feature_list, _("Fractions"), (const char *[]){ "xxxx",
+                                                                       "frac",
+                                                                       "afrc", NULL });
+      add_check_group (feature_list, _("Numeric Extras"), (const char *[]){ "zero",
+                                                                            "nalt",
+                                                                            "sinf", NULL });
+      add_check_group (feature_list, _("Character Alternatives"), (const char *[]){ "swsh",
+                                                                                    "cswh",
+                                                                                    "locl",
+                                                                                    "calt",
+                                                                                    "falt",
+                                                                                    "hist",
+                                                                                    "salt",
+                                                                                    "jalt",
+                                                                                    "titl",
+                                                                                    "rand",
+                                                                                    "subs",
+                                                                                    "sups",
+                                                                                    "ordn",
+                                                                                    "ltra",
+                                                                                    "ltrm",
+                                                                                    "rtla",
+                                                                                    "rtlm",
+                                                                                    "rclt", NULL });
+      add_check_group (feature_list, _("Positional Alternatives"), (const char *[]){ "init",
+                                                                                     "medi",
+                                                                                     "med2",
+                                                                                     "fina",
+                                                                                     "fin2",
+                                                                                     "fin3",
+                                                                                     "isol", NULL });
+      add_check_group (feature_list, _("Width Variants"), (const char *[]){ "fwid",
+                                                                            "hwid",
+                                                                            "halt",
+                                                                            "pwid",
+                                                                            "palt",
+                                                                            "twid",
+                                                                            "qwid", NULL });
+      add_check_group (feature_list, _("Alternative Stylistic Sets"), (const char *[]){ "ss00",
+                                                                                        "ss01",
+                                                                                        "ss02",
+                                                                                        "ss03",
+                                                                                        "ss04",
+                                                                                        "ss05",
+                                                                                        "ss06",
+                                                                                        "ss07",
+                                                                                        "ss08",
+                                                                                        "ss09",
+                                                                                        "ss10",
+                                                                                        "ss11",
+                                                                                        "ss12",
+                                                                                        "ss13",
+                                                                                        "ss14",
+                                                                                        "ss15",
+                                                                                        "ss16",
+                                                                                        "ss17",
+                                                                                        "ss18",
+                                                                                        "ss19",
+                                                                                        "ss20", NULL });
+      add_check_group (feature_list, _("Mathematical"), (const char *[]){ "dtls",
+                                                                          "flac",
+                                                                          "mgrk",
+                                                                          "ssty", NULL });
+      add_check_group (feature_list, _("Optical Bounds"), (const char *[]){ "opbd",
+                                                                            "lfbd",
+                                                                            "rtbd", NULL });
+      feature_items = g_list_reverse (feature_items);
+
+      variations_heading = GTK_WIDGET (gtk_builder_get_object (builder, "variations_heading"));
+      variations_grid = GTK_WIDGET (gtk_builder_get_object (builder, "variations_grid"));
+      if (instances == NULL)
+        instances = g_hash_table_new_full (instance_hash, instance_equal, NULL, free_instance);
+      else
+        g_hash_table_remove_all (instances);
 
-          toggle[i] = GTK_WIDGET (gtk_builder_get_object (builder, feature_names[i]));
-          iname = g_strconcat (feature_names[i], "_pres", NULL);
-          icon[i] = GTK_WIDGET (gtk_builder_get_object (builder, iname));
-          g_free (iname);
-        }
+      if (axes == NULL)
+        axes = g_hash_table_new_full (axes_hash, axes_equal, NULL, g_free);
+      else
+        g_hash_table_remove_all (axes);
 
       font_changed ();
 
diff --git a/demos/gtk-demo/fontplane.c b/demos/gtk-demo/fontplane.c
new file mode 100644
index 0000000..9f04bd3
--- /dev/null
+++ b/demos/gtk-demo/fontplane.c
@@ -0,0 +1,315 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "fontplane.h"
+
+#include "gtk.h"
+
+enum {
+  PROP_0,
+  PROP_WEIGHT_ADJUSTMENT,
+  PROP_WIDTH_ADJUSTMENT
+};
+
+G_DEFINE_TYPE (GtkFontPlane, gtk_font_plane, GTK_TYPE_WIDGET)
+
+static double
+adjustment_get_normalized_value (GtkAdjustment *adj)
+{
+  return (gtk_adjustment_get_value (adj) - gtk_adjustment_get_lower (adj)) /
+        (gtk_adjustment_get_upper (adj) - gtk_adjustment_get_lower (adj));
+}
+
+static void
+val_to_xy (GtkFontPlane *plane,
+           gint          *x,
+           gint          *y)
+{
+  gdouble u, v;
+  gint width, height;
+
+  width = gtk_widget_get_allocated_width (GTK_WIDGET (plane));
+  height = gtk_widget_get_allocated_height (GTK_WIDGET (plane));
+
+  u = adjustment_get_normalized_value (plane->width_adj);
+  v = adjustment_get_normalized_value (plane->weight_adj);
+
+  *x = CLAMP (width * u, 0, width - 1);
+  *y = CLAMP (height * (1 - v), 0, height - 1);
+}
+
+static void
+plane_snapshot (GtkWidget   *widget,
+                GtkSnapshot *snapshot)
+{
+  GtkFontPlane *plane = GTK_FONT_PLANE (widget);
+  gint x, y;
+  gint width, height;
+  cairo_t *cr;
+
+  val_to_xy (plane, &x, &y);
+  width = gtk_widget_get_allocated_width (widget);
+  height = gtk_widget_get_allocated_height (widget);
+
+  cr = gtk_snapshot_append_cairo (snapshot,
+                                  &GRAPHENE_RECT_INIT (0, 0, width, height),
+                                  "FontPlane");
+
+  cairo_set_source_rgb (cr, 0, 0, 0);
+  cairo_rectangle (cr, 0, 0, width, height);
+  cairo_paint (cr);
+
+  cairo_move_to (cr, 0,     y + 0.5);
+  cairo_line_to (cr, width, y + 0.5);
+
+  cairo_move_to (cr, x + 0.5, 0);
+  cairo_line_to (cr, x + 0.5, height);
+
+  if (gtk_widget_has_visible_focus (widget))
+    {
+      cairo_set_line_width (cr, 3.0);
+      cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.6);
+      cairo_stroke_preserve (cr);
+
+      cairo_set_line_width (cr, 1.0);
+      cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.8);
+      cairo_stroke (cr);
+    }
+  else
+    {
+      cairo_set_line_width (cr, 1.0);
+      cairo_set_source_rgba (cr, 0.8, 0.8, 0.8, 0.8);
+      cairo_stroke (cr);
+    }
+
+  cairo_destroy (cr);
+}
+
+static void
+set_cross_cursor (GtkWidget *widget,
+                  gboolean   enabled)
+{
+  if (enabled)
+    gtk_widget_set_cursor_from_name (widget, "crosshair");
+  else
+    gtk_widget_set_cursor (widget, NULL);
+}
+
+static void
+adj_changed (GtkFontPlane *plane)
+{
+  gtk_widget_queue_draw (GTK_WIDGET (plane));
+}
+
+static void
+adjustment_set_normalized_value (GtkAdjustment *adj,
+                                 double         val)
+{
+  gtk_adjustment_set_value (adj,
+      gtk_adjustment_get_lower (adj) +
+          val * (gtk_adjustment_get_upper (adj) - gtk_adjustment_get_lower (adj)));
+}
+
+static void
+update_value (GtkFontPlane *plane,
+              gint           x,
+              gint           y)
+{
+  GtkWidget *widget = GTK_WIDGET (plane);
+  gdouble u, v;
+
+  u = CLAMP (x * (1.0 / gtk_widget_get_allocated_width (widget)), 0, 1);
+  v = CLAMP (1 - y * (1.0 / gtk_widget_get_allocated_height (widget)), 0, 1);
+
+  adjustment_set_normalized_value (plane->width_adj, u);
+  adjustment_set_normalized_value (plane->weight_adj, v);
+
+  gtk_widget_queue_draw (widget);
+}
+
+static void
+hold_action (GtkGestureLongPress *gesture,
+             gdouble              x,
+             gdouble              y,
+             GtkFontPlane       *plane)
+{
+  gboolean handled;
+
+  g_signal_emit_by_name (plane, "popup-menu", &handled);
+}
+
+static void
+plane_drag_gesture_begin (GtkGestureDrag *gesture,
+                          gdouble         start_x,
+                          gdouble         start_y,
+                          GtkFontPlane  *plane)
+{
+  guint button;
+
+  button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
+
+  if (button == GDK_BUTTON_SECONDARY)
+    {
+      gboolean handled;
+
+      g_signal_emit_by_name (plane, "popup-menu", &handled);
+    }
+
+  if (button != GDK_BUTTON_PRIMARY)
+    {
+      gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
+      return;
+    }
+
+  set_cross_cursor (GTK_WIDGET (plane), TRUE);
+  update_value (plane, start_x, start_y);
+  gtk_widget_grab_focus (GTK_WIDGET (plane));
+  gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
+}
+
+static void
+plane_drag_gesture_update (GtkGestureDrag *gesture,
+                           gdouble         offset_x,
+                           gdouble         offset_y,
+                           GtkFontPlane  *plane)
+{
+  gdouble start_x, start_y;
+
+  gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (gesture),
+                                    &start_x, &start_y);
+  update_value (plane, start_x + offset_x, start_y + offset_y);
+}
+
+static void
+plane_drag_gesture_end (GtkGestureDrag *gesture,
+                        gdouble         offset_x,
+                        gdouble         offset_y,
+                        GtkFontPlane  *plane)
+{
+  set_cross_cursor (GTK_WIDGET (plane), FALSE);
+}
+
+static void
+gtk_font_plane_init (GtkFontPlane *plane)
+{
+  gtk_widget_set_has_window (GTK_WIDGET (plane), FALSE);
+  gtk_widget_set_can_focus (GTK_WIDGET (plane), TRUE);
+
+  plane->drag_gesture = gtk_gesture_drag_new (GTK_WIDGET (plane));
+  g_signal_connect (plane->drag_gesture, "drag-begin",
+                   G_CALLBACK (plane_drag_gesture_begin), plane);
+  g_signal_connect (plane->drag_gesture, "drag-update",
+                   G_CALLBACK (plane_drag_gesture_update), plane);
+  g_signal_connect (plane->drag_gesture, "drag-end",
+                   G_CALLBACK (plane_drag_gesture_end), plane);
+  gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (plane->drag_gesture), 0);
+
+  plane->long_press_gesture = gtk_gesture_long_press_new (GTK_WIDGET (plane));
+  g_signal_connect (plane->long_press_gesture, "pressed",
+                    G_CALLBACK (hold_action), plane);
+  gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (plane->long_press_gesture),
+                                     TRUE);
+}
+
+static void
+plane_finalize (GObject *object)
+{
+  GtkFontPlane *plane = GTK_FONT_PLANE (object);
+
+  g_clear_object (&plane->weight_adj);
+  g_clear_object (&plane->width_adj);
+
+  g_clear_object (&plane->drag_gesture);
+  g_clear_object (&plane->long_press_gesture);
+
+  G_OBJECT_CLASS (gtk_font_plane_parent_class)->finalize (object);
+}
+
+static void
+plane_set_property (GObject      *object,
+                   guint         prop_id,
+                   const GValue *value,
+                   GParamSpec   *pspec)
+{
+  GtkFontPlane *plane = GTK_FONT_PLANE (object);
+  GObject *adjustment;
+
+  switch (prop_id)
+    {
+    case PROP_WEIGHT_ADJUSTMENT:
+      adjustment = g_value_get_object (value);
+      if (adjustment)
+       {
+         plane->weight_adj = g_object_ref_sink (adjustment);
+         g_signal_connect_swapped (adjustment, "value-changed", G_CALLBACK (adj_changed), plane);
+       }
+      break;
+    case PROP_WIDTH_ADJUSTMENT:
+      adjustment = g_value_get_object (value);
+      if (adjustment)
+       {
+         plane->width_adj = g_object_ref_sink (adjustment);
+         g_signal_connect_swapped (adjustment, "value-changed", G_CALLBACK (adj_changed), plane);
+       }
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_font_plane_class_init (GtkFontPlaneClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+  object_class->finalize = plane_finalize;
+  object_class->set_property = plane_set_property;
+
+  widget_class->snapshot = plane_snapshot;
+
+  g_object_class_install_property (object_class,
+                                   PROP_WEIGHT_ADJUSTMENT,
+                                   g_param_spec_object ("weight-adjustment",
+                                                        NULL,
+                                                        NULL,
+                                                       GTK_TYPE_ADJUSTMENT,
+                                                       G_PARAM_WRITABLE |
+                                                       G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (object_class,
+                                   PROP_WIDTH_ADJUSTMENT,
+                                   g_param_spec_object ("width-adjustment",
+                                                        NULL,
+                                                        NULL,
+                                                       GTK_TYPE_ADJUSTMENT,
+                                                       G_PARAM_WRITABLE |
+                                                       G_PARAM_CONSTRUCT_ONLY));
+}
+
+GtkWidget *
+gtk_font_plane_new (GtkAdjustment *weight_adj,
+                     GtkAdjustment *width_adj)
+{
+  return g_object_new (GTK_TYPE_FONT_PLANE,
+                       "weight-adjustment", weight_adj,
+                       "width-adjustment", width_adj,
+                       NULL);
+}
diff --git a/demos/gtk-demo/fontplane.h b/demos/gtk-demo/fontplane.h
new file mode 100644
index 0000000..e9983a1
--- /dev/null
+++ b/demos/gtk-demo/fontplane.h
@@ -0,0 +1,65 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GTK_FONT_PLANE_H__
+#define __GTK_FONT_PLANE_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_FONT_PLANE            (gtk_font_plane_get_type ())
+#define GTK_FONT_PLANE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FONT_PLANE, 
GtkFontPlane))
+#define GTK_FONT_PLANE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FONT_PLANE, 
GtkFontPlaneClass))
+#define GTK_IS_FONT_PLANE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_COLOR_PLANE))
+#define GTK_IS_FONT_PLANE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_COLOR_PLANE))
+#define GTK_FONT_PLANE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FONT_PLANE, 
GtkFontPlaneClass))
+
+
+typedef struct _GtkFontPlane         GtkFontPlane;
+typedef struct _GtkFontPlaneClass    GtkFontPlaneClass;
+
+struct _GtkFontPlane
+{
+  GtkWidget parent_instance;
+
+  GtkAdjustment *weight_adj;
+  GtkAdjustment *width_adj;
+
+  GtkGesture *drag_gesture;
+  GtkGesture *long_press_gesture;
+};
+
+struct _GtkFontPlaneClass
+{
+  GtkWidgetClass parent_class;
+
+  /* Padding for future expansion */
+  void (*_gtk_reserved1) (void);
+  void (*_gtk_reserved2) (void);
+  void (*_gtk_reserved3) (void);
+  void (*_gtk_reserved4) (void);
+};
+
+
+GType       gtk_font_plane_get_type (void) G_GNUC_CONST;
+GtkWidget * gtk_font_plane_new      (GtkAdjustment *width_adj,
+                                     GtkAdjustment *weight_adj);
+
+G_END_DECLS
+
+#endif /* __GTK_FONT_PLANE_H__ */
diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build
index 0d57447..acd0c6a 100644
--- a/demos/gtk-demo/meson.build
+++ b/demos/gtk-demo/meson.build
@@ -94,7 +94,7 @@ gtkdemo_resources = gnome.compile_resources('gtkdemo_resources',
                                             source_dir: '.')
 
 executable('gtk4-demo',
-           'main.c', 'gtkfishbowl.c', demos, demos_h, gtkdemo_resources,
+           'main.c', 'gtkfishbowl.c', 'fontplane.c', demos, demos_h, gtkdemo_resources,
            c_args: gtkdemo_args,
            dependencies: gtkdemo_deps,
            include_directories: confinc,
diff --git a/demos/gtk-demo/open-type-layout.h b/demos/gtk-demo/open-type-layout.h
new file mode 100644
index 0000000..22521f3
--- /dev/null
+++ b/demos/gtk-demo/open-type-layout.h
@@ -0,0 +1,155 @@
+/* Registered OpenType layout tags, see
+ * https://www.microsoft.com/typography/otspec/featuretags.htm
+ */
+
+typedef struct {
+  unsigned int tag;
+  const char *name;
+} NamedTag;
+
+#define MAKE_TAG(a,b,c,d) (unsigned int)(((a) << 24) | ((b) << 16) | ((c) <<  8) | (d))
+
+static NamedTag open_type_layout_features[] = {
+  { MAKE_TAG('a','a','l','t'), NC_("OpenType layout", "Access All Alternates") },
+  { MAKE_TAG('a','b','v','f'), NC_("OpenType layout", "Above-base Forms") },
+  { MAKE_TAG('a','b','v','m'), NC_("OpenType layout", "Above-base Mark Positioning") },
+  { MAKE_TAG('a','b','v','s'), NC_("OpenType layout", "Above-base Substitutions") },
+  { MAKE_TAG('a','f','r','c'), NC_("OpenType layout", "Alternative Fractions") },
+  { MAKE_TAG('a','k','h','n'), NC_("OpenType layout", "Akhands") },
+  { MAKE_TAG('b','l','w','f'), NC_("OpenType layout", "Below-base Forms") },
+  { MAKE_TAG('b','l','w','m'), NC_("OpenType layout", "Below-base Mark Positioning") },
+  { MAKE_TAG('b','l','w','s'), NC_("OpenType layout", "Below-base Substitutions") },
+  { MAKE_TAG('c','a','l','t'), NC_("OpenType layout", "Contextual Alternates") },
+  { MAKE_TAG('c','a','s','e'), NC_("OpenType layout", "Case-Sensitive Forms") },
+  { MAKE_TAG('c','c','m','p'), NC_("OpenType layout", "Glyph Composition / Decomposition") },
+  { MAKE_TAG('c','f','a','r'), NC_("OpenType layout", "Conjunct Form After Ro") },
+  { MAKE_TAG('c','j','c','t'), NC_("OpenType layout", "Conjunct Forms") },
+  { MAKE_TAG('c','l','i','g'), NC_("OpenType layout", "Contextual Ligatures") },
+  { MAKE_TAG('c','p','c','t'), NC_("OpenType layout", "Centered CJK Punctuation") },
+  { MAKE_TAG('c','p','s','p'), NC_("OpenType layout", "Capital Spacing") },
+  { MAKE_TAG('c','s','w','h'), NC_("OpenType layout", "Contextual Swash") },
+  { MAKE_TAG('c','u','r','s'), NC_("OpenType layout", "Cursive Positioning") },
+  { MAKE_TAG('c','2','p','c'), NC_("OpenType layout", "Petite Capitals From Capitals") },
+  { MAKE_TAG('c','2','s','c'), NC_("OpenType layout", "Small Capitals From Capitals") },
+  { MAKE_TAG('d','i','s','t'), NC_("OpenType layout", "Distances") },
+  { MAKE_TAG('d','l','i','g'), NC_("OpenType layout", "Discretionary Ligatures") },
+  { MAKE_TAG('d','n','o','m'), NC_("OpenType layout", "Denominators") },
+  { MAKE_TAG('d','t','l','s'), NC_("OpenType layout", "Dotless Forms") },
+  { MAKE_TAG('e','x','p','t'), NC_("OpenType layout", "Expert Forms") },
+  { MAKE_TAG('f','a','l','t'), NC_("OpenType layout", "Final Glyph on Line Alternates") },
+  { MAKE_TAG('f','i','n','2'), NC_("OpenType layout", "Terminal Forms #2") },
+  { MAKE_TAG('f','i','n','3'), NC_("OpenType layout", "Terminal Forms #3") },
+  { MAKE_TAG('f','i','n','a'), NC_("OpenType layout", "Terminal Forms") },
+  { MAKE_TAG('f','l','a','c'), NC_("OpenType layout", "Flattened accent forms") },
+  { MAKE_TAG('f','r','a','c'), NC_("OpenType layout", "Fractions") },
+  { MAKE_TAG('f','w','i','d'), NC_("OpenType layout", "Full Widths") },
+  { MAKE_TAG('h','a','l','f'), NC_("OpenType layout", "Half Forms") },
+  { MAKE_TAG('h','a','l','n'), NC_("OpenType layout", "Halant Forms") },
+  { MAKE_TAG('h','a','l','t'), NC_("OpenType layout", "Alternate Half Widths") },
+  { MAKE_TAG('h','i','s','t'), NC_("OpenType layout", "Historical Forms") },
+  { MAKE_TAG('h','k','n','a'), NC_("OpenType layout", "Horizontal Kana Alternates") },
+  { MAKE_TAG('h','l','i','g'), NC_("OpenType layout", "Historical Ligatures") },
+  { MAKE_TAG('h','n','g','l'), NC_("OpenType layout", "Hangul") },
+  { MAKE_TAG('h','o','j','o'), NC_("OpenType layout", "Hojo Kanji Forms") },
+  { MAKE_TAG('h','w','i','d'), NC_("OpenType layout", "Half Widths") },
+  { MAKE_TAG('i','n','i','t'), NC_("OpenType layout", "Initial Forms") },
+  { MAKE_TAG('i','s','o','l'), NC_("OpenType layout", "Isolated Forms") },
+  { MAKE_TAG('i','t','a','l'), NC_("OpenType layout", "Italics") },
+  { MAKE_TAG('j','a','l','t'), NC_("OpenType layout", "Justification Alternates") },
+  { MAKE_TAG('j','p','7','8'), NC_("OpenType layout", "JIS78 Forms") },
+  { MAKE_TAG('j','p','8','3'), NC_("OpenType layout", "JIS83 Forms") },
+  { MAKE_TAG('j','p','9','0'), NC_("OpenType layout", "JIS90 Forms") },
+  { MAKE_TAG('j','p','0','4'), NC_("OpenType layout", "JIS2004 Forms") },
+  { MAKE_TAG('k','e','r','n'), NC_("OpenType layout", "Kerning") },
+  { MAKE_TAG('l','f','b','d'), NC_("OpenType layout", "Left Bounds") },
+  { MAKE_TAG('l','i','g','a'), NC_("OpenType layout", "Standard Ligatures") },
+  { MAKE_TAG('l','j','m','o'), NC_("OpenType layout", "Leading Jamo Forms") },
+  { MAKE_TAG('l','n','u','m'), NC_("OpenType layout", "Lining Figures") },
+  { MAKE_TAG('l','o','c','l'), NC_("OpenType layout", "Localized Forms") },
+  { MAKE_TAG('l','t','r','a'), NC_("OpenType layout", "Left-to-right alternates") },
+  { MAKE_TAG('l','t','r','m'), NC_("OpenType layout", "Left-to-right mirrored forms") },
+  { MAKE_TAG('m','a','r','k'), NC_("OpenType layout", "Mark Positioning") },
+  { MAKE_TAG('m','e','d','2'), NC_("OpenType layout", "Medial Forms #2") },
+  { MAKE_TAG('m','e','d','i'), NC_("OpenType layout", "Medial Forms") },
+  { MAKE_TAG('m','g','r','k'), NC_("OpenType layout", "Mathematical Greek") },
+  { MAKE_TAG('m','k','m','k'), NC_("OpenType layout", "Mark to Mark Positioning") },
+  { MAKE_TAG('m','s','e','t'), NC_("OpenType layout", "Mark Positioning via Substitution") },
+  { MAKE_TAG('n','a','l','t'), NC_("OpenType layout", "Alternate Annotation Forms") },
+  { MAKE_TAG('n','l','c','k'), NC_("OpenType layout", "NLC Kanji Forms") },
+  { MAKE_TAG('n','u','k','t'), NC_("OpenType layout", "Nukta Forms") },
+  { MAKE_TAG('n','u','m','r'), NC_("OpenType layout", "Numerators") },
+  { MAKE_TAG('o','n','u','m'), NC_("OpenType layout", "Oldstyle Figures") },
+  { MAKE_TAG('o','p','b','d'), NC_("OpenType layout", "Optical Bounds") },
+  { MAKE_TAG('o','r','d','n'), NC_("OpenType layout", "Ordinals") },
+  { MAKE_TAG('o','r','n','m'), NC_("OpenType layout", "Ornaments") },
+  { MAKE_TAG('p','a','l','t'), NC_("OpenType layout", "Proportional Alternate Widths") },
+  { MAKE_TAG('p','c','a','p'), NC_("OpenType layout", "Petite Capitals") },
+  { MAKE_TAG('p','k','n','a'), NC_("OpenType layout", "Proportional Kana") },
+  { MAKE_TAG('p','n','u','m'), NC_("OpenType layout", "Proportional Figures") },
+  { MAKE_TAG('p','r','e','f'), NC_("OpenType layout", "Pre-Base Forms") },
+  { MAKE_TAG('p','r','e','s'), NC_("OpenType layout", "Pre-base Substitutions") },
+  { MAKE_TAG('p','s','t','f'), NC_("OpenType layout", "Post-base Forms") },
+  { MAKE_TAG('p','s','t','s'), NC_("OpenType layout", "Post-base Substitutions") },
+  { MAKE_TAG('p','w','i','d'), NC_("OpenType layout", "Proportional Widths") },
+  { MAKE_TAG('q','w','i','d'), NC_("OpenType layout", "Quarter Widths") },
+  { MAKE_TAG('r','a','n','d'), NC_("OpenType layout", "Randomize") },
+  { MAKE_TAG('r','c','l','t'), NC_("OpenType layout", "Required Contextual Alternates") },
+  { MAKE_TAG('r','k','r','f'), NC_("OpenType layout", "Rakar Forms") },
+  { MAKE_TAG('r','l','i','g'), NC_("OpenType layout", "Required Ligatures") },
+  { MAKE_TAG('r','p','h','f'), NC_("OpenType layout", "Reph Forms") },
+  { MAKE_TAG('r','t','b','d'), NC_("OpenType layout", "Right Bounds") },
+  { MAKE_TAG('r','t','l','a'), NC_("OpenType layout", "Right-to-left alternates") },
+  { MAKE_TAG('r','t','l','m'), NC_("OpenType layout", "Right-to-left mirrored forms") },
+  { MAKE_TAG('r','u','b','y'), NC_("OpenType layout", "Ruby Notation Forms") },
+  { MAKE_TAG('r','v','r','n'), NC_("OpenType layout", "Required Variation Alternates") },
+  { MAKE_TAG('s','a','l','t'), NC_("OpenType layout", "Stylistic Alternates") },
+  { MAKE_TAG('s','i','n','f'), NC_("OpenType layout", "Scientific Inferiors") },
+  { MAKE_TAG('s','i','z','e'), NC_("OpenType layout", "Optical size") },
+  { MAKE_TAG('s','m','c','p'), NC_("OpenType layout", "Small Capitals") },
+  { MAKE_TAG('s','m','p','l'), NC_("OpenType layout", "Simplified Forms") },
+  { MAKE_TAG('s','s','0','1'), NC_("OpenType layout", "Stylistic Set 1") },
+  { MAKE_TAG('s','s','0','2'), NC_("OpenType layout", "Stylistic Set 2") },
+  { MAKE_TAG('s','s','0','3'), NC_("OpenType layout", "Stylistic Set 3") },
+  { MAKE_TAG('s','s','0','4'), NC_("OpenType layout", "Stylistic Set 4") },
+  { MAKE_TAG('s','s','0','5'), NC_("OpenType layout", "Stylistic Set 5") },
+  { MAKE_TAG('s','s','0','6'), NC_("OpenType layout", "Stylistic Set 6") },
+  { MAKE_TAG('s','s','0','7'), NC_("OpenType layout", "Stylistic Set 7") },
+  { MAKE_TAG('s','s','0','8'), NC_("OpenType layout", "Stylistic Set 8") },
+  { MAKE_TAG('s','s','0','9'), NC_("OpenType layout", "Stylistic Set 9") },
+  { MAKE_TAG('s','s','1','0'), NC_("OpenType layout", "Stylistic Set 10") },
+  { MAKE_TAG('s','s','1','1'), NC_("OpenType layout", "Stylistic Set 11") },
+  { MAKE_TAG('s','s','1','2'), NC_("OpenType layout", "Stylistic Set 12") },
+  { MAKE_TAG('s','s','1','3'), NC_("OpenType layout", "Stylistic Set 13") },
+  { MAKE_TAG('s','s','1','4'), NC_("OpenType layout", "Stylistic Set 14") },
+  { MAKE_TAG('s','s','1','5'), NC_("OpenType layout", "Stylistic Set 15") },
+  { MAKE_TAG('s','s','1','6'), NC_("OpenType layout", "Stylistic Set 16") },
+  { MAKE_TAG('s','s','1','7'), NC_("OpenType layout", "Stylistic Set 17") },
+  { MAKE_TAG('s','s','1','8'), NC_("OpenType layout", "Stylistic Set 18") },
+  { MAKE_TAG('s','s','1','9'), NC_("OpenType layout", "Stylistic Set 19") },
+  { MAKE_TAG('s','s','2','0'), NC_("OpenType layout", "Stylistic Set 20") },
+  { MAKE_TAG('s','s','t','y'), NC_("OpenType layout", "Math script style alternates") },
+  { MAKE_TAG('s','t','c','h'), NC_("OpenType layout", "Stretching Glyph Decomposition") },
+  { MAKE_TAG('s','u','b','s'), NC_("OpenType layout", "Subscript") },
+  { MAKE_TAG('s','u','p','s'), NC_("OpenType layout", "Superscript") },
+  { MAKE_TAG('s','w','s','h'), NC_("OpenType layout", "Swash") },
+  { MAKE_TAG('t','i','t','l'), NC_("OpenType layout", "Titling") },
+  { MAKE_TAG('t','j','m','o'), NC_("OpenType layout", "Trailing Jamo Forms") },
+  { MAKE_TAG('t','n','a','m'), NC_("OpenType layout", "Traditional Name Forms") },
+  { MAKE_TAG('t','n','u','m'), NC_("OpenType layout", "Tabular Figures") },
+  { MAKE_TAG('t','r','a','d'), NC_("OpenType layout", "Traditional Forms") },
+  { MAKE_TAG('t','w','i','d'), NC_("OpenType layout", "Third Widths") },
+  { MAKE_TAG('u','n','i','c'), NC_("OpenType layout", "Unicase") },
+  { MAKE_TAG('v','a','l','t'), NC_("OpenType layout", "Alternate Vertical Metrics") },
+  { MAKE_TAG('v','a','t','u'), NC_("OpenType layout", "Vattu Variants") },
+  { MAKE_TAG('v','e','r','t'), NC_("OpenType layout", "Vertical Writing") },
+  { MAKE_TAG('v','h','a','l'), NC_("OpenType layout", "Alternate Vertical Half Metrics") },
+  { MAKE_TAG('v','j','m','o'), NC_("OpenType layout", "Vowel Jamo Forms") },
+  { MAKE_TAG('v','k','n','a'), NC_("OpenType layout", "Vertical Kana Alternates") },
+  { MAKE_TAG('v','k','r','n'), NC_("OpenType layout", "Vertical Kerning") },
+  { MAKE_TAG('v','p','a','l'), NC_("OpenType layout", "Proportional Alternate Vertical Metrics") },
+  { MAKE_TAG('v','r','t','2'), NC_("OpenType layout", "Vertical Alternates and Rotation") },
+  { MAKE_TAG('v','r','t','r'), NC_("OpenType layout", "Vertical Alternates for Rotation") },
+  { MAKE_TAG('z','e','r','o'), NC_("OpenType layout", "Slashed Zero") },
+};
+
+#undef MAKE_TAG



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]