Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
be5invis committed Nov 21, 2020
2 parents 922ca29 + 7117316 commit 9eff02f
Show file tree
Hide file tree
Showing 125 changed files with 437 additions and 342 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
## Modifications since version 2.x

### 4.0.0-beta.3

* \[**Breaking**\] Added variant `r/earless-corner-serifed` and `r/earless-rounded-serifed`; Reordered `r`'s variant ranking and renamed `r/straight` to `r/serifless` (#742).
* Fix variant application of fraction 1/10 (U+2152, #736).
* Make variant application effective on LATIN SMALL LETTER WITH STROKE (U+0167, #737).
* Updated readme to reflect change in spacing parameter `force-monospace` to `fontconfig-mono`.
* Made check and cross marks wide-aware.


### 4.0.0-beta.2

* [**Breaking**] Reorder and reorganize character variants of `i`, `l`, and `f`, including:
Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,12 +313,12 @@ Configuration of build plans are organized under `[buildPlans.<plan name>]` sect
* `family`: String, defines the family name of your custom variant.
* `spacing`: Optional, String, denotes the spacing of the custom variant. Valid values include:
- `term`: Make the symbols' width suitable for terminal emulators. Arrows and geometric symbols ill become narrower.
- `force-monospace`: Apply `term` spacing changes and further:
- `fontconfig-mono`: Apply `term` spacing changes and further:
- Completely remove wide glyphs. All non-combining glyphs will be exactly the same width.
- Remove `NWID` and `WWID` OpenType feature.

This spacing is recommended for Linux users who customize for their terminal fonts: certain applications, including FontConfig, recognizes a font as monospace if and only if its every non-combining glyphs having the same width.
- `fixed`: Apply `force-monospace` changes and remove ligations.
- `fixed`: Apply `fontconfig-mono` changes and remove ligations.
* `serifs`: Optional, String, configures style of serifs.
- When set to `slab`, the font will be converted into slab-serif.
- Otherwise the font will be sans-serif.
Expand Down Expand Up @@ -590,11 +590,13 @@ Subsection `variants` is used to configure character variants in the font. Prope
+ `q = 'earless-rounded'`, `cv25 = 5`: Earless (rounded top-left) single-storey `q`.
+ `q = 'earless-rounded-tailed'`, `cv25 = 6`: Earless (rounded top-left) single-storey `q` with curly tail.
- Styles for `r`:
+ `r = 'straight'`, `cv26 = 1`: Straight, serif-less `r` (default for Sans).
+ `r = 'serifless'`, `cv26 = 1`: Straight, serif-less `r` (default for Sans).
+ `r = 'serifed'`, `cv26 = 2`: `r` with serif at both top and bottom (default for Slab Upright).
+ `r = 'top-serifed'`, `cv26 = 3`: `r` with serifs at top-left only (default for Slab Italic).
+ `r = 'earless-corner'`, `cv26 = 4`: Earless (corner top-left), serif-less `r`.
+ `r = 'earless-rounded'`, `cv26 = 5`: Earless (rounded top-left), serif-less `r`.
+ `r = 'earless-corner-serifed'`, `cv26 = 5`: Earless (corner top-left), serifed `r`.
+ `r = 'earless-rounded'`, `cv26 = 6`: Earless (rounded top-left), serif-less `r`.
+ `r = 'earless-rounded-serifed'`, `cv26 = 7`: Earless (rounded top-left), serifed `r`.
- Styles for `t`:
+ `t = 'standard'`, `cv27 = 1`: Standard `t` shape (default).
+ `t = 'cross'`, `cv27 = 2`: Futura-like `t` shape.
Expand Down
2 changes: 1 addition & 1 deletion build-plans.toml
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ j = 'flat-hook-serifed'
capital-i = 'serifed'
capital-j = 'serifed'
g = 'singlestorey'
r = 'straight'
r = 'serifless'
a = 'doublestorey'
d = 'toothed'
u = 'toothed'
Expand Down
5 changes: 5 additions & 0 deletions changes/4.0.0-beta.3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
* \[**Breaking**\] Added variant `r/earless-corner-serifed` and `r/earless-rounded-serifed`; Reordered `r`'s variant ranking and renamed `r/straight` to `r/serifless` (#742).
* Fix variant application of fraction 1/10 (U+2152, #736).
* Make variant application effective on LATIN SMALL LETTER WITH STROKE (U+0167, #737).
* Updated readme to reflect change in spacing parameter `force-monospace` to `fontconfig-mono`.
* Made check and cross marks wide-aware.
50 changes: 27 additions & 23 deletions font-src/gen/finalize/gc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ function markLookups(table, sink) {
let sizeBefore = sink.size;
for (const l of Array.from(sink)) {
const lookup = table.lookups[l];
if (!lookup || !lookup.subtables) continue;
if (!lookup) continue;
if (lookup.type === "gsub_chaining" || lookup.type === "gpos_chaining") {
for (let st of lookup.subtables) {
for (let st of lookup.rules) {
if (!st || !st.apply) continue;
for (const app of st.apply) sink.add(app.lookup);
}
Expand Down Expand Up @@ -91,56 +91,60 @@ function markGlyphsStep(glyphStore, sink, restFont, cfg) {
if (restFont.GSUB) {
for (const l in restFont.GSUB.lookups) {
const lookup = restFont.GSUB.lookups[l];
if (!lookup || !lookup.subtables) continue;
for (let st of lookup.subtables) {
markGlyphsSubtable(sink, lookup.type, st, cfg);
}
if (!lookup) continue;
markGlyphsLookupImpl(sink, lookup, cfg);
}
}
const glyphCount1 = sink.size;
return glyphCount1 > glyphCount;
}

function markGlyphsSubtable(sink, type, st, cfg) {
switch (type) {
function markGlyphsLookupImpl(sink, lookup, cfg) {
switch (lookup.type) {
case "gsub_single":
return markGlyphsGsubSingle(sink, st, cfg);
return markGlyphsGsubSingle(sink, lookup, cfg);
case "gsub_multiple":
return markGlyphsGsubMultiple(sink, st, cfg);
return markGlyphsGsubMultiple(sink, lookup, cfg);
case "gsub_alternate":
return markGlyphsGsubAlternate(sink, st, cfg);
return markGlyphsGsubAlternate(sink, lookup, cfg);
case "gsub_ligature":
return markGlyphsGsubLigature(sink, st, cfg);
return markGlyphsGsubLigature(sink, lookup, cfg);
case "gsub_chaining":
break;
case "gsub_reverse":
return markGlyphsGsubReverse(sink, st, cfg);
return markGlyphsGsubReverse(sink, lookup, cfg);
}
}

function markGlyphsGsubSingle(sink, st, cfg) {
function markGlyphsGsubSingle(sink, lookup, cfg) {
const st = lookup.substitutions;
for (const k in st) if (sink.has(k) && st[k]) sink.add(st[k]);
}
function markGlyphsGsubMultiple(sink, st, cfg) {
function markGlyphsGsubMultiple(sink, lookup, cfg) {
const st = lookup.substitutions;
for (const k in st) if (sink.has(k) && st[k]) for (const g of st[k]) sink.add(g);
}
function markGlyphsGsubAlternate(sink, st, cfg) {
function markGlyphsGsubAlternate(sink, lookup, cfg) {
const st = lookup.substitutions;
if (!cfg || !cfg.ignoreAltSub) {
for (const k in st) if (sink.has(k) && st[k]) for (const g of st[k]) sink.add(g);
}
}
function markGlyphsGsubLigature(sink, st, cfg) {
for (const sub of st.substitutions) {
function markGlyphsGsubLigature(sink, lookup, cfg) {
const st = lookup.substitutions;
for (const sub of st) {
let check = true;
for (const g of sub.from) if (!sink.has(g)) check = false;
if (check && sub.to) sink.add(sub.to);
}
}
function markGlyphsGsubReverse(sink, st, cfg) {
if (st.match && st.to) {
const matchCoverage = st.match[st.inputIndex];
for (let j = 0; j < matchCoverage.length; j++) {
if (sink.has(matchCoverage[j]) && st.to[j]) sink.add(st.to[j]);
function markGlyphsGsubReverse(sink, lookup, cfg) {
for (const rule of lookup.rules) {
if (rule.match && rule.to) {
const matchCoverage = rule.match[rule.inputIndex];
for (let j = 0; j < matchCoverage.length; j++) {
if (sink.has(matchCoverage[j]) && rule.to[j]) sink.add(rule.to[j]);
}
}
}
}
Expand Down
57 changes: 26 additions & 31 deletions font-src/gen/otd-conv/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class LookupStore {
const dst = this.query(id);
const handler = this.m_handlers[otdLookup.type];
if (!dst || !handler) return;

if (otdLookup.subtables) throw new Error("Unreachable.");
handler.fill(dst, otdLookup, this);
}
}
Expand All @@ -33,12 +33,11 @@ const GsubSingleHandler = {
return new Ot.Gsub.Single();
},
fill(dst, src, store) {
for (const st of src.subtables) {
for (const k in st) {
const from = store.glyphs.query(k);
const to = store.glyphs.query(st[k]);
if (from && to) dst.mapping.set(from, to);
}
const st = src.substitutions;
for (const k in st) {
const from = store.glyphs.query(k);
const to = store.glyphs.query(st[k]);
if (from && to) dst.mapping.set(from, to);
}
}
};
Expand All @@ -47,13 +46,12 @@ const GsubMultipleHandler = {
return new Ot.Gsub.Multiple();
},
fill(dst, src, store) {
for (const st of src.subtables) {
out: for (const k in st) {
const from = store.glyphs.query(k);
const to = mapGlyphListAll(st[k], store);
if (!from || !to) continue out;
dst.mapping.set(from, to);
}
const st = src.substitutions;
for (const k in st) {
const from = store.glyphs.query(k);
const to = mapGlyphListAll(st[k], store);
if (!from || !to) continue;
dst.mapping.set(from, to);
}
}
};
Expand All @@ -68,13 +66,12 @@ const GsubLigatureHandler = {
return new Ot.Gsub.Ligature();
},
fill(dst, src, store) {
for (const st of src.subtables) {
for (const { from: _from, to: _to } of st.substitutions) {
const to = store.glyphs.query(_to);
const from = mapGlyphListAll(_from, store);
if (!from || !to) continue;
dst.mapping.push({ from, to });
}
const st = src.substitutions;
for (const { from: _from, to: _to } of st) {
const to = store.glyphs.query(_to);
const from = mapGlyphListAll(_from, store);
if (!from || !to) continue;
dst.mapping.push({ from, to });
}
}
};
Expand All @@ -84,7 +81,7 @@ const GsubChainingHandler = {
return new Ot.Gsub.Chaining();
},
fill(dst, src, store) {
out: for (const st of src.subtables) {
out: for (const st of src.rules) {
const match = [];
for (const m of st.match) {
const m1 = mapGlyphListSome(m, store);
Expand All @@ -109,7 +106,7 @@ const GsubReverseHandler = {
return new Ot.Gsub.ReverseSub();
},
fill(dst, src, store) {
out: for (const st of src.subtables) {
out: for (const st of src.rules) {
const match = [];
const doSubAt = st.inputIndex;
const replacement = new Map();
Expand Down Expand Up @@ -176,21 +173,19 @@ const GposMarkToBaseHandler = {
return new Ot.Gpos.MarkToBase();
},
fill(dst, src, store) {
const st = src.subtables[0];
const mm = collectClassMap(st.marks);
dst.marks = convertMarkRecords(st.marks, mm, store);
dst.bases = convertBaseRecords(st.bases, mm, store);
const mm = collectClassMap(src.marks);
dst.marks = convertMarkRecords(src.marks, mm, store);
dst.bases = convertBaseRecords(src.bases, mm, store);
}
};
const GposMarkToMarkHandler = {
init() {
return new Ot.Gpos.MarkToMark();
},
fill(dst, src, store) {
const st = src.subtables[0];
const mm = collectClassMap(st.marks);
dst.marks = convertMarkRecords(st.marks, mm, store);
dst.baseMarks = convertBaseRecords(st.bases, mm, store);
const mm = collectClassMap(src.marks);
dst.marks = convertMarkRecords(src.marks, mm, store);
dst.baseMarks = convertBaseRecords(src.bases, mm, store);
}
};
function collectClassMap(marks) {
Expand Down
1 change: 1 addition & 0 deletions font-src/glyphs/auto-build/accents.ptl
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ define customDecompositions : object
."\u0123" "g\u0312"

# autobuild Latin glyphs
."\u0167" "t\u0335"
."\u0197" "I\u0335"
."\u019A" "l\u0335"
."\u0248" "J\u0335"
Expand Down
25 changes: 17 additions & 8 deletions font-src/glyphs/auto-build/composite.ptl
Original file line number Diff line number Diff line change
Expand Up @@ -728,31 +728,40 @@ glyph-block Autobuild-Fractions : if [not recursive] : begin
include : Translate (-Width) 0
return gnn

define [denumeratorImpl denid] : begin
local gnd ".frac-den-\(prefix){\(denid)}"
define [denumeratorImplT offset] : lambda [denid] : begin
local gnd ".frac-den-\(prefix){\(denid)}{\(offset)}"
if [not : query-glyph gnd] : create-glyph gnd : glyph-proc
define mfDenGlyph : miniatureFont.queryByNameEnsured denid

set-width 0
include mfDenGlyph
include : Upright
include : Translate (- mfDenGlyph.advanceWidth / 2) 0
include : Translate offset 0
include : Scale scaleFactor
include : Translate Middle (SymbolMid - CAP * scaleFactor - dist / 2)
include : Italify
include : Translate (-Width) 0
return gnd

define [createFractionImpl job jobDecomposable] : begin
local {gnf unicode {numid denid}} job
local {gnf unicode {numid :: denidList}} job
local gnn : EnsureComponentGlyphT numid numeratorImpl
local gnd : EnsureComponentGlyphT denid denumeratorImpl
local gndList {}

local totalDenWidth 0
local offset 0
foreach denid [items-of denidList] : begin
set totalDenWidth : totalDenWidth + [miniatureFont.queryByNameEnsured denid].advanceWidth
foreach denid [items-of denidList] : begin
gndList.push : EnsureComponentGlyphT denid : denumeratorImplT (offset - totalDenWidth / 2)
set offset : offset + [miniatureFont.queryByNameEnsured denid].advanceWidth

if [not : query-glyph gnf] : create-glyph gnf unicode : glyph-proc
include : refer-glyph gnn
include : refer-glyph gnd
foreach gnd [items-of gndList] : include : refer-glyph gnd
include : Translate (Width) 0
include : refer-glyph gnFractionBar
if jobDecomposable : CvDecompose.set currentGlyph { gnFractionBar gnn gnd }
if jobDecomposable : CvDecompose.set currentGlyph { gnFractionBar gnn :: gndList }

create-glyph gnFractionBar : glyph-proc
set-width Width
Expand All @@ -772,7 +781,7 @@ glyph-block Autobuild-Fractions : if [not recursive] : begin
list 0x00BE { 'three.lnum' 'four.lnum' }
list 0x2150 { 'one.lnum' 'seven.lnum' }
list 0x2151 { 'one.lnum' 'nine.lnum' }
list 0x2152 { 'one.lnum' 'numbers/ten{one.lnum}{zero.lnum}' }
list 0x2152 { 'one.lnum' 'one.lnum' 'zero.lnum' }
list 0x2153 { 'one.lnum' 'three.lnum' }
list 0x2154 { 'two.lnum' 'three.lnum' }
list 0x2155 { 'one.lnum' 'five.lnum' }
Expand Down

0 comments on commit 9eff02f

Please sign in to comment.