diff --git a/demo/src/index.ts b/demo/src/index.ts index a8cf588..15506a4 100644 --- a/demo/src/index.ts +++ b/demo/src/index.ts @@ -1,6 +1,9 @@ import { font, getGlyphPath } from "../../src/index.ts"; import { Glyph, Line, Vec } from "../../src/type"; + +const lowercase = ["a","á","à","ă","ắ","ằ","ẵ","ẳ","â","ấ","ầ","ẫ","ẩ","ǎ","å","ǻ","ä","ǟ","ã","ȧ","ǡ","ą","ā","ả","ȁ","ȃ","ạ","ặ","ậ","ḁ","æ","ǽ","ǣ","ẚ","ɐ","ɑ","ɒ","b","ḃ","ḅ","ḇ","ʙ","ƀ","ɓ","ƃ","c","ć","ĉ","č","ċ","ç","ḉ","ȼ","ƈ","ɕ","d","ď","ḋ","ḑ","đ","ḍ","ḓ","ḏ","ð","ȸ","dz","ʣ","dž","ʥ","ʤ","ɖ","ɗ","ƌ","ȡ","ẟ","e","é","è","ĕ","ê","ế","ề","ễ","ể","ě","ë","ẽ","ė","ȩ","ḝ","ę","ē","ḗ","ḕ","ẻ","ȅ","ȇ","ẹ","ệ","ḙ","ḛ","ɇ","ǝ","ə","ɛ","ɘ","ɚ","ɜ","ɝ","ɞ","ʚ","ɤ","f","ḟ","ʩ","ƒ","g","ǵ","ğ","ĝ","ǧ","ġ","ģ","ḡ","ɡ","ɢ","ǥ","ɠ","ʛ","ɣ","ƣ","h","ĥ","ȟ","ḧ","ḣ","ḩ","ħ","ḥ","ḫ","ẖ","ʜ","ƕ","ɦ","ɧ","i","í","ì","ĭ","î","ǐ","ï","ḯ","ĩ","į","ī","ỉ","ȉ","ȋ","ị","ḭ","ij","ı","ɪ","ɨ","ɩ","j","ĵ","ǰ","ȷ","ɉ","ʝ","ɟ","ʄ","k","ḱ","ǩ","ķ","ḳ","ḵ","ƙ","ʞ","l","ĺ","ľ","ļ","ł","ḷ","ḹ","ḽ","ḻ","ŀ","lj","ỻ","ʪ","ʫ","ʟ","ƚ","ɫ","ɬ","ɭ","ȴ","ɮ","ƛ","ʎ","m","ḿ","ṁ","ṃ","ɱ","n","ń","ǹ","ň","ñ","ṅ","ņ","ṇ","ṋ","ṉ","nj","ɴ","ɲ","ƞ","ɳ","ȵ","ŋ","o","ó","ò","ŏ","ô","ố","ồ","ỗ","ổ","ǒ","ö","ȫ","ő","õ","ṍ","ṏ","ȭ","ȯ","ȱ","ø","ǿ","ǫ","ǭ","ō","ṓ","ṑ","ỏ","ȍ","ȏ","ơ","ớ","ờ","ỡ","ở","ợ","ọ","ộ","œ","ɶ","ɔ","ɵ","ɷ","ȣ","p","ṕ","ṗ","ƥ","ɸ","q","ȹ","ʠ","ɋ","ĸ","r","ŕ","ř","ṙ","ŗ","ȑ","ȓ","ṛ","ṝ","ṟ","ʀ","ɍ","ɹ","ɺ","ɻ","ɼ","ɽ","ɾ","ɿ","ʁ","s","ś","ṥ","ŝ","š","ṧ","ṡ","ş","ṣ","ṩ","ș","ſ","ẛ","ß","ʂ","ȿ","ẜ","ẝ","ʃ","ƪ","ʅ","ʆ","t","ť","ẗ","ṫ","ţ","ṭ","ț","ṱ","ṯ","ʨ","ƾ","ʦ","ʧ","ŧ","ƫ","ƭ","ʈ","ȶ","ʇ","u","ú","ù","ŭ","û","ǔ","ů","ü","ǘ","ǜ","ǚ","ǖ","ű","ũ","ṹ","ų","ū","ṻ","ủ","ȕ","ȗ","ư","ứ","ừ","ữ","ử","ự","ụ","ṳ","ṷ","ṵ","ʉ","ɥ","ʮ","ʯ","ɯ","ɰ","ʊ","v","ṽ","ṿ","ʋ","ỽ","ʌ","w","ẃ","ẁ","ŵ","ẘ","ẅ","ẇ","ẉ","ʍ","x","ẍ","ẋ","y","ý","ỳ","ŷ","ẙ","ÿ","ỹ","ẏ","ȳ","ỷ","ỵ","ʏ","ɏ","ƴ","ỿ","ȝ","z","ź","ẑ","ž","ż","ẓ","ẕ","ƍ","ƶ","ȥ","ʐ","ʑ","ɀ","ʒ","ǯ","ƹ","ƺ","ʓ","þ","ƿ","ƨ","ƽ","ƅ","ɂ","ʕ","ʡ","ʢ","ʖ","ʗ","ʘ","ʬ","ʭ"] +/* console.log( JSON.stringify( font["3"].map( @@ -8,6 +11,24 @@ console.log( ) as Glyph, ), ); +*/ + + +const rotateGlyph = (g: Glyph) => g.map((l: Line) => l.map((p: Vec) => [1 - p[0], 1 - p[1]])) +const scaleGlyph = (g: Glyph) => g.map((l: Line) => l.map((p: Vec) => [0.25 + p[0] * 0.5, 0.25 + p[1] * 0.5])) + +// font["ʙ"] = scaleGlyph(font["B"]) +console.log(JSON.stringify(scaleGlyph(font['6']))) + +for (let l = 0; l < lowercase.length; l++) { + if (font[lowercase[l]] === undefined) { + console.log(`%c ${lowercase[l]}`, "font-size: 3em" ) + break; + } else { + console.log(`✅${lowercase[l]}`) + } +} + const app = document.getElementById("app"), form = document.createElement("form"), @@ -50,13 +71,17 @@ const update = () => { rect.setAttribute("y", `${margin[1] + y * textSize[1]}`); rect.setAttribute("width", `${textSize[0]}`); rect.setAttribute("height", `${textSize[1]}`); - group.appendChild(rect); + rect.setAttribute("title", char) + const title = document.createElementNS(namespace, "title") + title.textContent = char + rect.appendChild(title) lines.map((d: string) => { const path = document.createElementNS(namespace, "path"); path.setAttribute("d", d); group.appendChild(path); }); + group.appendChild(rect); } } group.setAttribute("stroke-width", `${fontScale * 40}`); diff --git a/demo/style.css b/demo/style.css index 5d167ba..8648d10 100644 --- a/demo/style.css +++ b/demo/style.css @@ -63,7 +63,6 @@ footer p { #app svg g rect { stroke: #ccc; stroke-width: 0.5px; - fill: #fefefe66; } @media screen and (min-width: 900px) { diff --git a/src/glyphs/diacritics.ts b/src/glyphs/diacritics.ts index 47eac94..8d929ee 100644 --- a/src/glyphs/diacritics.ts +++ b/src/glyphs/diacritics.ts @@ -31,8 +31,8 @@ const diacritics = { [ [0.4, 0.85], [0.5, 0.8], - [0.6, 0.85] - ] + [0.6, 0.85], + ], ], // diaeresis dr: [ @@ -72,6 +72,24 @@ const diacritics = { [0.6, 0.1], ], ], + // inverse breve + bri: [ + [ + [0.4, 0.15], + [0.4, 0.1], + [0.6, 0.1], + [0.6, 0.15], + ], + ], + // half circle right + hcr: [ + [ + [0.6, 0.1], + [0.7, 0.1], + [0.7, 0.2], + [0.6, 0.2], + ], + ], // haček or caron hc: [ [ @@ -87,13 +105,13 @@ const diacritics = { [0.7, 0.1], ], ], - // angstorm or circle or ring + // angstorm or circle or ring (top) gs: [ [ [0.45, 0.2], [0.45, 0.15], [0.55, 0.15], - [0.55, 0.25], + [0.55, 0.2], [0.45, 0.2], ], ], @@ -108,7 +126,7 @@ const diacritics = { ], ], // cedilla left - cdl: [ + cdl: [ [ [0.25, 0.7], [0.25, 0.75], @@ -117,6 +135,16 @@ const diacritics = { [0.2, 0.8], ], ], + // cedilla right + cdr: [ + [ + [0.75, 0.7], + [0.75, 0.75], + [0.8, 0.75], + [0.8, 0.8], + [0.7, 0.8], + ], + ], // ring/dot below db: [ [ @@ -144,24 +172,46 @@ const diacritics = { [0.55, 0.2], [0.55, 0.25], [0.5, 0.25], - [0.5, 0.3] + [0.5, 0.3], + ], + ], + // hook bottom right + hbr: [ + [ + [0.75, 0.725], + [0.75, 0.85], + [0.85, 0.9] ] ], - // line below + // line below lb: [ [ [0.3, 0.8], - [0.7, 0.8] - ] + [0.7, 0.8], + ], ], // horn hr: [ [ - [0.75, 0.35], - [0.8, 0.25] - ] - ] - + [0.8, 0.3], + [0.85, 0.25], + [0.85, 0.2], + ], + ], + crs: [ + [ + [0.8, 0.3], + [0.8, 0.25], + [0.85, 0.2], + ], + ], + // barred (kind of /) + brd: [ + [ + [0.55, 0.2], + [0.35, 0.8], + ], + ], } as Font; -export default diacritics +export default diacritics; diff --git a/src/glyphs/lowercase.ts b/src/glyphs/lowercase.ts deleted file mode 100644 index ed76db7..0000000 --- a/src/glyphs/lowercase.ts +++ /dev/null @@ -1,413 +0,0 @@ -import { Font, ExtendedTable, Glyph } from "../type"; -import diacritics from "./diacritics"; -/* - * Base alphabet - */ -const lowercase = { - a: [ - [ - [0.8, 0.5], - [0.2, 0.5], - [0.2, 0.7], - [0.8, 0.7], - [0.8, 0.3], - [0.3, 0.3], - ], - ], - b: [ - [ - [0.25, 0.1], - [0.25, 0.7], - [0.75, 0.7], - [0.75, 0.3], - [0.25, 0.3], - ], - ], - c: [ - [ - [0.8, 0.3], - [0.2, 0.3], - [0.2, 0.7], - [0.8, 0.7], - ], - ], - d: [ - [ - [0.75, 0.1], - [0.75, 0.7], - [0.25, 0.7], - [0.25, 0.3], - [0.75, 0.3], - ], - ], - e: [ - [ - [0.2, 0.5], - [0.8, 0.5], - [0.8, 0.3], - [0.2, 0.3], - [0.2, 0.7], - [0.8, 0.7], - ], - ], - f: [ - [ - [0.2, 0.5], - [0.7, 0.5], - ], - [ - [0.4, 0.7], - [0.4, 0.2], - [0.7, 0.2], - ], - ], - g: [ - [ - [0.75, 0.7], - [0.25, 0.7], - [0.25, 0.3], - [0.75, 0.3], - [0.75, 0.9], - [0.5, 0.9], - ], - ], - h: [ - [ - [0.25, 0.7], - [0.25, 0.1], - ], - [ - [0.25, 0.3], - [0.75, 0.3], - [0.75, 0.7], - ], - ], - i: [ - [ - [0.5, 0.1], - [0.5, 0.15], - ], - [ - [0.5, 0.3], - [0.5, 0.7], - ], - ], - j: [ - [ - [0.6, 0.1], - [0.6, 0.15], - ], - [ - [0.6, 0.3], - [0.6, 0.9], - [0.3, 0.9], - ], - ], - k: [ - [ - [0.3, 0.7], - [0.3, 0.1], - ], - [ - [0.8, 0.3], - [0.3, 0.5], - [0.8, 0.7], - ], - ], - l: [ - [ - [0.4, 0.1], - [0.5, 0.1], - [0.5, 0.7], - [0.6, 0.7], - ], - ], - m: [ - [ - [0.2, 0.7], - [0.2, 0.3], - [0.8, 0.3], - [0.8, 0.7], - ], - [ - [0.5, 0.3], - [0.5, 0.7], - ], - ], - n: [ - [ - [0.2, 0.7], - [0.2, 0.3], - [0.8, 0.3], - [0.8, 0.7], - ], - ], - o: [ - [ - [0.2, 0.7], - [0.2, 0.3], - [0.8, 0.3], - [0.8, 0.7], - [0.2, 0.7], - ], - ], - p: [ - [ - [0.25, 0.9], - [0.25, 0.3], - [0.75, 0.3], - [0.75, 0.7], - [0.25, 0.7], - ], - ], - q: [ - [ - [0.75, 0.9], - [0.75, 0.3], - [0.25, 0.3], - [0.25, 0.7], - [0.75, 0.7], - ], - ], - r: [ - [ - [0.7, 0.3], - [0.4, 0.3], - [0.4, 0.7], - ], - ], - s: [ - [ - [0.8, 0.3], - [0.2, 0.3], - [0.2, 0.5], - [0.8, 0.5], - [0.8, 0.7], - [0.2, 0.7], - ], - ], - t: [ - [ - [0.2, 0.3], - [0.8, 0.3], - ], - [ - [0.35, 0.2], - [0.35, 0.7], - [0.65, 0.7], - ], - ], - u: [ - [ - [0.2, 0.3], - [0.2, 0.7], - [0.8, 0.7], - ], - [ - [0.8, 0.75], - [0.8, 0.3], - ], - ], - v: [ - [ - [0.2, 0.3], - [0.5, 0.7], - [0.8, 0.3], - ], - ], - w: [ - [ - [0.2, 0.3], - [0.2, 0.7], - [0.8, 0.7], - [0.8, 0.3], - ], - [ - [0.5, 0.3], - [0.5, 0.7], - ], - ], - x: [ - [ - [0.2, 0.3], - [0.8, 0.7], - ], - [ - [0.8, 0.3], - [0.2, 0.7], - ], - ], - y: [ - [ - [0.25, 0.3], - [0.25, 0.7], - [0.75, 0.7], - ], - [ - [0.75, 0.3], - [0.75, 0.9], - [0.5, 0.9], - ], - ], - z: [ - [ - [0.2, 0.3], - [0.8, 0.3], - [0.2, 0.7], - [0.8, 0.7], - ], - ], -} as Font; - -// Associate diacritics with existing glyph -const accentTable = { - // a - ḁ: ["a", ["db"]], - ả: ["a", ["ha"]], - ấ: ["a", ["cr", "ct"]], - ầ: ["a", ["cr", "gr"]], - ẩ: ["a", ["cr", "ha"]], - ẫ: ["a", ["cr", "tl"]], - ậ: ["a", ["cr", "db"]], - ắ: ["a", ["br", "ct"]], - ằ: ["a", ["br", "gr"]], - ẳ: ["a", ["br", "ct"]], - ẵ: ["a", ["br", "tl"]], - ặ: ["a", ["br", "db"]], - - à: ["a", ["gr"]], - á: ["a", ["ct"]], - â: ["a", ["cr"]], - ä: ["a", ["dr"]], - ã: ["a", ["tl"]], - ă: ["a", ["br"]], - ǎ: ["a", ["hc"]], - ā: ["a", ["mc"]], - - // b - ḃ: ["b", ["da"]], - ḅ: ["b", ["db"]], - ḇ: ["b", ["lb"]], - - // c - ć: ["c", ["ct"]], - ĉ: ["c", ["cr"]], - ç: ["c", ["cd"]], - - // d - ḋ: ["d", ["da"]], - ḍ: ["d", ["db"]], - ḏ: ["d", ["lb"]], - ḑ: ["d", ["cd"]], - ḓ: ["d", ["crb"]], - - // e - ẹ: ["e", ["db"]], - ẻ: ["e", ["ha"]], - ẽ: ["e", ["tl"]], - ế: ["e", ["cr", "ct"]], - ề: ["e", ["cr", "gr"]], - ể: ["e", ["cr", "ha"]], - ễ: ["e", ["cr", "tl"]], - ệ: ["e", ["cr", "db"]], - - ḙ: ["e", ["crb"]], - ḛ: ["e", ["tlb"]], - - // f - ḟ: ["f", ["da"]], - - // g - ḡ: ["g", ["mc"]], - - // h - ḣ: ["h", ["da"]], - ḥ: ["h", ["db"]], - ḧ: ["h", ["dr"]], - ḩ: ["h", ["cdl"]], - - // i - Ỉ: ["i", ["ha"]], - Ị: ["i", ["db"]], - - // o - ọ: ["o", ["db"]], - ỏ: ["o", ["ha"]], - ố: ["o", ["cr", "ct"]], - ồ: ["o", ["cr", "gr"]], - ổ: ["o", ["cr", "ha"]], - ỗ: ["o", ["cr", "tl"]], - ộ: ["o", ["cr", "db"]], - ớ: ["o", ["hr", "ct"]], - ờ: ["o", ["hr", "gr"]], - ở: ["o", ["hr", "ha"]], - ỡ: ["o", ["hr", "tl"]], - ợ: ["o", ["hr", "db"]], - - // u - ụ: ["u", ["db"]], - ủ: ["u", ["ha"]], - ứ: ["u", ["hr", "ct"]], - ừ: ["u", ["hr", "gr"]], - ử: ["u", ["hr", "ha"]], - ữ: ["u", ["hr", "tl"]], - ự: ["u", ["hr", "db"]], - - // y - ỳ: ["y", ["gr"]], - ỵ: ["y", ["db"]], - ỷ: ["y", ["ha"]], - ỹ: ["y", ["tl"]], -} as ExtendedTable; - -// Clone exisiting glyph and add diacritical marks -const accented = {} as Font; -Object.keys(accentTable).map((char) => { - accented[char as keyof typeof accented] = [ - ...lowercase[accentTable[char][0] as keyof Font], - ...accentTable[char][1].reduce( - (acc: Glyph, a: keyof Font) => [...acc, ...diacritics[a]], - [], - ), - ] as Glyph; -}); - -// Merge all glyphs and add some ligature -const extended = { - ...lowercase, - æ: [ - [ - [0.5, 0.3], - [0.8, 0.3], - [0.8, 0.5], - [0.2, 0.5], - [0.2, 0.7], - [0.5, 0.7], - [0.5, 0.3], - [0.3, 0.3], - ], - [ - [0.5, 0.7], - [0.8, 0.7], - ], - ], - œ: [ - [ - [0.5, 0.3], - [0.8, 0.3], - [0.8, 0.5], - [0.5, 0.5], - [0.5, 0.3], - [0.2, 0.3], - [0.2, 0.7], - [0.5, 0.7], - [0.5, 0.5], - ], - [ - [0.5, 0.7], - [0.8, 0.7], - ], - ], - ...accented, -}; -export default extended; diff --git a/src/glyphs/lowercase/base.ts b/src/glyphs/lowercase/base.ts new file mode 100644 index 0000000..76aa486 --- /dev/null +++ b/src/glyphs/lowercase/base.ts @@ -0,0 +1,597 @@ +import { type Font } from "../../type"; + +/* + * Base alphabet + */ +const base = { + a: [ + [ + [0.8, 0.5], + [0.2, 0.5], + [0.2, 0.7], + [0.8, 0.7], + ], + [ + [0.8, 0.725], + [0.8, 0.3], + [0.3, 0.3], + ], + ], + æ: [ + [ + [0.5, 0.3], + [0.8, 0.3], + [0.8, 0.5], + [0.2, 0.5], + [0.2, 0.7], + [0.5, 0.7], + [0.5, 0.3], + [0.3, 0.3], + ], + [ + [0.5, 0.7], + [0.8, 0.7], + ], + ], + ɐ: [ + [ + [0.2, 0.5], + [0.8, 0.5], + [0.8, 0.3], + [0.2, 0.3], + [0.2, 0.7], + [0.7, 0.7], + ], + ], + ɑ: [ + [ + [0.8, 0.5], + [0.2, 0.5], + [0.2, 0.7], + [0.8, 0.7], + ], + [ + [0.8, 0.725], + [0.8, 0.3], + ], + ], + ɒ: [ + [ + [0.2, 0.5], + [0.8, 0.5], + [0.8, 0.3], + [0.2, 0.3], + ], + [ + [0.2, 0.275], + [0.2, 0.7], + ], + ], + + b: [ + [ + [0.25, 0.1], + [0.25, 0.725], + ], + [ + [0.25, 0.7], + [0.75, 0.7], + [0.75, 0.3], + [0.25, 0.3], + ], + ], + ʙ: [ + [ + [0.55, 0.5], + [0.55, 0.35], + [0.35, 0.35], + [0.35, 0.65], + [0.65, 0.65], + [0.65, 0.5], + [0.35, 0.5], + ], + ], + ƀ: [ + [ + [0.25, 0.1], + [0.25, 0.725], + ], + [ + [0.25, 0.7], + [0.75, 0.7], + [0.75, 0.3], + [0.25, 0.3], + ], + [ + [0.15, 0.165], + [0.35, 0.165], + ], + ], + ɓ: [ + [ + [0.35, 0.1], + [0.25, 0.1], + [0.25, 0.725], + ], + [ + [0.25, 0.7], + [0.75, 0.7], + [0.75, 0.3], + [0.25, 0.3], + ], + ], + ƃ: [ + [ + [0.75, 0.1], + [0.25, 0.1], + [0.25, 0.725], + ], + [ + [0.25, 0.7], + [0.75, 0.7], + [0.75, 0.3], + [0.25, 0.3], + ], + ], + + c: [ + [ + [0.8, 0.3], + [0.2, 0.3], + [0.2, 0.7], + [0.8, 0.7], + ], + ], + ɕ: [ + [ + [0.8, 0.3], + [0.2, 0.3], + [0.2, 0.7], + [0.8, 0.7], + [0.5, 0.55], + [0.15, 0.75], + ], + ], + + + d: [ + [ + [0.75, 0.1], + [0.75, 0.725], + ], + [ + [0.75, 0.7], + [0.25, 0.7], + [0.25, 0.3], + [0.75, 0.3], + ], + ], + đ: [ + [ + [0.75, 0.1], + [0.75, 0.725], + ], + [ + [0.75, 0.7], + [0.25, 0.7], + [0.25, 0.3], + [0.75, 0.3], + ], + [ + [0.65, 0.165], + [0.85, 0.165], + ], + ], + ð: [ + [ + [0.5, 0.1], + [0.75, 0.3], + [0.75, 0.725], + ], + [ + [0.75, 0.7], + [0.25, 0.7], + [0.25, 0.3], + [0.75, 0.3], + ], + [ + [0.5, 0.2], + [0.65, 0.1] + ] + ], + ȸ: [ + [ + [0.5, 0.1], + [0.5, 0.725], + ], + [ + [0.25, 0.3], + [0.75, 0.3], + [0.75, 0.7], + [0.25, 0.7], + [0.25, 0.3] + ] + ], + dz: [ + [ + [0.45, 0.1], + [0.45, 0.725], + ], + [ + [0.45, 0.7], + [0.15, 0.7], + [0.15, 0.3], + [0.45, 0.3], + ], + [ + [0.55, 0.3], + [0.85, 0.3], + [0.55, 0.7], + [0.85, 0.7] + ] + ], + ʣ: [ + [ + [0.5, 0.1], + [0.5, 0.725], + ], + [ + [0.5, 0.7], + [0.15, 0.7], + [0.15, 0.3], + [0.5, 0.3], + ], + [ + [0.5, 0.3], + [0.85, 0.3], + [0.5, 0.7], + [0.85, 0.7] + ] + ], + dž: [ + [ + [0.45, 0.1], + [0.45, 0.725], + ], + [ + [0.45, 0.7], + [0.15, 0.7], + [0.15, 0.3], + [0.45, 0.3], + ], + [ + [0.55, 0.3], + [0.85, 0.3], + [0.55, 0.7], + [0.85, 0.7] + ], + [ + [0.55, 0.1], + [0.7, 0.2], + [0.85, 0.1] + ] + ], + ʥ: [ + [ + [0.5, 0.1], + [0.5, 0.725], + ], + [ + [0.5, 0.7], + [0.15, 0.7], + [0.15, 0.3], + [0.5, 0.3], + ], + [ + [0.5, 0.3], + [0.85, 0.3], + [0.5, 0.7], + [0.85, 0.7], + [0.75, 0.6], + [0.55, 0.8] + ] + ], + ʤ: [ + [ + [0.5, 0.1], + [0.5, 0.725], + ], + [ + [0.5, 0.7], + [0.15, 0.7], + [0.15, 0.3], + [0.5, 0.3], + ],[ + [0.5, 0.3], + [0.85, 0.3], + [0.55, 0.55], + [0.85, 0.7], + [0.7, 0.9], + [0.5, 0.8] + ] + ], + ɗ: [ + [ + [0.85, 0.1], + [0.8, 0.1], + [0.75, 0.15], + [0.75, 0.725], + ], + [ + [0.75, 0.7], + [0.25, 0.7], + [0.25, 0.3], + [0.75, 0.3], + ], + ], + ƌ: [ + [ + [0.25, 0.15], + [0.75, 0.15], + [0.75, 0.725], + ], + [ + [0.75, 0.7], + [0.25, 0.7], + [0.25, 0.3], + [0.75, 0.3], + + ] + ], + + e: [ + [ + [0.2, 0.5], + [0.8, 0.5], + [0.8, 0.3], + [0.2, 0.3], + [0.2, 0.7], + [0.8, 0.7], + ], + ], + f: [ + [ + [0.2, 0.5], + [0.7, 0.5], + ], + [ + [0.4, 0.7], + [0.4, 0.2], + [0.7, 0.2], + ], + ], + g: [ + [ + [0.75, 0.7], + [0.25, 0.7], + [0.25, 0.3], + [0.75, 0.3], + ], + [ + [0.75, 0.275], + [0.75, 0.9], + [0.5, 0.9], + ], + ], + h: [ + [ + [0.25, 0.7], + [0.25, 0.1], + ], + [ + [0.225, 0.3], + [0.75, 0.3], + [0.75, 0.7], + ], + ], + i: [ + [ + [0.5, 0.1], + [0.5, 0.15], + ], + [ + [0.5, 0.3], + [0.5, 0.7], + ], + ], + j: [ + [ + [0.6, 0.1], + [0.6, 0.15], + ], + [ + [0.45, 0.3], + [0.75, 0.3], + ], + [ + [0.6, 0.3], + [0.6, 0.9], + [0.3, 0.9], + ], + ], + k: [ + [ + [0.3, 0.7], + [0.3, 0.1], + ], + [ + [0.8, 0.3], + [0.3, 0.5], + [0.8, 0.7], + ], + ], + l: [ + [ + [0.4, 0.1], + [0.5, 0.1], + [0.5, 0.7], + [0.6, 0.7], + ], + ], + m: [ + [ + [0.2, 0.7], + [0.2, 0.275], + ], + [ + [0.2, 0.3], + [0.8, 0.3], + [0.8, 0.7], + ], + [ + [0.5, 0.3], + [0.5, 0.7], + ], + ], + n: [ + [ + [0.2, 0.7], + [0.2, 0.275], + ], + [ + [0.2, 0.3], + [0.8, 0.3], + [0.8, 0.7], + ], + ], + o: [ + [ + [0.2, 0.7], + [0.2, 0.3], + [0.8, 0.3], + [0.8, 0.7], + [0.2, 0.7], + ], + ], + p: [ + [ + [0.25, 0.9], + [0.25, 0.3], + [0.75, 0.3], + [0.75, 0.7], + [0.2, 0.7], + ], + ], + q: [ + [ + [0.75, 0.9], + [0.75, 0.3], + [0.25, 0.3], + [0.25, 0.7], + [0.8, 0.7], + ], + ], + r: [ + [ + [0.7, 0.3], + [0.4, 0.3], + ], + [ + [0.4, 0.275], + [0.4, 0.7], + ], + ], + s: [ + [ + [0.8, 0.3], + [0.2, 0.3], + [0.2, 0.5], + [0.8, 0.5], + [0.8, 0.7], + [0.2, 0.7], + ], + ], + t: [ + [ + [0.2, 0.3], + [0.8, 0.3], + ], + [ + [0.35, 0.2], + [0.35, 0.7], + [0.65, 0.7], + ], + ], + u: [ + [ + [0.2, 0.3], + [0.2, 0.7], + [0.8, 0.7], + ], + [ + [0.8, 0.75], + [0.8, 0.3], + ], + ], + v: [ + [ + [0.2, 0.3], + [0.5, 0.7], + [0.8, 0.3], + ], + ], + w: [ + [ + [0.2, 0.3], + [0.2, 0.725], + ], + [ + [0.2, 0.7], + [0.8, 0.7], + [0.8, 0.3], + ], + [ + [0.5, 0.3], + [0.5, 0.7], + ], + ], + x: [ + [ + [0.2, 0.3], + [0.8, 0.7], + ], + [ + [0.8, 0.3], + [0.2, 0.7], + ], + ], + y: [ + [ + [0.25, 0.3], + [0.25, 0.7], + [0.775, 0.7], + ], + [ + [0.75, 0.3], + [0.75, 0.9], + [0.5, 0.9], + ], + ], + z: [ + [ + [0.2, 0.3], + [0.8, 0.3], + [0.2, 0.7], + [0.8, 0.7], + ], + ], + œ: [ + [ + [0.5, 0.3], + [0.8, 0.3], + [0.8, 0.5], + [0.5, 0.5], + [0.5, 0.3], + [0.2, 0.3], + [0.2, 0.7], + [0.5, 0.7], + [0.5, 0.5], + ], + [ + [0.5, 0.7], + [0.8, 0.7], + ], + ] +} as Font; + +export { base }; diff --git a/src/glyphs/lowercase/diaBaseAssociation.ts b/src/glyphs/lowercase/diaBaseAssociation.ts new file mode 100644 index 0000000..25e5a96 --- /dev/null +++ b/src/glyphs/lowercase/diaBaseAssociation.ts @@ -0,0 +1,119 @@ +import { type ExtendedTable } from "../../type"; + +// Associate diacritics with existing glyph +const diaBaseAssociation = { + // a + á: ["a", ["ct"]], + à: ["a", ["gr"]], + ă: ["a", ["br"]], + ắ: ["a", ["br", "ct"]], + ằ: ["a", ["br", "gr"]], + ẵ: ["a", ["br", "tl"]], + ẳ: ["a", ["br", "ha"]], + â: ["a", ["cr"]], + ấ: ["a", ["cr", "ct"]], + ầ: ["a", ["cr", "gr"]], + ẫ: ["a", ["cr", "tl"]], + ẩ: ["a", ["cr", "ha"]], + ǎ: ["a", ["hc"]], + å: ["a", ["gs"]], + ǻ: ["a", ["gs", "ha"]], + ä: ["a", ["dr"]], + ǟ: ["a", ["dr", "mc"]], + ã: ["a", ["tl"]], + ȧ: ["a", ["gs"]], + ǡ: ["a", ["gs", "mc"]], + ą: ["a", ["cdr"]], + ā: ["a", ["mc"]], + ả: ["a", ["ha"]], + ȁ: ["a", ["gr", "gr"]], + ȃ: ["a", ["bri"]], + ạ: ["a", ["db"]], + ặ: ["a", ["br", "db"]], + ậ: ["a", ["cr", "db"]], + ḁ: ["a", ["db"]], + ǽ: ["æ", ["ct"]], + ǣ: ["æ", ["mc"]], + ẚ: ["a", ["hcr"]], + // b + ḃ: ["b", ["da"]], + ḅ: ["b", ["db"]], + ḇ: ["b", ["lb"]], + + // c + ć: ["c", ["ct"]], + ĉ: ["c", ["cr"]], + č: ["c", ["hc"]], + ċ: ["c", ["da"]], + ç: ["c", ["cd"]], + ḉ: ["c", ["cd", "ct"]], + ȼ: ["c", ["brd"]], + ƈ: ["c", ["crs"]], + // d + ď: ["d", ["ct"]], + ḋ: ["d", ["da"]], + ḑ: ["d", ["cd"]], + ḍ: ["d", ["db"]], + ḓ: ["d", ["crb"]], + ḏ: ["d", ["lb"]], + ɖ: ["d", ["crs"]], + // e + ẹ: ["e", ["db"]], + ẻ: ["e", ["ha"]], + ẽ: ["e", ["tl"]], + ế: ["e", ["cr", "ct"]], + ề: ["e", ["cr", "gr"]], + ể: ["e", ["cr", "ha"]], + ễ: ["e", ["cr", "tl"]], + ệ: ["e", ["cr", "db"]], + + ḙ: ["e", ["crb"]], + ḛ: ["e", ["tlb"]], + + // f + ḟ: ["f", ["da"]], + + // g + ḡ: ["g", ["mc"]], + + // h + ḣ: ["h", ["da"]], + ḥ: ["h", ["db"]], + ḧ: ["h", ["dr"]], + ḩ: ["h", ["cdl"]], + + // i + Ỉ: ["i", ["ha"]], + Ị: ["i", ["db"]], + + // o + ọ: ["o", ["db"]], + ỏ: ["o", ["ha"]], + ố: ["o", ["cr", "ct"]], + ồ: ["o", ["cr", "gr"]], + ổ: ["o", ["cr", "ha"]], + ỗ: ["o", ["cr", "tl"]], + ộ: ["o", ["cr", "db"]], + ớ: ["o", ["hr", "ct"]], + ờ: ["o", ["hr", "gr"]], + ở: ["o", ["hr", "ha"]], + ỡ: ["o", ["hr", "tl"]], + ợ: ["o", ["hr", "db"]], + + // u + ụ: ["u", ["db"]], + ủ: ["u", ["ha"]], + ứ: ["u", ["hr", "ct"]], + ừ: ["u", ["hr", "gr"]], + ử: ["u", ["hr", "ha"]], + ữ: ["u", ["hr", "tl"]], + ự: ["u", ["hr", "db"]], + + // y + ỳ: ["y", ["gr"]], + ỵ: ["y", ["db"]], + ỷ: ["y", ["ha"]], + ỹ: ["y", ["tl"]], +} as ExtendedTable; + +export { diaBaseAssociation } diff --git a/src/glyphs/lowercase/index.ts b/src/glyphs/lowercase/index.ts new file mode 100644 index 0000000..87a9252 --- /dev/null +++ b/src/glyphs/lowercase/index.ts @@ -0,0 +1,120 @@ +import { Font, Glyph, DiaGroup, Line, Vec } from "../../type"; +import diacritics from "../diacritics"; +import { base } from "./base"; +import { diaBaseAssociation } from "./diaBaseAssociation"; + +// A list of top keys diactricts +// Use to detect and move diacritics +const topDia = [ + "gr", + "ct", + "cr", + "dr", + "tl", + "br", + "bri", + "hcr", + "mc", + "gs", + "da", + "ha", +] as Array; + +const topDiaCount = (diaKey: keyof Font): number => + topDia.includes(diaKey) ? 1 : 0; + +const moveDia = { + tp: (g: Glyph) => + g.map((l: Line) => l.map((p: Vec) => [p[0], p[1] - 0.0625])), + bt: (g: Glyph) => g.map((l: Line) => l.map((p: Vec) => [p[0], p[1] + 0.125])), + lf: (g: Glyph) => g.map((l: Line) => l.map((p: Vec) => [p[0] - 0.125, p[1]])), + rg: (g: Glyph) => g.map((l: Line) => l.map((p: Vec) => [p[0] + 0.125, p[1]])), +}; + +const mergeDia = (diaKeys: DiaGroup): Glyph => { + // check if theres is two diacritics and + // both are situated on top of letter + const multipleTopDia = diaKeys.reduce( + (acc: number, dia: keyof Font) => (acc += topDiaCount(dia)), + 0, + ); + if (diaKeys.length > 1 && multipleTopDia > 1) { + // move acute accent left + if (diaKeys.includes("ct")) { + return diaKeys + .filter((k: keyof Font) => k !== "ct") + .reduce( + (g: Glyph, k: keyof Font) => [ + ...g, + ...(topDia.includes(k) ? moveDia.rg(diacritics[k]) : diacritics[k]), + ], + [...moveDia.lf(diacritics["ct"])], + ); + } + // move grave accent right + else if (diaKeys.includes("gr")) { + return diaKeys + .filter((k: keyof Font) => k !== "gr") + .reduce( + (g: Glyph, k: keyof Font) => [ + ...g, + ...(topDia.includes(k) ? moveDia.lf(diacritics[k]) : diacritics[k]), + ], + [...moveDia.rg(diacritics["gr"])], + ); + } + // move breve bottom + else if (diaKeys.includes("br")) { + return diaKeys + .filter((k: keyof Font) => k !== "br") + .reduce( + (g: Glyph, k: keyof Font) => [...g, ...diacritics[k]], + [...moveDia.bt(diacritics["br"])], + ); + } + // move tild up + else if (diaKeys.includes("tl")) { + return diaKeys + .filter((k: keyof Font) => k !== "tl") + .reduce( + (g: Glyph, k: keyof Font) => [...g, ...diacritics[k]], + [...moveDia.tp(diacritics["tl"])], + ); + } + // else move macron up + else if (diaKeys.includes("mc")) { + return diaKeys + .filter((k: keyof Font) => k !== "mc") + .reduce( + (g: Glyph, k: keyof Font) => [...g, ...diacritics[k]], + [...moveDia.tp(diacritics["mc"])], + ); + } else { + return diaKeys.reduce( + (acc: Glyph, k: keyof Font) => [...acc, ...diacritics[k]], + [] as Glyph, + ); + } + } else { + return diaKeys.reduce( + (acc: Glyph, k: keyof Font) => [...acc, ...diacritics[k]], + [] as Glyph, + ); + } +}; + +// Clone exisiting glyph and add diacritical marks +const accented = {} as Font; +Object.keys(diaBaseAssociation).map((char) => { + accented[char as keyof typeof accented] = [ + ...base[diaBaseAssociation[char][0] as keyof Font], + ...mergeDia(diaBaseAssociation[char][1] as DiaGroup), + ] as Glyph; +}); + +// Merge all glyphs and add some ligature +const lowercase = { + ...base, + ...accented, +}; +export default lowercase; diff --git a/src/index.ts b/src/index.ts index f5430ba..408df91 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import { type Vec, Line, Glyph, Font } from "./type"; -import lowercase from "./glyphs/lowercase"; +import lowercase from "./glyphs/lowercase/index"; import uppercase from "./glyphs/uppercase"; import ponctuation from "./glyphs/poncuation"; import number from './glyphs/number'; diff --git a/src/type.d.ts b/src/type.d.ts index 8b4d2b6..ba68733 100644 --- a/src/type.d.ts +++ b/src/type.d.ts @@ -7,6 +7,9 @@ export interface Line extends Array {} // Another for letter (array of Line) export interface Glyph extends Array {} +// An array of diacritics key (two or three letters) +export interface DiaGroup extends Array {} + // Table to dupplicate existing glyph with diacriticals marks export interface ExtendedTable { [key: string]: [string, string[]]; diff --git a/tsconfig.build.json b/tsconfig.build.json index ba4be3d..19511cb 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -1,13 +1,15 @@ - +{ "compilerOptions": { - "target": "ES2020", + "target": "ESNext", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ESNext", "DOM", "DOM.Iterable"], "skipLibCheck": true, + "types":  ["vite/client", "node"], + "strict": true, /* Bundler mode */ - "moduleResolution": "bundler", + "moduleResolution": "Node", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, @@ -19,6 +21,6 @@ "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, - "include": ["src"], - "exclude": ["__tests__/*.ts"] + "include": ["./src"], + "exclude": ["__tests__/*.ts", "node_modules"] }