Prevent pathological geometry produced in phonetic ligatures (#1565, #1566).

This commit is contained in:
be5invis 2023-02-25 06:06:03 -08:00
parent 6a307b5973
commit 3607318795
7 changed files with 29 additions and 21 deletions

View file

@ -1 +1,2 @@
* Add variants for partial differential symbol (#1503).
* Prevent pathological geometry produced in phonetic ligatures (#1565, #1566).

View file

@ -146,7 +146,7 @@ class QuadifySink {
c = this.alignHVKnots(c);
c = this.cleanupOccurrentKnots1(c);
c = this.removeColinearKnots(c);
this.contours.push(c);
if (c.length > 2) this.contours.push(c);
}
this.lastContour = [];
}

View file

@ -1256,18 +1256,23 @@ glyph-block Autobuild-Pnonetic-Ligatures : begin
local df1 : CreateDerivedFontFromJobs jobs {} : lambda [gs] : Thinner gs shrink1 true
local df2 : CreateDerivedFontFromJobs jobs {} : lambda [gs] : Thinner gs shrink2 true
# TODO: we need a better geometry to do such minkovski sums
define [createMaskout c1 c2 s] : begin
define dfg1 : df1.queryByNameEnsured c1
define dfg2 : df2.queryByNameEnsured c2
return : WithTransform [Translate (s + dfg1.advanceWidth * wadj1 - kern) 0] dfg2
foreach [{gn unicode { c1 c2 } mak} : items-of jobs.nonDecomposable] : if [not : query-glyph gn] : begin
local maskOuts {}
local s 0
local step (-OX)
local s step
local dist (Stroke * 2)
while (s < dist) : do
maskOuts.push : new-glyph : glyph-proc
define dfg1 : df1.queryByNameEnsured c1
define dfg2 : df2.queryByNameEnsured c2
include dfg2
include : Translate (s + dfg1.advanceWidth * wadj1 - kern) 0
local maskOuts : list
createMaskout c1 c2 0.1
createMaskout c1 c2 (dist - 0.1)
while (s < dist) : begin
maskOuts.push : createMaskout c1 c2 s
set s : s + step
create-glyph gn unicode : glyph-proc
@ -1281,7 +1286,8 @@ glyph-block Autobuild-Pnonetic-Ligatures : begin
include : Translate (dfg1.advanceWidth * wadj1 - kern) 0
local leftHalf : intersection dfg1
Rect (CAP * 2) (Descender * 2) (-CWidth) (dfg1.advanceWidth * wadj1 - kern + dfg2.advanceWidth * wadj2 / 2)
include : difference.apply null { leftHalf :: maskOuts}
include leftHalf
# include : difference.apply null { leftHalf :: maskOuts }
include : Ungizmo
include : Translate (-refW / 2) 0
include : Scale [clamp 0 1 ((CWidth - SB * 1.25) / (CWidth - SB * 2) * CWidth / refW)] 1

View file

@ -411,6 +411,7 @@ glyph-block Autobuild-Transformed : begin
list 0x1E046 'cyrl/sha'
list 0x1E047 'cyrl/yery'
list 0x1E048 'cyrl/e'
list 0x1E049 'cyrl/yu'
list 0x1E04B 'cyrl/schwa'
list 0x1E04C 'cyrl/Ukrainiani'
list 0x1E04D 'cyrl/je'

14
package-lock.json generated
View file

@ -21,7 +21,7 @@
"wawoff2": "^2.0.1"
},
"devDependencies": {
"@unicode/unicode-14.0.0": "^1.3.1",
"@unicode/unicode-15.0.0": "^1.3.1",
"cldr": "^7.3.0",
"eslint": "^8.34.0",
"eslint-config-prettier": "^8.6.0",
@ -662,10 +662,10 @@
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
"dev": true
},
"node_modules/@unicode/unicode-14.0.0": {
"node_modules/@unicode/unicode-15.0.0": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@unicode/unicode-14.0.0/-/unicode-14.0.0-1.3.1.tgz",
"integrity": "sha512-VUfD/m7AK1VeJ46Y6iR5qRWLsnf8GYbl83MkRNQqVBSK3k05Xpax3emDtA14g8vjmW0vg0r1nf8n3fSnQciM3Q==",
"resolved": "https://registry.npmjs.org/@unicode/unicode-15.0.0/-/unicode-15.0.0-1.3.1.tgz",
"integrity": "sha512-zxm5Cx0v9vGxFOM8tVuArWHxxJTk+stiLA+ZHKt2mJO3HHmM6uN8OFcDGuvcix3MqguQ75am0XvpUgEz4P4vFw==",
"dev": true
},
"node_modules/@xmldom/xmldom": {
@ -4376,10 +4376,10 @@
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
"dev": true
},
"@unicode/unicode-14.0.0": {
"@unicode/unicode-15.0.0": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@unicode/unicode-14.0.0/-/unicode-14.0.0-1.3.1.tgz",
"integrity": "sha512-VUfD/m7AK1VeJ46Y6iR5qRWLsnf8GYbl83MkRNQqVBSK3k05Xpax3emDtA14g8vjmW0vg0r1nf8n3fSnQciM3Q==",
"resolved": "https://registry.npmjs.org/@unicode/unicode-15.0.0/-/unicode-15.0.0-1.3.1.tgz",
"integrity": "sha512-zxm5Cx0v9vGxFOM8tVuArWHxxJTk+stiLA+ZHKt2mJO3HHmM6uN8OFcDGuvcix3MqguQ75am0XvpUgEz4P4vFw==",
"dev": true
},
"@xmldom/xmldom": {

View file

@ -21,7 +21,7 @@
"deep-equal": "^2.2.0"
},
"devDependencies": {
"@unicode/unicode-14.0.0": "^1.3.1",
"@unicode/unicode-15.0.0": "^1.3.1",
"cldr": "^7.3.0",
"eslint": "^8.34.0",
"eslint-config-prettier": "^8.6.0",
@ -34,4 +34,4 @@
"engines": {
"node": ">=16.0.0"
}
}
}

View file

@ -7,14 +7,14 @@ export async function collectBlockData() {
// Missing ranges in UnicodeDataIndex
[[0x10780, 0x107bf], "Latin Extended-F"],
[[0x1df00, 0x1dfff], "Latin Extended-G"],
[[0x1e030, 0x1e08f], "Cyrillic Extended-D"]
[[0x1e030, 0x1e08f], "Cyrillic Extended-D"],
[[0x1fa70, 0x1faff], "Symbols and Pictographs Extended-A "],
[[0x1fb00, 0x1fbff], "Symbols for Legacy Computing"]
];
for (const id of UnicodeDataIndex.Block) {
if (!id || /Private_Use_Area/.test(id) || /undefined/.test(id)) continue;
const rangesModule = await import(`@unicode/unicode-14.0.0/Block/${id}/ranges.js`);
const rangesModule = await import(`@unicode/unicode-15.0.0/Block/${id}/ranges.js`);
const rg = rangesModule.default;
BlockData.push([[rg[0].begin, rg[0].end - 1], id.replace(/_/g, " ")]);
}