90 lines
3.3 KiB
Text
90 lines
3.3 KiB
Text
import [Glyph] from"../support/glyph/index.mjs"
|
|
import [Transform] from"../support/geometry/transform.mjs"
|
|
|
|
define GDEF_SIMPLE 1
|
|
define GDEF_LIGATURE 2
|
|
define GDEF_MARK 3
|
|
|
|
# Compatibility ligatures
|
|
define [interpretLookups gs lutns lookups] : begin
|
|
foreach [lutn : items-of lutns] : begin
|
|
local lut lookups.(lutn)
|
|
if lut : interpretLookup gs lut lookups
|
|
|
|
define [interpretLookup gs lut lookups] : match lut.type
|
|
"gsub_chaining" : begin
|
|
local j 0
|
|
while (j < gs.length) : begin
|
|
local incN 1
|
|
do : foreach [rule : items-of lut.rules] : begin
|
|
local matchT rule.match
|
|
local ib rule.inputBegins
|
|
local foundMatch true
|
|
for [local k 0] (foundMatch && k < matchT.length) [inc k] : begin
|
|
if [not gs.(j + k - ib)]
|
|
: then : set foundMatch false
|
|
: else : if ([matchT.(k).indexOf gs.(j + k - ib)] < 0) : set foundMatch false
|
|
if foundMatch : begin
|
|
foreach [app : items-of rule.apply] : do
|
|
local aj : j - ib + app.at
|
|
local alut lookups.(app.lookup)
|
|
interpretLookupAt gs aj alut
|
|
set incN : incN + rule.inputEnds - rule.inputBegins
|
|
break nothing
|
|
set j : j + incN
|
|
"gsub_reverse" : begin
|
|
local j (gs.length - 1)
|
|
while (j >= 0) : begin
|
|
do : foreach [rule : items-of lut.rules] : begin
|
|
local matchT rule.match
|
|
local ib rule.inputIndex
|
|
local foundMatch true
|
|
for [local k 0] (foundMatch && k < matchT.length) [inc k] : begin
|
|
if [not gs.(j + k - ib)]
|
|
: then : set foundMatch false
|
|
: else : if ([matchT.(k).indexOf gs.(j + k - ib)] < 0) : set foundMatch false
|
|
if foundMatch : begin
|
|
set gs.(j) : rule.to.[matchT.(ib).indexOf gs.(j)] || gs.(j)
|
|
set j : j - 1
|
|
"gsub_single" : begin
|
|
for [local j 0] (j < gs.length) [inc j] : begin
|
|
interpretLookupAt gs j lut
|
|
|
|
define [interpretLookupAt gs j lut] : match lut.type
|
|
"gsub_single" : if lut.substitutions.(gs.(j)) : set gs.(j) lut.substitutions.(gs.(j))
|
|
|
|
export : define [BuildCompatLigatures para glyphStore GSUB GDEF config] : begin
|
|
foreach [cldef : items-of config] : do
|
|
if [not cldef.unicode] : break nothing
|
|
if [not cldef.featureTag] : break nothing
|
|
if [not cldef.sequence] : break nothing
|
|
|
|
local feature null
|
|
foreach [fn : items-of GSUB.languages.'DFLT_DFLT'.features]
|
|
if (cldef.featureTag === [fn.slice 0 4]) : set feature GSUB.features.(fn)
|
|
|
|
if [not feature] : break nothing
|
|
|
|
local gnames {}
|
|
for [local j 0] [j < cldef.sequence.length] [inc j] : begin
|
|
if [not : glyphStore.queryByUnicode : cldef.sequence.charCodeAt j] : break nothing
|
|
gnames.push : glyphStore.queryNameOfUnicode : cldef.sequence.charCodeAt j
|
|
|
|
interpretLookups gnames feature GSUB.lookups
|
|
|
|
define g1Name : '$clig.' + cldef.unicode
|
|
local g1 : new Glyph g1Name
|
|
set g1.advanceWidth 0
|
|
foreach [gn : items-of gnames] : begin
|
|
local g : glyphStore.queryByName gn
|
|
g1.applyTransform : new Transform 1 0 0 1 (-g1.advanceWidth) 0
|
|
g1.includeGlyph g
|
|
g1.applyTransform : new Transform 1 0 0 1 (g1.advanceWidth) 0
|
|
set g1.advanceWidth : g1.advanceWidth + g.advanceWidth
|
|
|
|
if(para.forceMonospace && [Math.round g1.advanceWidth] > [Math.round para.width])
|
|
throw : new Error "Compat ligature wider than one unit, conflicts with fontconfig-mono: \[cldef.unicode.toString 16]"
|
|
|
|
glyphStore.addGlyph g1Name g1
|
|
glyphStore.encodeGlyph cldef.unicode g1
|
|
set GDEF.glyphClassDef.(g1Name) GDEF_LIGATURE
|