diff --git a/README.md b/README.md index 3b25e9026..05b589b04 100644 --- a/README.md +++ b/README.md @@ -195,7 +195,7 @@ Since version 2.0, Iosevka would no longer support building via `makefile`. To i - + 3. Run `npm run build -- contents::` and the built fonts would be avaliable in `dist/`. Aside from `contents::`, other options are: diff --git a/changes/3.2.2.md b/changes/3.2.2.md new file mode 100644 index 000000000..778ec8b89 --- /dev/null +++ b/changes/3.2.2.md @@ -0,0 +1 @@ + * Fix broken ligation of kerning colons and dot-related symbols. \ No newline at end of file diff --git a/gen/finalize/gc.js b/gen/finalize/gc.js index 5bdbd4af3..82761ed9a 100644 --- a/gen/finalize/gc.js +++ b/gen/finalize/gc.js @@ -7,6 +7,54 @@ module.exports = function gcFont(gs, excludedChars, restFont, cfg) { sweep(gs, restFont, sink); }; +function markSweepOtl(table) { + if (!table || !table.features || !table.lookups) return; + const accessibleLookupsIds = new Set(); + markLookups(table, accessibleLookupsIds); + let lookups1 = {}; + for (const l in table.lookups) { + if (accessibleLookupsIds.has(l)) lookups1[l] = table.lookups[l]; + } + table.lookups = lookups1; + + let features1 = {}; + for (let f in table.features) { + const feature = table.features[f]; + if (!feature) continue; + const featureFiltered = []; + for (const l of feature) if (accessibleLookupsIds.has(l)) featureFiltered.push(l); + if (!featureFiltered.length) continue; + features1[f] = featureFiltered; + } + table.features = features1; +} +function markLookups(table, sink) { + if (!table || !table.features) return; + for (let f in table.features) { + const feature = table.features[f]; + if (!feature) continue; + for (const l of feature) sink.add(l); + } + let loop = 0, + lookupSetChanged = false; + do { + lookupSetChanged = false; + let sizeBefore = sink.size; + for (const l of Array.from(sink)) { + const lookup = table.lookups[l]; + if (!lookup || !lookup.subtables) continue; + if (lookup.type === "gsub_chaining" || lookup.type === "gpos_chaining") { + for (let st of lookup.subtables) { + if (!st || !st.apply) continue; + for (const app of st.apply) sink.add(app.lookup); + } + } + } + loop++; + lookupSetChanged = sizeBefore !== sink.size; + } while (loop < 0xff && lookupSetChanged); +} + function mark(gs, excludedChars, restFont, cfg) { const sink = markInitial(gs, excludedChars); while (markStep(sink, restFont, cfg)); @@ -25,72 +73,19 @@ function markInitial(gs, excludedChars) { function markStep(sink, restFont, cfg) { const glyphCount = sink.size; - if (restFont.GSUB) { for (const l in restFont.GSUB.lookups) { const lookup = restFont.GSUB.lookups[l]; if (!lookup || !lookup.subtables) continue; - if (lookup && lookup.subtables) { - for (let st of lookup.subtables) { - markSubtable(sink, lookup.type, st, cfg); - } + for (let st of lookup.subtables) { + markSubtable(sink, lookup.type, st, cfg); } } } - const glyphCount1 = sink.size; return glyphCount1 > glyphCount; } -function markSweepOtl(table) { - if (!table || !table.features || !table.lookups) return; - const accessibleLookupsIds = new Set(); - markLookups(table, accessibleLookupsIds); - - let lookups1 = {}; - for (const l in table.lookups) { - if (accessibleLookupsIds.has(l)) lookups1[l] = table.lookups[l]; - } - table.lookups = lookups1; - - let features1 = {}; - for (let f in table.features) { - const feature = table.features[f]; - if (!feature) continue; - const featureFiltered = []; - for (const l of feature) if (accessibleLookupsIds.has(l)) featureFiltered.push(l); - if (!featureFiltered.length) continue; - features1[f] = featureFiltered; - } - table.features = features1; -} -function markLookups(gsub, sink) { - if (!gsub || !gsub.features) return; - for (let f in gsub.features) { - const feature = gsub.features[f]; - if (!feature) continue; - for (const l of feature) sink.add(l); - } - let loop = 0, - lookupSetChanged = false; - do { - lookupSetChanged = false; - let sizeBefore = sink.size; - for (const l of Array.from(sink)) { - const lookup = gsub.lookups[l]; - if (!lookup || !lookup.subtables) continue; - if (lookup.type === "gsub_chaining" || lookup.type === "gpos_chaining") { - for (let st of lookup.subtables) { - if (!st || !st.apply) continue; - for (const app of st.apply) sink.add(app.lookup); - } - } - } - loop++; - lookupSetChanged = sizeBefore !== sink.size; - } while (loop < 0xff && lookupSetChanged); -} - function markSubtable(sink, type, st, cfg) { switch (type) { case "gsub_single": @@ -143,24 +138,109 @@ function sweepOtl(gsub, sink) { } } -function sweepSubtable(st, type, sink) { +function sweepSubtable(st, type, gs) { switch (type) { - case "gsub_ligature": { - if (!st.substitutions) return false; - let newSubst = []; - for (const rule of st.substitutions) { - let include = true; - if (!sink.has(rule.to)) include = false; - for (const from of rule.from) if (!sink.has(from)) include = false; - if (include) newSubst.push(rule); - } - st.substitutions = newSubst; - return true; - } - default: { + case "gsub_single": + return sweep_GsubSingle(st, gs); + case "gsub_multiple": + return sweep_GsubMultiple(st, gs); + case "gsub_ligature": + return sweep_GsubLigature(st, gs); + case "gsub_chaining": + return sweep_GsubChaining(st, gs); + case "gsub_reverse": + return sweep_gsubReverse(st, gs); + default: return true; + } +} + +function sweep_GsubSingle(st, gs) { + let nonEmpty = false; + let from = Object.keys(st); + for (const gidFrom of from) { + if (!gs.has(gidFrom) || !gs.has(st[gidFrom])) { + delete st[gidFrom]; + } else { + nonEmpty = true; } } + return nonEmpty; +} + +function sweep_GsubMultiple(st, gs) { + let nonEmpty = false; + let from = Object.keys(st); + for (const gidFrom of from) { + let include = gs.has(gidFrom); + if (st[gidFrom]) { + for (const gidTo of st[gidFrom]) { + include = include && gs.has(gidTo); + } + } else { + include = false; + } + if (!include) { + delete st[gidFrom]; + } else { + nonEmpty = true; + } + } + return nonEmpty; +} + +function sweep_GsubLigature(st, gs) { + if (!st.substitutions) return false; + let newSubst = []; + for (const rule of st.substitutions) { + let include = true; + if (!gs.has(rule.to)) include = false; + for (const from of rule.from) if (!gs.has(from)) include = false; + if (include) newSubst.push(rule); + } + st.substitutions = newSubst; + return true; +} + +function sweep_GsubChaining(st, gs) { + const newMatch = []; + for (let j = 0; j < st.match.length; j++) { + newMatch[j] = []; + for (let k = 0; k < st.match[j].length; k++) { + const gidFrom = st.match[j][k]; + if (gs.has(gidFrom)) { + newMatch[j].push(gidFrom); + } + } + if (!newMatch[j].length) return false; + } + st.match = newMatch; + return true; +} + +function sweep_gsubReverse(st, gs) { + const newMatch = [], + newTo = []; + for (let j = 0; j < st.match.length; j++) { + newMatch[j] = []; + for (let k = 0; k < st.match[j].length; k++) { + const gidFrom = st.match[j][k]; + let include = gs.has(gidFrom); + if (j === st.inputIndex) { + include = include && gs.has(st.to[k]); + if (include) { + newMatch[j].push(gidFrom); + newTo.push(st.to[k]); + } + } else { + if (include) newMatch[j].push(gidFrom); + } + } + if (!newMatch[j].length) return false; + } + st.match = newMatch; + st.to = newTo; + return true; } function filterInPlace(a, condition) { diff --git a/glyphs/symbol-punctuation.ptl b/glyphs/symbol-punctuation.ptl index 0d230465e..a1b677d83 100644 --- a/glyphs/symbol-punctuation.ptl +++ b/glyphs/symbol-punctuation.ptl @@ -1602,7 +1602,7 @@ glyph-block Symbol-Punctuation-Ties : begin g4 (RightSB - OX) 0 save "undertie" 0x203F -glyph-block Symbol-Punctuation-Ligation Variants : begin +glyph-block Symbol-Punctuation-Ligation-Variants : begin glyph-block-import CommonShapes glyph-block-import Overmarks diff --git a/images/charvars.png b/images/charvars.png index fb5cb40c3..0300343ef 100644 Binary files a/images/charvars.png and b/images/charvars.png differ diff --git a/images/iosevka-aile.png b/images/iosevka-aile.png index 8de4c0730..7332863a5 100644 Binary files a/images/iosevka-aile.png and b/images/iosevka-aile.png differ diff --git a/images/iosevka-curly-slab.png b/images/iosevka-curly-slab.png index 1c77c129b..49e3d2447 100644 Binary files a/images/iosevka-curly-slab.png and b/images/iosevka-curly-slab.png differ diff --git a/images/iosevka-curly.png b/images/iosevka-curly.png index 96d7ebdcc..620ae9b4d 100644 Binary files a/images/iosevka-curly.png and b/images/iosevka-curly.png differ diff --git a/images/iosevka-etoile.png b/images/iosevka-etoile.png index c94dd204f..e9b09d18a 100644 Binary files a/images/iosevka-etoile.png and b/images/iosevka-etoile.png differ diff --git a/images/iosevka-fixed-curly-slab.png b/images/iosevka-fixed-curly-slab.png index 82bd1693b..b66803c27 100644 Binary files a/images/iosevka-fixed-curly-slab.png and b/images/iosevka-fixed-curly-slab.png differ diff --git a/images/iosevka-fixed-curly.png b/images/iosevka-fixed-curly.png index 5b6e29106..817d97a15 100644 Binary files a/images/iosevka-fixed-curly.png and b/images/iosevka-fixed-curly.png differ diff --git a/images/iosevka-fixed-slab.png b/images/iosevka-fixed-slab.png index 0bd7b143e..60820ae04 100644 Binary files a/images/iosevka-fixed-slab.png and b/images/iosevka-fixed-slab.png differ diff --git a/images/iosevka-fixed-ss01.png b/images/iosevka-fixed-ss01.png index 9a556ba7a..8bb2d5163 100644 Binary files a/images/iosevka-fixed-ss01.png and b/images/iosevka-fixed-ss01.png differ diff --git a/images/iosevka-fixed-ss02.png b/images/iosevka-fixed-ss02.png index 4b8384eff..721672a47 100644 Binary files a/images/iosevka-fixed-ss02.png and b/images/iosevka-fixed-ss02.png differ diff --git a/images/iosevka-fixed-ss03.png b/images/iosevka-fixed-ss03.png index 9fe97fa8c..330687b00 100644 Binary files a/images/iosevka-fixed-ss03.png and b/images/iosevka-fixed-ss03.png differ diff --git a/images/iosevka-fixed-ss04.png b/images/iosevka-fixed-ss04.png index 357485d55..2de9c4aad 100644 Binary files a/images/iosevka-fixed-ss04.png and b/images/iosevka-fixed-ss04.png differ diff --git a/images/iosevka-fixed-ss05.png b/images/iosevka-fixed-ss05.png index a8f5823d5..6eb5864e4 100644 Binary files a/images/iosevka-fixed-ss05.png and b/images/iosevka-fixed-ss05.png differ diff --git a/images/iosevka-fixed-ss06.png b/images/iosevka-fixed-ss06.png index 7d7c6ddf8..6b1efcd70 100644 Binary files a/images/iosevka-fixed-ss06.png and b/images/iosevka-fixed-ss06.png differ diff --git a/images/iosevka-fixed-ss07.png b/images/iosevka-fixed-ss07.png index b3ee686c4..e7fc1fb19 100644 Binary files a/images/iosevka-fixed-ss07.png and b/images/iosevka-fixed-ss07.png differ diff --git a/images/iosevka-fixed-ss08.png b/images/iosevka-fixed-ss08.png index 8133211bc..68d2e00d2 100644 Binary files a/images/iosevka-fixed-ss08.png and b/images/iosevka-fixed-ss08.png differ diff --git a/images/iosevka-fixed-ss09.png b/images/iosevka-fixed-ss09.png index 7d02c021b..ade3578a2 100644 Binary files a/images/iosevka-fixed-ss09.png and b/images/iosevka-fixed-ss09.png differ diff --git a/images/iosevka-fixed-ss10.png b/images/iosevka-fixed-ss10.png index aca22d991..ade690dc5 100644 Binary files a/images/iosevka-fixed-ss10.png and b/images/iosevka-fixed-ss10.png differ diff --git a/images/iosevka-fixed-ss11.png b/images/iosevka-fixed-ss11.png index a77e8b73e..004a15586 100644 Binary files a/images/iosevka-fixed-ss11.png and b/images/iosevka-fixed-ss11.png differ diff --git a/images/iosevka-fixed-ss12.png b/images/iosevka-fixed-ss12.png index 25d6f6d9a..4aa860bc9 100644 Binary files a/images/iosevka-fixed-ss12.png and b/images/iosevka-fixed-ss12.png differ diff --git a/images/iosevka-fixed-ss13.png b/images/iosevka-fixed-ss13.png index 8797ba21c..12a582a7b 100644 Binary files a/images/iosevka-fixed-ss13.png and b/images/iosevka-fixed-ss13.png differ diff --git a/images/iosevka-fixed-ss14.png b/images/iosevka-fixed-ss14.png index 725c7c7e0..07524f42d 100644 Binary files a/images/iosevka-fixed-ss14.png and b/images/iosevka-fixed-ss14.png differ diff --git a/images/iosevka-fixed.png b/images/iosevka-fixed.png index 377e19a1e..2def611c2 100644 Binary files a/images/iosevka-fixed.png and b/images/iosevka-fixed.png differ diff --git a/images/iosevka-slab.png b/images/iosevka-slab.png index 29b26f423..b37691c44 100644 Binary files a/images/iosevka-slab.png and b/images/iosevka-slab.png differ diff --git a/images/iosevka-sparkle.png b/images/iosevka-sparkle.png index c7c89f502..769410f6d 100644 Binary files a/images/iosevka-sparkle.png and b/images/iosevka-sparkle.png differ diff --git a/images/iosevka-ss01.png b/images/iosevka-ss01.png index 0980d3322..fe3a38b6b 100644 Binary files a/images/iosevka-ss01.png and b/images/iosevka-ss01.png differ diff --git a/images/iosevka-ss02.png b/images/iosevka-ss02.png index d34ca25b8..7aabf0267 100644 Binary files a/images/iosevka-ss02.png and b/images/iosevka-ss02.png differ diff --git a/images/iosevka-ss03.png b/images/iosevka-ss03.png index 1f7a02e20..9bf6545c6 100644 Binary files a/images/iosevka-ss03.png and b/images/iosevka-ss03.png differ diff --git a/images/iosevka-ss04.png b/images/iosevka-ss04.png index 58b902abe..fb067a898 100644 Binary files a/images/iosevka-ss04.png and b/images/iosevka-ss04.png differ diff --git a/images/iosevka-ss05.png b/images/iosevka-ss05.png index e85d3de6c..9ffe92f79 100644 Binary files a/images/iosevka-ss05.png and b/images/iosevka-ss05.png differ diff --git a/images/iosevka-ss06.png b/images/iosevka-ss06.png index 86498c9ea..536c8d1ae 100644 Binary files a/images/iosevka-ss06.png and b/images/iosevka-ss06.png differ diff --git a/images/iosevka-ss07.png b/images/iosevka-ss07.png index a63d5ae21..971a09548 100644 Binary files a/images/iosevka-ss07.png and b/images/iosevka-ss07.png differ diff --git a/images/iosevka-ss08.png b/images/iosevka-ss08.png index 980a5419a..0c1e880fe 100644 Binary files a/images/iosevka-ss08.png and b/images/iosevka-ss08.png differ diff --git a/images/iosevka-ss09.png b/images/iosevka-ss09.png index 43574600d..a2c106d20 100644 Binary files a/images/iosevka-ss09.png and b/images/iosevka-ss09.png differ diff --git a/images/iosevka-ss10.png b/images/iosevka-ss10.png index b86fa6e5b..e22891fa2 100644 Binary files a/images/iosevka-ss10.png and b/images/iosevka-ss10.png differ diff --git a/images/iosevka-ss11.png b/images/iosevka-ss11.png index b032b7b86..7e9bca17b 100644 Binary files a/images/iosevka-ss11.png and b/images/iosevka-ss11.png differ diff --git a/images/iosevka-ss12.png b/images/iosevka-ss12.png index 43eb11fd7..cc18fb8f4 100644 Binary files a/images/iosevka-ss12.png and b/images/iosevka-ss12.png differ diff --git a/images/iosevka-ss13.png b/images/iosevka-ss13.png index 3884a60eb..d77aeee92 100644 Binary files a/images/iosevka-ss13.png and b/images/iosevka-ss13.png differ diff --git a/images/iosevka-ss14.png b/images/iosevka-ss14.png index 8481be691..4783d1257 100644 Binary files a/images/iosevka-ss14.png and b/images/iosevka-ss14.png differ diff --git a/images/iosevka-term-curly-slab.png b/images/iosevka-term-curly-slab.png index f5bd8d89a..f5226e9fb 100644 Binary files a/images/iosevka-term-curly-slab.png and b/images/iosevka-term-curly-slab.png differ diff --git a/images/iosevka-term-curly.png b/images/iosevka-term-curly.png index 119295cf5..a4faacfe3 100644 Binary files a/images/iosevka-term-curly.png and b/images/iosevka-term-curly.png differ diff --git a/images/iosevka-term-slab.png b/images/iosevka-term-slab.png index 266a8581f..15286fb90 100644 Binary files a/images/iosevka-term-slab.png and b/images/iosevka-term-slab.png differ diff --git a/images/iosevka-term-ss01.png b/images/iosevka-term-ss01.png index 35983a3a9..bba101fec 100644 Binary files a/images/iosevka-term-ss01.png and b/images/iosevka-term-ss01.png differ diff --git a/images/iosevka-term-ss02.png b/images/iosevka-term-ss02.png index cdf70987e..d7f696844 100644 Binary files a/images/iosevka-term-ss02.png and b/images/iosevka-term-ss02.png differ diff --git a/images/iosevka-term-ss03.png b/images/iosevka-term-ss03.png index 82ccb3afd..ba927202a 100644 Binary files a/images/iosevka-term-ss03.png and b/images/iosevka-term-ss03.png differ diff --git a/images/iosevka-term-ss04.png b/images/iosevka-term-ss04.png index 50d37a22c..c13bfce02 100644 Binary files a/images/iosevka-term-ss04.png and b/images/iosevka-term-ss04.png differ diff --git a/images/iosevka-term-ss05.png b/images/iosevka-term-ss05.png index 18915d237..2dcbc108e 100644 Binary files a/images/iosevka-term-ss05.png and b/images/iosevka-term-ss05.png differ diff --git a/images/iosevka-term-ss06.png b/images/iosevka-term-ss06.png index 2f6cd22dd..d4a9307b0 100644 Binary files a/images/iosevka-term-ss06.png and b/images/iosevka-term-ss06.png differ diff --git a/images/iosevka-term-ss07.png b/images/iosevka-term-ss07.png index ddb54de45..385627110 100644 Binary files a/images/iosevka-term-ss07.png and b/images/iosevka-term-ss07.png differ diff --git a/images/iosevka-term-ss08.png b/images/iosevka-term-ss08.png index 5cc2c361c..27b73cb66 100644 Binary files a/images/iosevka-term-ss08.png and b/images/iosevka-term-ss08.png differ diff --git a/images/iosevka-term-ss09.png b/images/iosevka-term-ss09.png index a156e2086..dd5b4a50b 100644 Binary files a/images/iosevka-term-ss09.png and b/images/iosevka-term-ss09.png differ diff --git a/images/iosevka-term-ss10.png b/images/iosevka-term-ss10.png index 415841f16..e5c37d5e8 100644 Binary files a/images/iosevka-term-ss10.png and b/images/iosevka-term-ss10.png differ diff --git a/images/iosevka-term-ss11.png b/images/iosevka-term-ss11.png index 64e55bfe2..d76fd019a 100644 Binary files a/images/iosevka-term-ss11.png and b/images/iosevka-term-ss11.png differ diff --git a/images/iosevka-term-ss12.png b/images/iosevka-term-ss12.png index 0b749106c..2a07922d6 100644 Binary files a/images/iosevka-term-ss12.png and b/images/iosevka-term-ss12.png differ diff --git a/images/iosevka-term-ss13.png b/images/iosevka-term-ss13.png index ca8305702..04a43e8c3 100644 Binary files a/images/iosevka-term-ss13.png and b/images/iosevka-term-ss13.png differ diff --git a/images/iosevka-term-ss14.png b/images/iosevka-term-ss14.png index bd0c72d42..40b6321bb 100644 Binary files a/images/iosevka-term-ss14.png and b/images/iosevka-term-ss14.png differ diff --git a/images/iosevka-term.png b/images/iosevka-term.png index 48404d410..4991f8113 100644 Binary files a/images/iosevka-term.png and b/images/iosevka-term.png differ diff --git a/images/iosevka.png b/images/iosevka.png index 7955f4512..3f3cd25f6 100644 Binary files a/images/iosevka.png and b/images/iosevka.png differ diff --git a/images/languages.png b/images/languages.png index c5ef74452..b03db0831 100644 Binary files a/images/languages.png and b/images/languages.png differ diff --git a/images/ligations.png b/images/ligations.png index 827ae9f0b..98cefe24e 100644 Binary files a/images/ligations.png and b/images/ligations.png differ diff --git a/images/matrix.png b/images/matrix.png index f796ebcce..faacf1ba6 100644 Binary files a/images/matrix.png and b/images/matrix.png differ diff --git a/images/preview-all.png b/images/preview-all.png index 7e139dcd4..f6293fb9d 100644 Binary files a/images/preview-all.png and b/images/preview-all.png differ diff --git a/images/stylesets.png b/images/stylesets.png index ecde61c8e..cbfde1add 100644 Binary files a/images/stylesets.png and b/images/stylesets.png differ diff --git a/images/weights.png b/images/weights.png index 83b46a1aa..ce0735a8a 100644 Binary files a/images/weights.png and b/images/weights.png differ diff --git a/package.json b/package.json index 6ec2e0aa4..ba4eea6d1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "iosevka", - "version": "3.2.1", + "version": "3.2.2", "main": "./generate.js", "scripts": { "build": "verda -f verdafile.js",