From 138c98855b48ca2ac966dd8d09728bb8043122a6 Mon Sep 17 00:00:00 2001 From: multipleof4 Date: Sun, 9 Nov 2025 13:23:09 -0800 Subject: [PATCH] Revert: Update build-font.js --- scripts/build-font.js | 189 +++--------------------------------------- 1 file changed, 12 insertions(+), 177 deletions(-) diff --git a/scripts/build-font.js b/scripts/build-font.js index b11c505..9da502b 100644 --- a/scripts/build-font.js +++ b/scripts/build-font.js @@ -40,10 +40,7 @@ const styleName="Regular"; const unitsPerEm=1000; const ascender=800; const descender=-200; -const defaultAdv=580; // slightly tighter default -const wideAdv=700; // for M/W/m/w -const spaceAdv=240; // tighter space -const periodAdv=220; // tighter period +const defaultAdv=600; const mkGlyph=(name,unicode,adv,pathFn)=> new opentype.Glyph({ @@ -53,23 +50,16 @@ const mkGlyph=(name,unicode,adv,pathFn)=> path:pathFn(new opentype.Path()) }); -const glyphSpace=mkGlyph( - "space", - " ".codePointAt(0), - spaceAdv, - p=>p -); - +const glyphSpace=mkGlyph("space"," ".codePointAt(0),260,p=>p); const glyphPeriod=mkGlyph( "period", ".".codePointAt(0), - periodAdv, + 260, p=>{ - const x=80,w=70,h=120; - p.moveTo(x,0); - p.lineTo(x,h); - p.lineTo(x+w,h); - p.lineTo(x+w,0); + p.moveTo(80,0); + p.lineTo(80,120); + p.lineTo(180,120); + p.lineTo(180,0); p.close(); return p; } @@ -102,8 +92,8 @@ const glyphList=[ glyphk(opentype,defaultAdv), glyphL(opentype,defaultAdv), glyphl(opentype,defaultAdv), - glyphM(opentype,wideAdv), - glyphm(opentype,wideAdv), + glyphM(opentype,740), + glyphm(opentype,740), glyphN(opentype,defaultAdv), glyphn(opentype,defaultAdv), glyphO(opentype,defaultAdv), @@ -122,8 +112,8 @@ const glyphList=[ glyphu(opentype,defaultAdv), glyphV(opentype,defaultAdv), glyphv(opentype,defaultAdv), - glyphW(opentype,wideAdv), - glyphw(opentype,wideAdv-40), + glyphW(opentype,760), + glyphw(opentype,660), glyphX(opentype,defaultAdv), glyphx(opentype,defaultAdv), glyphY(opentype,defaultAdv), @@ -142,163 +132,8 @@ const font=new opentype.Font({ copyright:"Author: Anon. License: CC0 1.0 Universal." }); -// basic kerning pairs (GPOS-based; opentype.js expects glyph indices) -const kernPairs=[ - ["A","V",-70], - ["A","W",-70], - ["A","Y",-70], - ["A","T",-50], - ["A","O",-25], - ["A","Q",-25], - ["V","A",-70], - ["V","O",-40], - ["V","a",-50], - ["V","o",-50], - ["V","e",-45], - ["V","u",-40], - ["W","A",-70], - ["W","O",-40], - ["W","a",-50], - ["W","o",-50], - ["W","e",-45], - ["W","u",-40], - ["Y","A",-80], - ["Y","O",-40], - ["Y","a",-70], - ["Y","o",-70], - ["Y","e",-65], - ["Y","u",-55], - ["T","A",-60], - ["T","O",-40], - ["T","a",-70], - ["T","o",-70], - ["T","e",-65], - ["T","u",-60], - ["T","y",-50], - ["L","T",-50], - ["L","V",-70], - ["L","W",-70], - ["L","Y",-80], - ["F","a",-45], - ["F","o",-45], - ["F","e",-40], - ["P","A",-70], - ["P","a",-40], - ["P","o",-40], - ["K","O",-40], - ["K","a",-40], - ["K","o",-40], - ["K","e",-35], - ["K","u",-35], - ["space","A",-20], - ["space","V",-15], - ["space","W",-15], - ["space","Y",-15] -]; - -const nameToIndex=name=>font.glyphs.glyphIndex({name}); - -const pairsByScriptLang={ - DFLT:{ - dflt:kernPairs - }, - latn:{ - dflt:kernPairs - } -}; - -const lookups=[]; -const features=[]; -let lookupIndex=0; - -for(const [script,tags] of Object.entries(pairsByScriptLang)){ - for(const [lang,entries] of Object.entries(tags)){ - const subTable={ - posFormat:1, - coverage:{ format:1, glyphs:[] }, - pairSets:[] - }; - const leftMap=new Map(); - - for(const [lName,rName,val] of entries){ - const lIdx=nameToIndex(lName); - const rIdx=nameToIndex(rName); - if(lIdx<=0 || rIdx<=0 || !val)continue; - if(!leftMap.has(lIdx))leftMap.set(lIdx,[]); - leftMap.get(lIdx).push({ rIdx, val }); - } - - if(leftMap.size===0)continue; - - const coverageGlyphs=[]; - const pairSets=[]; - for(const [lIdx,items] of leftMap.entries()){ - coverageGlyphs.push(lIdx); - pairSets.push({ - pairValueRecords:items.map(i=>({ - secondGlyph:i.rIdx, - value1:{ xAdvance:i.val }, - value2:{} - })) - }); - } - - subTable.coverage.glyphs=coverageGlyphs; - subTable.pairSets=pairSets; - - const lookup={ - lookupType:2, - lookupFlag:0, - subtables:[subTable] - }; - - const feature={ - tag:"kern", - lookupListIndexes:[lookupIndex] - }; - - lookups.push(lookup); - features.push({ script, lang, feature }); - lookupIndex++; - } -} - -if(lookups.length){ - font.tables.gpos={ - version:1, - scripts:[], - features:[], - lookups - }; - - const scriptMap=new Map(); - - for(const {script,lang,feature} of features){ - if(!scriptMap.has(script))scriptMap.set(script,{ tag:script, script:{ defaultLangSys:{ featureIndexes:[], lookupOrder:null, reqFeatureIndex:0xffff }, langSysRecords:[] } }); - const rec=scriptMap.get(script); - const scriptObj=rec.script; - - const featureIndex=font.tables.gpos.features.length; - font.tables.gpos.features.push(feature); - - if(lang==="dflt"){ - scriptObj.defaultLangSys.featureIndexes.push(featureIndex); - }else{ - scriptObj.langSysRecords.push({ - tag:lang, - langSys:{ - lookupOrder:null, - reqFeatureIndex:0xffff, - featureIndexes:[featureIndex] - } - }); - } - } - - font.tables.gpos.scripts=[...scriptMap.values()]; -} - const buf=Buffer.from(font.toArrayBuffer()); const outPath=path.join(outDir,"Stain.otf"); fs.writeFileSync(outPath,buf); console.log(`Built ${outPath}`); +