Iosevka/glyphs/autobuilds.ptl

813 lines
No EOL
26 KiB
Text

###### Automatic builds
# Build accented glyphs
define [isAboveMark mark] : mark && mark.anchors && mark.anchors.above && mark.anchors.above.type === MARK
set font.features {.}
set font.features.cv {.}
define customDecompositions {
# Latvians use comma instead of cedillas in several letters.
# Record them as custom decomposition.
."\u0156" "R\u0326"
."\u0157" "r\u0326"
."\u0136" "K\u0326"
."\u0137" "k\u0326"
."\u0145" "N\u0326"
."\u0146" "n\u0326"
."\u013B" "L\u0326"
."\u013C" "l\u0326"
."\u0122" "G\u0326"
."\u0123" "g\u0312"
# autobuild Latin glyphs
."\u0197" "I\u0335"
."\u019A" "l\u0335"
."\u0248" "J\u0335"
."\u0249" "j\u0335"
."\u0268" "i\u0335"
."\u024C" "R\u0335"
."\u024D" "r\u0335"
."\u01B5" "Z\u0335"
."\u01B6" "z\u0335"
."\u1D7B" "\u026A\u0335"
."\u1D7C" "\u0269\u0335"
."\u1D7F" "\u028A\u0336"
."\u0289" "u\u0336"
."\u0244" "U\u0336"
."\u01E5" "g\u0336"
."\u01BB" "2\u0336"
."\u024E" "Y\u0336"
."\u04B0" "\u04AE\u0335"
."\u04B1" "\u04AF\u0335"
."\u024F" "y\u0336"
."\u023A" "A\u0338"
."\u023B" "C\u0338"
."\u023C" "c\u0337"
."\u023E" "T\u0338"
."\u0246" "E\u0338"
."\u0247" "e\u0337"
."\u0290" "z\u0322"
."\u0256" "d\u0322"
."\u0273" "n\u0322"
."\u01AE" "T\u0322"
."\u1D8F" "a\u0322"
."\u1D90" "\u0251\u0322"
."\u1D91" "\u0257\u0322"
."\u1D99" "u\u0322"
."\u1E9A" "a\u0357"
# Cyrillic composite characters
."\u0498" "\u0417\u0327"
."\u0499" "\u0437\u0327"
."\u04AA" "\u0421\u0327"
."\u04AB" "\u0441\u0327"
# Spacing modifers
# ."`" " \u0300"
."\u02CB" " \u0300"
# ."\u00B4" " \u0301"
."\u02CA" " \u0301"
# ."^" " \u0302"
."\u02C6" " \u0302"
# ."~" " \u0303"
."\u02DC" " \u0303"
."\u00AF" " \u0304"
."\u02C9" " \u0304"
."\u02D8" " \u0306"
."\u02D9" " \u0307"
."\u00A8" " \u0308"
# ."\u00B0" " \u030A"
."\u02DA" " \u030A"
."\u02C7" " \u030C"
."\u00B8" " \u0327"
."\u02CD" " \u0331"
."\u02CE" " \u0316"
."\u02CF" " \u0317"
."\u02D2" " \u0339"
."\u02D3" " \u031C"
."\u02D4" " \u031D"
."\u02D5" " \u031E"
."\u02D6" " \u031F"
."\u02D7" " \u0320"
."\u02DB" " \u0328"
."\u02DD" " \u030B"
."\u02DF" " \u033D"
."\u02EC" " \u032C"
."\u02ED" " \u033F"
."\u02F3" " \u0325"
."\u02F7" " \u0330"
."\u1FED" " \u0308\u0300"
."\u1FEE" " \u0308\u0301"
."\u1FEF" " \u0300"
."\u1FFD" " \u0301"
."\u1FFE" " \u0314"
."\u1FBD" " \u0313"
."\u1FBE" " \u0345"
."\u1FBF" " \u0313"
."\u1FC0" " \u0342"
."\u1FC1" " \u0308\u0342"
."\u0384" " \u0301"
."\u0385" " \u0308\u0301"
# Suppress incorrect slashed arrows... so far
."\u219A" ""
."\u219B" ""
."\u21AE" ""
}
define iotaBelowToLF : function [p] : if (p === glyphs.iotaBelow) glyphs.iotaLF p
define ogonekBelowToTR : function [p] : if (p === glyphs.ogonekBelow) glyphs.ogonekTR p
define [subParts parts] : begin
local hasMarkAbove false
foreach p [items-of parts] : if [isAboveMark p] : set hasMarkAbove true
# replace dotted-i and dotted-j with dotless equalivents
if ((parts.0 === glyphs.i || parts.0 === glyphs.cyrUkrainiani) && hasMarkAbove) : parts.0 = glyphs.dotlessi
if (parts.0 === glyphs.j && hasMarkAbove) : parts.0 = glyphs.dotlessj
# replace below marks with trailing marks
if parts.0.anchors.lf : set parts : parts.map iotaBelowToLF
if parts.0.anchors.trailing : set parts : parts.map ogonekBelowToTR
# composite greek overmarks
for [local j 0] (j < parts.length) [inc j] : piecewise
(parts.(j) === glyphs.commaAbove) : begin
piecewise
(parts.(j + 1) === glyphs.graveAbove) : begin
set parts.(j) null; set parts.(j + 1) glyphs.psilivaria
(parts.(j + 1) === glyphs.acuteAbove) : begin
set parts.(j) null; set parts.(j + 1) glyphs.psilioxia
(parts.(j + 1) === glyphs.perispomeniAbove) : begin
set parts.(j) null; set parts.(j + 1) glyphs.psiliperispomeni
(parts.(j) === glyphs.revCommaAbove) : begin
piecewise
(parts.(j + 1) === glyphs.graveAbove) : begin
set parts.(j) null; set parts.(j + 1) glyphs.dasiavaria
(parts.(j + 1) === glyphs.acuteAbove) : begin
set parts.(j) null; set parts.(j + 1) glyphs.dasiaoxia
(parts.(j + 1) === glyphs.perispomeniAbove) : begin
set parts.(j) null; set parts.(j + 1) glyphs.dasiaperispomeni
return parts
define [pad s n] : begin
while (s.length < n) : s = '0' + s
return s
#set font.features.ccmp {}
define [shorter x y] : if (x.length < y.length) x y
local {cfv} : let : begin
local nComposed 0
local foundDecompositions {.}
define [decideName namingParts parts code] : begin
local baseName namingParts.0.name
local glyphName baseName
foreach [part : namingParts.slice 1] : if part : glyphName = glyphName + [fallback part.shortName part.name]
if foundDecompositions.(glyphName) : begin
local j 2
while foundDecompositions.(glyphName + j) [inc j]
set glyphName (glyphName + j)
if (glyphName.length > 27) : set glyphName ('uni' + [pad [[code.toString 16].toUpperCase] 4])
return glyphName
local [buildForCode code] : if [not unicodeGlyphs.(code)] : begin
local str : String.fromCharCode code
local nfd : fallback customDecompositions.(str) : unorm.nfd str
if (nfd.length > 1) : begin
local parts {}
local allFound true
foreach j [range 0 nfd.length] : begin
local part unicodeGlyphs.([nfd.charCodeAt j])
if [not part] : then : set allFound false
: else : set parts.(j) unicodeGlyphs.([nfd.charCodeAt j])
if allFound : begin
local namingParts : parts.slice 0
set parts : subParts parts
local glyphName : decideName namingParts parts code
set foundDecompositions.(glyphName) {glyphName code parts}
inc nComposed
#if (global && global.gc) : global.gc
if recursiveCodes : recursiveCodes.forEach buildForCode
: else : foreach code [range 0x0000 0xFFFF] : buildForCode code
#if (global && global.gc) : global.gc
progress "Composition Decision"
local {glyphName code parts} {}
define construction : glyph-construction
if code : assign-unicode code
include parts.0 AS_BASE
set-width parts.0.advanceWidth
local names {parts.0.name}
foreach part [items-of : parts.slice 1] : if part : begin
include part
names.push part.name
if (part.name === 'rtailBR') : eject-contour 'serifRB'
define [cfv glyphName _pa] : if (!recursive && _pa.0.featureSelector) : begin
local h {.}
foreach [feature : items-of : Object.keys _pa.0.featureSelector] : begin
local variant _pa.0.featureSelector.(feature)
local variantRoot glyphs.(variant)
if variantRoot : begin
set parts {variantRoot :: [_pa.slice 1]}
set code null
create-glyph (glyphName + '.' + feature) construction
set h.(feature) (glyphName + '.' + feature)
if glyphs.(glyphName) : set glyphs.(glyphName).featureSelector h
foreach [_id : items-of : Object.keys foundDecompositions] : begin
set {glyphName code parts} foundDecompositions.(_id)
create-glyph glyphName construction
cfv glyphName parts
progress "Unicode Precomposites (\(nComposed) glyphs)"
list cfv
symbol-block "Manual Precomposites and CV variants"
cfv 'i' {glyphs.dotlessi glyphs.dotAbove}
cfv 'cyrUkrainiani' {glyphs.i}
foreach [name : items-of : Object.keys glyphs] : begin
if glyphs.(name).featureSelector : begin
local fs glyphs.(name).featureSelector
foreach [feature : items-of : Object.keys fs] : begin
if [not font.features.cv.(feature)] : set font.features.cv.(feature) {.}
set font.features.cv.(feature).(name) fs.(feature)
local MarkZoom : glyph-construction
apply-transform : Upright
apply-transform : Translate (-MIDDLE) (-XH - ACCENT)
apply-transform : Scale ((RIGHTSB - SB) / (markExtend * 3))
apply-transform : Translate (MIDDLE) (XH + ACCENT)
apply-transform : Italify
composite 'asciitilde' glyphs.space glyphs.tildeAbove MarkZoom [into-unicode '~']
composite 'asciigrave' glyphs.space glyphs.graveAbove MarkZoom [into-unicode '`']
composite 'asciicaret' glyphs.space glyphs.circumflexAbove MarkZoom [into-unicode '^']
composite 'latin1acute' glyphs.space glyphs.acuteAbove MarkZoom [into-unicode 0xB4]
composite 'degree' glyphs.space glyphs.ringAbove MarkZoom [into-unicode 0xB0]
if [not recursive] : begin
composite 'asciitilde.centered' glyphs.asciitilde [Upright] [Translate 0 (parenMid - XH - ACCENT)] [Italify]
set glyphs.asciitilde.featureSelector {
.cv16 'asciitilde'
.cv17 'asciitilde.centered'
}
composite 'asterisk.centered' glyphs.asterisk [Upright] [Translate 0 (parenMid - glyphs.asterisk.centery)] [Italify]
set glyphs.asterisk.featureSelector {
.cv18 'asterisk'
.cv19 'asterisk.centered'
}
define [suggestName name] : begin
if glyphs.(name) : begin
local j 2
while glyphs.(name + j) : inc j
set name (name + j)
return name
# Build miniature clyphs : circled, superscripts, subscripts...
define [createCircledGlyphs records] : if [not recursive] : begin
local dscale 0.55
local pendingGlyphs : records.map : [record] -> record.1
local miniatureFont : Miniature pendingGlyphs [fallback para.smallCrowd 3.75] 0.65 nothing true
foreach {unicode glyphid w} [items-of records] : create-glyph [suggestName : 'circle' + glyphid] : glyph-construction
local width : fallback w WIDTH
set-width width
local sw [adviceBlackness 5]
if unicode : assign-unicode unicode
include : create-glyph [suggestName : 'circleinner' + glyphid] : glyph-construction
local g miniatureFont.(glyphid)
include g
local shift 0
if (g.anchors.above && g.anchors.below) : set shift : CAP / 2 - [mix g.anchors.above.y g.anchors.below.y 0.5]
apply-transform : Upright
apply-transform : Translate (-WIDTH / 2) (-CAP / 2 + shift)
apply-transform : Scale dscale
apply-transform : Translate (width / 2) (CAP / 2 * dscale)
apply-transform : Italify
refair this
include : OShape
* (CAP * dscale + [Math.max (CAP * 0.175) (sw * 3)])
* (-[Math.max (CAP * 0.175) (sw * 3)])
* [Math.max (SB + O * 3) (width / 2 - CAP / 2 * dscale - sw * 2.5)]
* [Math.min (width - SB - O * 3) (width / 2 + CAP / 2 * dscale + sw * 2.5)]
* sw
* (SMALLSMOOTHA * width / WIDTH)
* (SMALLSMOOTHB * width / WIDTH)
apply-transform : Upright
apply-transform : Translate 0 (parenMid - CAP * dscale / 2)
apply-transform : Italify
define [createSuperscripts records] : if [not recursive] : begin
local pendingGlyphs : records.map : [record] -> record.1
local miniatureFont : Miniature pendingGlyphs [fallback para.smallCrowd 3.5] 0.7 nothing true
foreach {unicode glyphid} [items-of records] : create-glyph [suggestName : 'sup' + glyphid] : glyph-construction
if unicode : assign-unicode unicode
include miniatureFont.(glyphid) AS_BASE
apply-transform [Upright] true
apply-transform [Translate (-MIDDLE) (-CAP)] true
apply-transform [Scale 0.7] true
apply-transform [Translate MIDDLE (CAP + ACCENT / 2)] true
apply-transform [Italify] true
refair this
define [createSubscripts records] : if [not recursive] : begin
local pendingGlyphs : records.map : [record] -> record.1
local miniatureFont : Miniature pendingGlyphs [fallback para.smallCrowd 3.5] 0.7 nothing true
foreach {unicode glyphid} [items-of records] : create-glyph [suggestName : 'sub' + glyphid] : glyph-construction
if unicode : assign-unicode unicode
include miniatureFont.(glyphid) AS_BASE
apply-transform [Upright] true
apply-transform [Translate (-MIDDLE) 0] true
apply-transform [Scale 0.7] true
apply-transform [Translate MIDDLE (DESCENDER / 2)] true
apply-transform [Italify] true
refair this
define [createSMCPs records] : if [not recursive] : begin
local pendingGlyphs : records.map : [record] -> record.1
local params : Object.create para
set params.cap0 para.cap
set params.cap XH
set params.xheight (XH * XH / CAP)
local sf : Fork pendingGlyphs params
foreach {unicode glyphid tfm} [items-of records] : create-glyph [suggestName : 'smcp' + glyphid] : glyph-construction
if unicode : assign-unicode unicode
include sf.(glyphid) AS_BASE
if tfm : include tfm
define [createMedievalCombs records] : if [not recursive] : begin
local pendingGlyphs : records.map : [record] -> record.1
local miniatureFont : Miniature pendingGlyphs [fallback para.smallCrowd2 3.5] 0.7 nothing true
foreach {unicode glyphid} [items-of records] : create-glyph [suggestName : 'comb' + glyphid] : glyph-construction
set-width 0
if unicode : assign-unicode unicode
include miniatureFont.(glyphid)
apply-transform : Upright
apply-transform : Translate (-MIDDLE) 0
apply-transform : Scale 0.4
apply-transform : Translate markMiddle aboveMarkBot
apply-transform : Italify
refair this
set-anchor 'above' MARK markMiddle XH markMiddle aboveMarkTop
define [createFractions records] : if [not recursive] : begin
local pendingGlyphs : [records.map : [record] -> record.1].concat : records.map : [record] -> record.2
local miniatureFont : Miniature pendingGlyphs 4 0.6 nothing true
foreach {unicode numid denid height} [items-of records] : create-glyph [suggestName : numid + 'over' + denid] : glyph-construction
if unicode : assign-unicode unicode
local fine : adviceBlackness 3
local dist : XH * 0.4
include : create-glyph : glyph-construction
include : create-glyph [suggestName : 'num' + numid] : glyph-construction
include miniatureFont.(numid)
apply-transform : Upright
apply-transform : Translate (- miniatureFont.(numid).advanceWidth / 2) 0
apply-transform : Scale (CAP / [fallback height CAP] * 0.55)
apply-transform : Translate MIDDLE 0
apply-transform : Italify
refair this
apply-transform : Upright
apply-transform : Translate 0 (CAP * 0.55 + dist)
apply-transform : Italify
include : create-glyph [suggestName : 'den' + denid] : glyph-construction
include miniatureFont.(denid)
apply-transform : Upright
apply-transform : Translate (- miniatureFont.(denid).advanceWidth / 2) 0
apply-transform : Scale (CAP / [fallback height CAP] * 0.55)
apply-transform : Translate MIDDLE 0
apply-transform : Italify
refair this
apply-transform : Upright
apply-transform : Translate (-MIDDLE) (-CAP * 0.55 - dist / 2)
apply-transform : Translate MIDDLE parenMid
apply-transform : Italify
include : HBar SB RIGHTSB parenMid (fine * 0.75)
let : if [not recursive] : begin
local compositions : list
list 0xA9 'C'
list 0xAE 'R'
list 0x2117 'P'
list 0x24EA 'zero' FULLWIDTH
list null 'space' FULLWIDTH
foreach [j : range 1 till 9] : compositions.push {(0x2460 + j - 1) unicodeGlyphs.(['0'.charCodeAt 0] + j).name FULLWIDTH}
foreach [j : range 0 26] : compositions.push {(0x24B6 + j) unicodeGlyphs.(['A'.charCodeAt 0] + j).name FULLWIDTH}
foreach [j : range 0 26] : compositions.push {(0x24D0 + j) unicodeGlyphs.(['a'.charCodeAt 0] + j).name FULLWIDTH}
createCircledGlyphs compositions
progress 'Circled'
createSMCPs : list
list 0x1D00 'A'
list 0x1D01 'AE'
list 0x1D03 'Bbar'
list 0x1D04 'C'
list 0x1D05 'D'
list 0x1D06 'Dcroat'
list 0x1D07 'E'
list 0x1D08 'cyrZe'
list 0x1D0A 'J'
list 0x1D0B 'K'
list 0x1D0C 'Lslash'
list 0x1D0D 'M'
list 0x1D0E 'cyrI'
list 0x1D0F 'O'
list 0x1D10 'turnC'
list 0x1D15 'OU'
list 0x1D18 'P'
list 0x1D19 'cyrYa'
list 0x1D1A 'R' [FlipAround MIDDLE (XH / 2)]
list 0x1D1B 'T'
list 0x1D1C 'U'
list 0x1D20 'V'
list 0x1D21 'W'
list 0x1D22 'Z'
list 0x1D23 'Ezh'
list 0x1D26 'Gamma'
list 0x1D27 'Lambda'
list 0x1D28 'Pi'
list 0x1D29 'Rho'
list 0x1D2B 'cyrEl'
progress 'Small Caps'
createSuperscripts : list
list 0x2070 'zero'
list 0x00B9 'one'
list 0x00B2 'two'
list 0x00B3 'three'
list 0x2074 'four'
list 0x2075 'five'
list 0x2076 'six'
list 0x2077 'seven'
list 0x2078 'eight'
list 0x2079 'nine'
list 0x02B0 'h'
list 0x02B1 'hhooktop'
list 0x02B2 'j'
list 0x02B3 'r'
list 0x02B4 'turnr'
list 0x02B5 'turnrrtail'
list 0x02B6 'invsmcpR'
list 0x02B7 'w'
list 0x02B8 'y'
list 0x02C0 'fineglottalstop'
list 0x02C1 'finerevglottalstop'
list 0x02E0 'latingamma'
list 0x02E1 'l'
list 0x02E2 's'
list 0x02E3 'x'
list 0x02E4 'revglottalstop'
list 0x2071 'i'
list 0x207F 'n'
list 0x1D43 'a'
list 0x1D44 'turna'
list 0x1D45 'scripta'
list 0x1D46 'turnae'
list 0x1D47 'b'
list 0x1D48 'd'
list 0x1D49 'e'
list 0x1D4A 'turne'
list 0x1D4B 'epsilon'
list 0x1D4C 'cyrze'
list 0x1D4D 'g'
list 0x1D4E 'turni'
list 0x1D4F 'k'
list 0x1D50 'm'
list 0x1D51 'eng'
list 0x1D52 'o'
list 0x1D53 'turnc'
list 0x1D54 'oupperhalf'
list 0x1D55 'olowerhalf'
list 0x1D56 'p'
list 0x1D57 't'
list 0x1D58 'u'
list 0x1D5A 'turnm'
list 0x1D5B 'v'
list 0x1D5D 'beta'
list 0x1D5E 'gamma'
list 0x1D5F 'delta'
list 0x1D60 'phi'
list 0x1D61 'chi'
list 0x1D78 'smcpH'
list 0x1D9B 'turnscripta'
list 0x1D9C 'c'
list 0x1D9D 'ccurlytail'
list 0x1D9E 'eth'
list 0x1D9F 'revlatinepsilon'
list 0x1DA0 'f'
list 0x1DA1 'turnf'
list 0x1DA2 'scriptg'
list 0x1DA3 'turnh'
list 0x1DA4 'ibarOver'
list 0x1DA5 'latiniota'
list 0x1DA6 'smcpI'
list 0x1DA7 'smcpIbarOver'
list 0x1DA8 'jcurlytail'
list 0x1DAB 'smcpL'
list 0x1DA9 'lrtail'
list 0x1DAC 'mltail'
list 0x1DAD 'turnmleg'
list 0x1DAE 'nltail'
list 0x1DAF 'nrtailBR'
list 0x1DB0 'smcpN'
list 0x1DB1 'obar'
list 0x1DB2 'varphi'
list 0x1DB3 'srtail'
list 0x1DB4 'esh'
list 0x1DB5 'tltail'
list 0x1DB6 'ulongBarOver'
list 0x1DB7 'latinupsilon1'
list 0x1DB8 'smcpU'
list 0x1DB9 'latinupsilon2'
list 0x1DBA 'turnv'
list 0x1DBC 'zrtailBR'
list 0x1DBD 'zcurlytail'
list 0x1DBE 'ezh'
list 0x1DBF 'theta'
list 0x1DBB 'z'
list 0x1D2C 'A'
list 0x1D2D 'AE'
list 0x1D2E 'B'
list 0x1D2F 'Bbar'
list 0x1D30 'D'
list 0x1D31 'E'
list 0x1D32 'turnE'
list 0x1D33 'G'
list 0x1D34 'H'
list 0x1D35 'I'
list 0x1D36 'J'
list 0x1D37 'K'
list 0x1D38 'L'
list 0x1D39 'M'
list 0x1D3A 'N'
list 0x1D3B 'cyrI'
list 0x1D3C 'O'
list 0x1D3D 'OU'
list 0x1D3E 'P'
list 0x1D3F 'R'
list null 'S' # there is no superscript S in unicode, but is is used for the SM symbol
list 0x1D40 'T'
list 0x1D41 'U'
list 0x1D42 'W'
list 0x2C7D 'V'
list 0x207A 'plus'
list 0x207B 'minus'
list 0x207C 'equal'
list 0x207D 'parenLeft'
list 0x207E 'parenRight'
if [not recursive] : let [df : Miniature {'a' 'o'} 3.5 0.7] : begin
create-glyph 'ordfeminine' : glyph-construction
assign-unicode 0xAA
include df.a
include : HBarBottom SB RIGHTSB DESCENDER
apply-transform : Upright
apply-transform : Translate (-MIDDLE) (-XH)
apply-transform : Scale 0.7
apply-transform : Translate MIDDLE CAP
apply-transform : Italify
create-glyph 'ordmasculine' : glyph-construction
assign-unicode 0xBA
include df.o
include : HBarBottom SB RIGHTSB DESCENDER
apply-transform : Upright
apply-transform : Translate (-MIDDLE) (-XH)
apply-transform : Scale 0.7
apply-transform : Translate MIDDLE CAP
apply-transform : Italify
progress 'Superscripts'
createSubscripts : list
list 0x2080 'zero'
list 0x2081 'one'
list 0x2082 'two'
list 0x2083 'three'
list 0x2084 'four'
list 0x2085 'five'
list 0x2086 'six'
list 0x2087 'seven'
list 0x2088 'eight'
list 0x2089 'nine'
list 0x2090 'a'
list 0x2091 'e'
list 0x2092 'o'
list 0x2093 'x'
list 0x2094 'turne'
list 0x2095 'h'
list 0x2096 'k'
list 0x2097 'l'
list 0x2098 'm'
list 0x2099 'n'
list 0x209A 'p'
list 0x209B 's'
list 0x209C 't'
list 0x1D62 'i'
list 0x1D63 'r'
list 0x1D64 'u'
list 0x1D65 'v'
list 0x1D66 'beta'
list 0x1D67 'gamma'
list 0x1D68 'rho'
list 0x1D69 'phi'
list 0x1D6A 'chi'
list 0x2C7C 'j'
list 0x208A 'plus'
list 0x208B 'minus'
list 0x208C 'equal'
list 0x208D 'parenLeft'
list 0x208E 'parenRight'
progress 'Subscripts'
createFractions : list
list 0x00BC 'one' 'four'
list 0x00BD 'one' 'two'
list 0x00BE 'three' 'four'
list 0x2150 'one' 'seven'
list 0x2151 'one' 'nine'
list 0x2152 'one' 'ten'
list 0x2153 'one' 'three'
list 0x2154 'two' 'three'
list 0x2155 'one' 'five'
list 0x2156 'two' 'five'
list 0x2157 'three' 'five'
list 0x2158 'four' 'five'
list 0x2159 'one' 'six'
list 0x215A 'five' 'six'
list 0x215B 'one' 'eight'
list 0x215C 'three' 'eight'
list 0x215D 'five' 'eight'
list 0x215E 'seven' 'eight'
list 0x2189 'zero' 'three'
# care-of
list 0x2105 'C' 'O'
list 0x2106 'C' 'U'
# Powerline LN symbol
list 0xE0A1 'L' 'N'
# fraction bar
list null 'space' 'space'
progress 'Fractions'
createMedievalCombs : list
list 0x363 'a'
list 0x364 'e'
list 0x365 'i'
list 0x366 'o'
list 0x367 'u'
list 0x368 'c'
list 0x369 'd'
list 0x36A 'h'
list 0x36B 'm'
list 0x36C 'r'
list 0x36D 't'
list 0x36E 'v'
list 0x36F 'x'
progress 'Medival Combining Characters'
# Ligatures
symbol-block 'Unicode Ligatures'
define shrink : clamp 0.75 0.9 : linreg 72 0.75 108 0.9 STROKE
define [createLigatures records] : if [not recursive] : begin
local pendingGlyphs : [records.map : [record] -> record.1].concat : records.map : [record] -> record.2
local df : Thinner pendingGlyphs shrink 1
foreach [{unicode c1 c2} : items-of records] : begin
local glyphName "\(c1)_\(c2)"
if glyphs.(glyphName) : begin
local j 2
while glyphs.(glyphName + j) : inc j
set glyphName (glyphName + j)
create-glyph glyphName : glyph-construction
assign-unicode unicode
include df.(c2)
include : Translate (WIDTH * shrink - SB * shrink * 1.75) 0
include df.(c1)
include : Upright
include : Translate (-WIDTH * shrink + (SB * shrink * 7/8)) 0
include : Scale ((WIDTH - SB * 1.25) / (WIDTH - SB * 2) * WIDTH / (WIDTH * shrink * 2 - SB * shrink * 1.75)) 1
include : Translate (WIDTH / 2) 0
include : Italify
createLigatures : list
list 0x1C4 'D' 'Zcaron'
list 0x1C5 'D' 'zcaron'
list 0x1C6 'd' 'zcaron'
list 0x1C7 'L' 'J'
list 0x1C8 'L' 'j'
list 0x1C9 'l' 'j'
list 0x1CA 'N' 'J'
list 0x1CB 'N' 'j'
list 0x1CC 'n' 'j'
list 0x2A3 'd' 'z'
list 0x1F1 'D' 'Z'
list 0x1F2 'D' 'z'
list 0x1F3 'd' 'z'
list 0x2A4 'd' 'ezh'
list 0x2A5 'd' 'zcurlytail'
list 0x2A6 't' 's'
list 0x2A7 't' 'esh'
list 0x2A8 't' 'ccurlytail'
list 0x2A9 'f' 'eng'
list 0x2AA 'l' 's'
list 0x2AB 'l' 'z'
# Composite superscripts and subscripts
let : begin
define [doubleSuperscript a b] : glyph-construction
include a
apply-transform : Translate (-WIDTH * 0.6) 0
include b
apply-transform : Upright
apply-transform : Translate (-WIDTH * 0.2) (-CAP)
apply-transform : Scale 0.8
apply-transform : Translate MIDDLE CAP
apply-transform : Italify
create-glyph 'trademark' : glyph-construction
assign-unicode 0x2122
include : doubleSuperscript glyphs.supT glyphs.supM
create-glyph 'servicemark' : glyph-construction
assign-unicode 0x2120
include : doubleSuperscript glyphs.supS glyphs.supM
progress 'Double Superscripts'
# CJK double width letters
symbol-block 'CJK Double Width Characters'
define [createDoubleWidth records] : if [not recursive] : begin
local scale 1.25
local pendingGlyphs : records.map : [record] -> record.1
local widenFont : Widen pendingGlyphs scale (scale * 1.1)
foreach {unicode glyphid} [items-of records] : create-glyph [suggestName : 'dw' + glyphid] : glyph-construction
set-width UPM
if unicode : assign-unicode unicode
include widenFont.(glyphid) AS_BASE
apply-transform [Translate (UPM / 2 - (WIDTH * scale) / 2) 0] true
if [not recursive] : createDoubleWidth : let [a {}] : begin
foreach [j : range 1 0x5f] : if [not unicodeGlyphs.(0xff00 + j)] : a.push {(0xff00 + j) unicodeGlyphs.(0x20 + j).name}
* a
### Generate Features and remove double-width glyphs when necessary
if [not recursive] : begin
if [not para.cjk] : begin
set font.glyf : font.glyf.filter [lambda [g] : g.advanceWidth <= WIDTH]
set glyphList font.glyf
set font.features.mark {.}
set font.features.mkmk {.marks {} .bases {}}
set font.features.markGlyphs {.}
set font.features.gdef {.simple {} .ligature {} .mark {}}
define [buildAnchorDescription glyph inserter propx propy prefix th] : begin
local buf ''
foreach key [items-of : Object.keys glyph.anchors] : if (!th || th.(key)) : buf = buf + ' <anchor ' + [Math.round glyph.anchors.(key).(propx)] + ' ' + [Math.round glyph.anchors.(key).(propy)] + '> ' + inserter + ' @' + prefix + key
return buf
# mark
define [createMarkLookup tableName anchorClasses] : let [lookup : set font.features.mark.(tableName) {.marks {} .bases {}}] : begin
local th {.}
foreach [ac : items-of anchorClasses] : set th.(ac) true
foreach glyph [items-of glyphList] : if glyph.anchors : begin
local anchorKeys : Object.keys glyph.anchors
local hasAnchor false
foreach [key : items-of anchorKeys] : if th.(key) : set hasAnchor true
if hasAnchor : begin
local isMarkGlyph false
foreach key [items-of anchorKeys] : if (glyph.anchors.(key).type == 'mark') : set isMarkGlyph true
if isMarkGlyph
then : lookup.marks.push : 'markClass ' + glyph.name + [buildAnchorDescription glyph '' 'x' 'y' 'mark' th]
else : lookup.bases.push : 'pos base ' + glyph.name + [buildAnchorDescription glyph 'mark' 'x' 'y' 'mark' th]
createMarkLookup 'letter1' {'above' 'below'}
createMarkLookup 'letter2' {'trailing' 'lf' 'topright' 'bottomright'}
createMarkLookup 'overlay' {'overlay' 'slash'}
# mkmk and GDEF
foreach glyph [items-of glyphList] : if (glyph.anchors && [begin [local anchorKeys : Object.keys glyph.anchors] anchorKeys.length])
then
local isMarkGlyph false
foreach key [items-of anchorKeys] : if (glyph.anchors.(key).type == 'mark') : set isMarkGlyph true
if isMarkGlyph
then
font.features.mkmk.marks.push : 'markClass ' + glyph.name + ' ' + [buildAnchorDescription glyph '' 'x' 'y' 'mkmk']
font.features.mkmk.bases.push : 'pos mark ' + glyph.name + ' ' + [buildAnchorDescription glyph 'mark' 'mbx' 'mby' 'mkmk']
foreach key [items-of anchorKeys] : begin
if [not font.features.markGlyphs.(key)] : set font.features.markGlyphs.(key) {}
font.features.markGlyphs.(key).push glyph.name
font.features.gdef.mark.push glyph.name
else : if [[regex '_'].test glyph.name] [font.features.gdef.ligature.push glyph.name] [font.features.gdef.simple.push glyph.name]
else : if [[regex '_'].test glyph.name] [font.features.gdef.ligature.push glyph.name] [font.features.gdef.simple.push glyph.name]
progress 'Features'