Mark to mark positioning
12 December 2014 Published on 21 October 2012
Important: As of version 1.3.17, the
mark
andmkmk
features are built automatically if there are combining marks withtop
and_top
anchors present in the font. Glyphs 2 and later also auto-builds theccmp
feature. So you do not need to fiddle around with feature code anymore. However, if you do want to make your own feature coding, then note that, since version 2,dotlessi
anddotlessj
have been renamed toidotless
andjdotless
, respectively.
Mark to base positioning
Last time we learned that, through the magic powers of OpenType and Unicode, we can put any accent on any base letter. To sum it up in a nutshell, we created a Prefix in the Features tab of the Font Info and entered this:
markClass [gravecomb acutecomb circumflexcomb] <anchor 0 500> @MARK_TOP_CENTER;
markClass cedillacomb <anchor 0 0> @MARK_BOT_CENTER;
feature ccmp {
# Glyph Composition/Decomposition
sub i' @MARK_TOP_CENTER by dotlessi;
sub j' @MARK_TOP_CENTER by dotlessj;
} ccmp;
feature mark {
# Mark to Base positioning
pos base [a n] <anchor 310 500> mark @MARK_TOP_CENTER
<anchor 310 0> mark @MARK_BOT_CENTER;
pos base [c e g o] <anchor 290 500> mark @MARK_TOP_CENTER
<anchor 290 0> mark @MARK_BOT_CENTER;
pos base [dotlessi dotlessj] <anchor 130 500> mark @MARK_TOP_CENTER
<anchor 130 0> mark @MARK_BOT_CENTER;
pos base [b h l] <anchor 130 700> mark @MARK_TOP_CENTER
<anchor 130 0> mark @MARK_BOT_CENTER;
} mark;
@BASE = [ a n c e g o b h l dotlessi dotlessj ];
@MARKS = [ @MARK_TOP_CENTER @MARK_BOT_CENTER ];
table GDEF {
GlyphClassDef @BASE,,@MARKS,;
} GDEF;
This allowed us to put a circumflex on an n and hang a cedilla on an o. Not very useful, you might say, but what if someone comes up with such an idea for a new letter? Or what if we find that a poet put dots below some of his letters in his handwritten diary to indicate syllable stress? With Unicode, we can encode it, thus type it, and with OpenType, we can actually build a font for that, and we can now make a true historical-critical edition of that poet’s archive.
Mark to mark positioning
Plus: we want to be compatible with a type rendering engine that employs character decomposition with combining accents. And in such an environment, a character sequence such as this one is possible: U+006E LATIN SMALL LETTER N
– U+0302 COMBINING CIRCUMFLEX ACCENT
– U+0303 COMBINING TILDE
. In other words, first we have an n, then a circumflex that sits on top of it, and finally a tilde on top of all of that. Okay, we can encode it. But can we build it?
Yes, we can! OpenType has a feature called mkmk
(Mark to Mark Positioning) which allows the positioning of accents relative to other accents. To cut a long story short, here’s what we inject into our Prefix, right after the mark
feature:
feature mkmk {
# Mark to Mark positioning
lookup STACK_ON_TOP {
lookupflag MarkAttachmentType @MARK_TOP_CENTER;
pos mark [acutecomb circumflexcomb dieresiscomb dotaccentcomb gravecomb] <anchor 0 680> mark @MARK_TOP_CENTER;
pos mark tildecomb <anchor 0 630> mark @MARK_TOP_CENTER;
} STACK_ON_TOP;
lookup STACK_BELOW {
lookupflag MarkAttachmentType @MARK_BOT_CENTER;
pos mark cedillacomb <anchor 0 -200> mark @MARK_BOT_CENTER;
} STACK_BELOW;
} mkmk;
Okay, let’s take a closer look at this. The mkmk
feature is subdivided into several lookups. Each lookup
represents a certain type of attachment. In our case, we have one for attaching an accent on top of another glyph, and another one for hanging accents at the bottom. This is why the lookupflag
defines a MarkAttachmentType
. The MarkAttachmentType
must be a previously defined markClass
. We have one called @MARK_TOP_CENTER
and one called @MARK_BOT_CENTER
. So that’s why we have two lookups here: lookup STACK_ON_TOP
and lookup STACK_BELOW
.
Inside these lookups, we can define anchor
positions for individual accents, or even groups of accents. This works very much like the pos base
rules from the mark
feature, but this time we connect to other accents with pos mark
instead.
As of version 1.3.16, there is a bug which causes negative anchor coordinates to be turned positive at export time. This will likely affect the mark to mark positioning of bottom accents. As a workaround, you can either move up bottom accents until all anchors are above the baseline and change the y coordinates in your
markClass
definition andpos mark
rule accordingly. Or you can fix the values directly in thefeatures
file of that font’s folder inside~/Library/Application Support/Glyphs/Temp/
, and re-export by double clickinggenerateFont.command
in the same folder.
Ha, now we can have fun and shove anchors on top of other anchors, and even give each of them a different color:
Yay!
Update 2014-12-12: Updated the note and moved it to the top.