Iosevka/font-src/otl/compat-ligature.ptl
2022-07-16 19:26:49 -07:00

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