Skip to content

Commit

Permalink
use a single global shaping buffer
Browse files Browse the repository at this point in the history
this doesn't seem to help the perf examples (maybe even makes
them a tiny bit slower) in Node, but I recall this helping out
in Firefox
  • Loading branch information
chearon committed Oct 15, 2023
1 parent 3f21512 commit e9615ec
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 20 deletions.
1 change: 1 addition & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ em++ \
-Wl,--export -Wl,hb_buffer_get_glyph_infos \
-Wl,--export -Wl,hb_buffer_get_glyph_positions \
-Wl,--export -Wl,hb_buffer_get_length \
-Wl,--export -Wl,hb_buffer_set_length \
-Wl,--export -Wl,hb_buffer_guess_segment_properties \
-Wl,--export -Wl,hb_buffer_set_cluster_level \
-Wl,--export -Wl,hb_buffer_set_direction \
Expand Down
8 changes: 6 additions & 2 deletions gen.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,8 @@ async function getScriptNames() {
const text = await res.text();
/** @type {Map<string, number>} */
const nameToCode = new Map([['Common', 0]]);
/** @type {Map<string, number>} */
const nameToTag = new Map([['Common', hb_tag('dflt')]]);
/** @type {Map<number, string>} */
const codeToName = new Map([[0, 'Common']]);
/** @type {Map<number, number>} */
Expand All @@ -392,18 +394,20 @@ async function getScriptNames() {
const [tag, /*no*/, /*en*/, /*fr*/, name, /*ver*/, /*date*/] = line.split(';');
if (nameToCode.has(name)) continue; // Common
nameToCode.set(name, code);
nameToTag.set(name, hb_tag(tag));
codeToName.set(code, name);
tagToCode.set(hb_tag(tag), code);
code += 1;
}

return {nameToCode, codeToName, tagToCode};
return {nameToCode, nameToTag, codeToName, tagToCode};
}

async function generateScriptNames() {
const {nameToCode, codeToName, tagToCode} = await getScriptNames();
const {nameToCode, nameToTag, codeToName, tagToCode} = await getScriptNames();
fs.writeFileSync(path.join(__dirname, 'gen/script-names.ts'), `// generated from gen.js
export const nameToCode = new Map(${JSON.stringify([...nameToCode.entries()])});
export const nameToTag = new Map(${JSON.stringify([...nameToTag.entries()])});
export const codeToName = new Map(${JSON.stringify([...codeToName.entries()])});
export const tagToCode = new Map(${JSON.stringify([...tagToCode.entries()])});
`);
Expand Down
1 change: 1 addition & 0 deletions gen/script-names.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// generated from gen.js
export const nameToCode = new Map([["Common",0],["Adlam",1],["",2],["Caucasian_Albanian",3],["Ahom",4],["Arabic",5],["Imperial_Aramaic",6],["Armenian",7],["Avestan",8],["Balinese",9],["Bamum",10],["Bassa_Vah",11],["Batak",12],["Bengali",13],["Bhaiksuki",14],["Bopomofo",15],["Brahmi",16],["Braille",17],["Buginese",18],["Buhid",19],["Chakma",20],["Canadian_Aboriginal",21],["Carian",22],["Cham",23],["Cherokee",24],["Chorasmian",25],["Coptic",26],["Cypro_Minoan",27],["Cypriot",28],["Cyrillic",29],["Devanagari",30],["Dives_Akuru",31],["Dogra",32],["Deseret",33],["Duployan",34],["Egyptian_Hieroglyphs",35],["Elbasan",36],["Elymaic",37],["Ethiopic",38],["Georgian",39],["Glagolitic",40],["Gunjala_Gondi",41],["Masaram_Gondi",42],["Gothic",43],["Grantha",44],["Greek",45],["Gujarati",46],["Gurmukhi",47],["Hangul",48],["Han",49],["Hanunoo",50],["Hatran",51],["Hebrew",52],["Hiragana",53],["Anatolian_Hieroglyphs",54],["Pahawh_Hmong",55],["Nyiakeng_Puachue_Hmong",56],["Katakana_Or_Hiragana",57],["Old_Hungarian",58],["Old_Italic",59],["Javanese",60],["Kayah_Li",61],["Katakana",62],["Kawi",63],["Kharoshthi",64],["Khmer",65],["Khojki",66],["Khitan_Small_Script",67],["Kannada",68],["Kaithi",69],["Tai_Tham",70],["Lao",71],["Latin",72],["Lepcha",73],["Limbu",74],["Linear_A",75],["Linear_B",76],["Lisu",77],["Lycian",78],["Lydian",79],["Mahajani",80],["Makasar",81],["Mandaic",82],["Manichaean",83],["Marchen",84],["Medefaidrin",85],["Mende_Kikakui",86],["Meroitic_Cursive",87],["Meroitic_Hieroglyphs",88],["Malayalam",89],["Modi",90],["Mongolian",91],["Mro",92],["Meetei_Mayek",93],["Multani",94],["Myanmar",95],["Nag_Mundari",96],["Nandinagari",97],["Old_North_Arabian",98],["Nabataean",99],["Newa",100],["Nko",101],["Nushu",102],["Ogham",103],["Ol_Chiki",104],["Old_Turkic",105],["Oriya",106],["Osage",107],["Osmanya",108],["Old_Uyghur",109],["Palmyrene",110],["Pau_Cin_Hau",111],["Old_Permic",112],["Phags_Pa",113],["Inscriptional_Pahlavi",114],["Psalter_Pahlavi",115],["Phoenician",116],["Miao",117],["Inscriptional_Parthian",118],["Rejang",119],["Hanifi_Rohingya",120],["Runic",121],["Samaritan",122],["Old_South_Arabian",123],["Saurashtra",124],["SignWriting",125],["Shavian",126],["Sharada",127],["Siddham",128],["Khudawadi",129],["Sinhala",130],["Sogdian",131],["Old_Sogdian",132],["Sora_Sompeng",133],["Soyombo",134],["Sundanese",135],["Syloti_Nagri",136],["Syriac",137],["Tagbanwa",138],["Takri",139],["Tai_Le",140],["New_Tai_Lue",141],["Tamil",142],["Tangut",143],["Tai_Viet",144],["Telugu",145],["Tifinagh",146],["Tagalog",147],["Thaana",148],["Thai",149],["Tibetan",150],["Tirhuta",151],["Tangsa",152],["Toto",153],["Ugaritic",154],["Vai",155],["Vithkuqi",156],["Warang_Citi",157],["Wancho",158],["Old_Persian",159],["Cuneiform",160],["Yezidi",161],["Yi",162],["Zanabazar_Square",163],["Inherited",164],["Unknown",165]]);
export const nameToTag = new Map([["Common",1684434036],["Adlam",1097100397],["",1097228651],["Caucasian_Albanian",1097295970],["Ahom",1097363309],["Arabic",1098015074],["Imperial_Aramaic",1098018153],["Armenian",1098018158],["Avestan",1098281844],["Balinese",1113681001],["Bamum",1113681269],["Bassa_Vah",1113682803],["Batak",1113683051],["Bengali",1113943655],["Bhaiksuki",1114139507],["Bopomofo",1114599535],["Brahmi",1114792296],["Braille",1114792297],["Buginese",1114990441],["Buhid",1114990692],["Chakma",1130457965],["Canadian_Aboriginal",1130458739],["Carian",1130459753],["Cham",1130914157],["Cherokee",1130915186],["Chorasmian",1130918515],["Coptic",1131376756],["Cypro_Minoan",1131441518],["Cypriot",1131442804],["Cyrillic",1132032620],["Devanagari",1147500129],["Dives_Akuru",1147756907],["Dogra",1148151666],["Deseret",1148416628],["Duployan",1148547180],["Egyptian_Hieroglyphs",1164409200],["Elbasan",1164730977],["Elymaic",1164736877],["Ethiopic",1165256809],["Georgian",1197829995],["Glagolitic",1198285159],["Gunjala_Gondi",1198485095],["Masaram_Gondi",1198485101],["Gothic",1198486632],["Grantha",1198678382],["Greek",1198679403],["Gujarati",1198877298],["Gurmukhi",1198879349],["Hangul",1214344807],["Han",1214344809],["Hanunoo",1214344815],["Hatran",1214346354],["Hebrew",1214603890],["Hiragana",1214870113],["Anatolian_Hieroglyphs",1215067511],["Pahawh_Hmong",1215131239],["Nyiakeng_Puachue_Hmong",1215131248],["Katakana_Or_Hiragana",1215458164],["Old_Hungarian",1215655527],["Old_Italic",1232363884],["Javanese",1247901281],["Kayah_Li",1264675945],["Katakana",1264676449],["Kawi",1264678761],["Kharoshthi",1265131890],["Khmer",1265134962],["Khojki",1265135466],["Khitan_Small_Script",1265202291],["Kannada",1265525857],["Kaithi",1265920105],["Tai_Tham",1281453665],["Lao",1281453935],["Latin",1281455214],["Lepcha",1281716323],["Limbu",1281977698],["Linear_A",1281977953],["Linear_B",1281977954],["Lisu",1281979253],["Lycian",1283023721],["Lydian",1283023977],["Mahajani",1298229354],["Makasar",1298230113],["Mandaic",1298230884],["Manichaean",1298230889],["Marchen",1298231907],["Medefaidrin",1298490470],["Mende_Kikakui",1298493028],["Meroitic_Cursive",1298494051],["Meroitic_Hieroglyphs",1298494063],["Malayalam",1298954605],["Modi",1299145833],["Mongolian",1299148391],["Mro",1299345263],["Meetei_Mayek",1299473769],["Multani",1299541108],["Myanmar",1299803506],["Nag_Mundari",1315006317],["Nandinagari",1315008100],["Old_North_Arabian",1315009122],["Nabataean",1315070324],["Newa",1315272545],["Nko",1315663727],["Nushu",1316186229],["Ogham",1332175213],["Ol_Chiki",1332503403],["Old_Turkic",1332898664],["Oriya",1332902241],["Osage",1332963173],["Osmanya",1332964705],["Old_Uyghur",1333094258],["Palmyrene",1348562029],["Pau_Cin_Hau",1348564323],["Old_Permic",1348825709],["Phags_Pa",1349017959],["Inscriptional_Pahlavi",1349020777],["Psalter_Pahlavi",1349020784],["Phoenician",1349021304],["Miao",1349284452],["Inscriptional_Parthian",1349678185],["Rejang",1382706791],["Hanifi_Rohingya",1383032935],["Runic",1383427698],["Samaritan",1398893938],["Old_South_Arabian",1398895202],["Saurashtra",1398895986],["SignWriting",1399287415],["Shavian",1399349623],["Sharada",1399353956],["Siddham",1399415908],["Khudawadi",1399418468],["Sinhala",1399418472],["Sogdian",1399809892],["Old_Sogdian",1399809903],["Sora_Sompeng",1399812705],["Soyombo",1399814511],["Sundanese",1400204900],["Syloti_Nagri",1400466543],["Syriac",1400468067],["Tagbanwa",1415669602],["Takri",1415670642],["Tai_Le",1415670885],["New_Tai_Lue",1415670901],["Tamil",1415671148],["Tangut",1415671399],["Tai_Viet",1415673460],["Telugu",1415933045],["Tifinagh",1415999079],["Tagalog",1416064103],["Thaana",1416126817],["Thai",1416126825],["Tibetan",1416192628],["Tirhuta",1416196712],["Tangsa",1416524641],["Toto",1416590447],["Ugaritic",1432838514],["Vai",1449224553],["Vithkuqi",1449751656],["Warang_Citi",1466004065],["Wancho",1466132591],["Old_Persian",1483761007],["Cuneiform",1483961720],["Yezidi",1499822697],["Yi",1500080489],["Zanabazar_Square",1516334690],["Inherited",1516858984],["Unknown",1517976186]]);
export const codeToName = new Map([[0,"Common"],[1,"Adlam"],[2,""],[3,"Caucasian_Albanian"],[4,"Ahom"],[5,"Arabic"],[6,"Imperial_Aramaic"],[7,"Armenian"],[8,"Avestan"],[9,"Balinese"],[10,"Bamum"],[11,"Bassa_Vah"],[12,"Batak"],[13,"Bengali"],[14,"Bhaiksuki"],[15,"Bopomofo"],[16,"Brahmi"],[17,"Braille"],[18,"Buginese"],[19,"Buhid"],[20,"Chakma"],[21,"Canadian_Aboriginal"],[22,"Carian"],[23,"Cham"],[24,"Cherokee"],[25,"Chorasmian"],[26,"Coptic"],[27,"Cypro_Minoan"],[28,"Cypriot"],[29,"Cyrillic"],[30,"Devanagari"],[31,"Dives_Akuru"],[32,"Dogra"],[33,"Deseret"],[34,"Duployan"],[35,"Egyptian_Hieroglyphs"],[36,"Elbasan"],[37,"Elymaic"],[38,"Ethiopic"],[39,"Georgian"],[40,"Glagolitic"],[41,"Gunjala_Gondi"],[42,"Masaram_Gondi"],[43,"Gothic"],[44,"Grantha"],[45,"Greek"],[46,"Gujarati"],[47,"Gurmukhi"],[48,"Hangul"],[49,"Han"],[50,"Hanunoo"],[51,"Hatran"],[52,"Hebrew"],[53,"Hiragana"],[54,"Anatolian_Hieroglyphs"],[55,"Pahawh_Hmong"],[56,"Nyiakeng_Puachue_Hmong"],[57,"Katakana_Or_Hiragana"],[58,"Old_Hungarian"],[59,"Old_Italic"],[60,"Javanese"],[61,"Kayah_Li"],[62,"Katakana"],[63,"Kawi"],[64,"Kharoshthi"],[65,"Khmer"],[66,"Khojki"],[67,"Khitan_Small_Script"],[68,"Kannada"],[69,"Kaithi"],[70,"Tai_Tham"],[71,"Lao"],[72,"Latin"],[73,"Lepcha"],[74,"Limbu"],[75,"Linear_A"],[76,"Linear_B"],[77,"Lisu"],[78,"Lycian"],[79,"Lydian"],[80,"Mahajani"],[81,"Makasar"],[82,"Mandaic"],[83,"Manichaean"],[84,"Marchen"],[85,"Medefaidrin"],[86,"Mende_Kikakui"],[87,"Meroitic_Cursive"],[88,"Meroitic_Hieroglyphs"],[89,"Malayalam"],[90,"Modi"],[91,"Mongolian"],[92,"Mro"],[93,"Meetei_Mayek"],[94,"Multani"],[95,"Myanmar"],[96,"Nag_Mundari"],[97,"Nandinagari"],[98,"Old_North_Arabian"],[99,"Nabataean"],[100,"Newa"],[101,"Nko"],[102,"Nushu"],[103,"Ogham"],[104,"Ol_Chiki"],[105,"Old_Turkic"],[106,"Oriya"],[107,"Osage"],[108,"Osmanya"],[109,"Old_Uyghur"],[110,"Palmyrene"],[111,"Pau_Cin_Hau"],[112,"Old_Permic"],[113,"Phags_Pa"],[114,"Inscriptional_Pahlavi"],[115,"Psalter_Pahlavi"],[116,"Phoenician"],[117,"Miao"],[118,"Inscriptional_Parthian"],[119,"Rejang"],[120,"Hanifi_Rohingya"],[121,"Runic"],[122,"Samaritan"],[123,"Old_South_Arabian"],[124,"Saurashtra"],[125,"SignWriting"],[126,"Shavian"],[127,"Sharada"],[128,"Siddham"],[129,"Khudawadi"],[130,"Sinhala"],[131,"Sogdian"],[132,"Old_Sogdian"],[133,"Sora_Sompeng"],[134,"Soyombo"],[135,"Sundanese"],[136,"Syloti_Nagri"],[137,"Syriac"],[138,"Tagbanwa"],[139,"Takri"],[140,"Tai_Le"],[141,"New_Tai_Lue"],[142,"Tamil"],[143,"Tangut"],[144,"Tai_Viet"],[145,"Telugu"],[146,"Tifinagh"],[147,"Tagalog"],[148,"Thaana"],[149,"Thai"],[150,"Tibetan"],[151,"Tirhuta"],[152,"Tangsa"],[153,"Toto"],[154,"Ugaritic"],[155,"Vai"],[156,"Vithkuqi"],[157,"Warang_Citi"],[158,"Wancho"],[159,"Old_Persian"],[160,"Cuneiform"],[161,"Yezidi"],[162,"Yi"],[163,"Zanabazar_Square"],[164,"Inherited"],[165,"Unknown"]]);
export const tagToCode = new Map([[1684434036,0],[1097100397,1],[1097228651,2],[1097295970,3],[1097363309,4],[1098015074,5],[1098018153,6],[1098018158,7],[1098281844,8],[1113681001,9],[1113681269,10],[1113682803,11],[1113683051,12],[1113943655,13],[1114139507,14],[1114599535,15],[1114792296,16],[1114792297,17],[1114990441,18],[1114990692,19],[1130457965,20],[1130458739,21],[1130459753,22],[1130914157,23],[1130915186,24],[1130918515,25],[1131376756,26],[1131441518,27],[1131442804,28],[1132032620,29],[1147500129,30],[1147756907,31],[1148151666,32],[1148416628,33],[1148547180,34],[1164409200,35],[1164730977,36],[1164736877,37],[1165256809,38],[1197829995,39],[1198285159,40],[1198485095,41],[1198485101,42],[1198486632,43],[1198678382,44],[1198679403,45],[1198877298,46],[1198879349,47],[1214344807,48],[1214344809,49],[1214344815,50],[1214346354,51],[1214603890,52],[1214870113,53],[1215067511,54],[1215131239,55],[1215131248,56],[1215458164,57],[1215655527,58],[1232363884,59],[1247901281,60],[1264675945,61],[1264676449,62],[1264678761,63],[1265131890,64],[1265134962,65],[1265135466,66],[1265202291,67],[1265525857,68],[1265920105,69],[1281453665,70],[1281453935,71],[1281455214,72],[1281716323,73],[1281977698,74],[1281977953,75],[1281977954,76],[1281979253,77],[1283023721,78],[1283023977,79],[1298229354,80],[1298230113,81],[1298230884,82],[1298230889,83],[1298231907,84],[1298490470,85],[1298493028,86],[1298494051,87],[1298494063,88],[1298954605,89],[1299145833,90],[1299148391,91],[1299345263,92],[1299473769,93],[1299541108,94],[1299803506,95],[1315006317,96],[1315008100,97],[1315009122,98],[1315070324,99],[1315272545,100],[1315663727,101],[1316186229,102],[1332175213,103],[1332503403,104],[1332898664,105],[1332902241,106],[1332963173,107],[1332964705,108],[1333094258,109],[1348562029,110],[1348564323,111],[1348825709,112],[1349017959,113],[1349020777,114],[1349020784,115],[1349021304,116],[1349284452,117],[1349678185,118],[1382706791,119],[1383032935,120],[1383427698,121],[1398893938,122],[1398895202,123],[1398895986,124],[1399287415,125],[1399349623,126],[1399353956,127],[1399415908,128],[1399418468,129],[1399418472,130],[1399809892,131],[1399809903,132],[1399812705,133],[1399814511,134],[1400204900,135],[1400466543,136],[1400468067,137],[1415669602,138],[1415670642,139],[1415670885,140],[1415670901,141],[1415671148,142],[1415671399,143],[1415673460,144],[1415933045,145],[1415999079,146],[1416064103,147],[1416126817,148],[1416126825,149],[1416192628,150],[1416196712,151],[1416524641,152],[1416590447,153],[1432838514,154],[1449224553,155],[1449751656,156],[1466004065,157],[1466132591,158],[1483761007,159],[1483961720,160],[1499822697,161],[1500080489,162],[1516334690,163],[1516858984,164],[1517976186,165]]);
19 changes: 12 additions & 7 deletions src/harfbuzz.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,8 @@ function createJsString(text: string) {
};
}

const langPtr = exports.malloc(3);

export class HbBuffer {
ptr: number;

Expand All @@ -312,6 +314,10 @@ export class HbBuffer {
return exports.hb_buffer_get_length(this.ptr);
}

setLength(length: number) {
exports.hb_buffer_set_length(this.ptr, length);
}

addText(text: string) {
const str = createJsString(text);
exports.hb_buffer_add_utf16(this.ptr, str.ptr, str.length, 0, str.length);
Expand Down Expand Up @@ -346,15 +352,14 @@ export class HbBuffer {
}

setLanguage(language: string) {
const str = createAsciiString(language);
exports.hb_buffer_set_language(this.ptr, exports.hb_language_from_string(str.ptr, -1));
str.free();
const len = Math.min(3, language.length);
const a = heapu8();
for (let i = 0; i < len; i++) a[langPtr + i] = language.codePointAt(i)!;
exports.hb_buffer_set_language(this.ptr, exports.hb_language_from_string(langPtr, len));
}

setScript(script: string) {
const str = createAsciiString(script);
exports.hb_buffer_set_script(this.ptr, exports.hb_script_from_string(str.ptr, -1));
str.free();
setScript(script: number) {
exports.hb_buffer_set_script(this.ptr, script);
}

setClusterLevel(level: number) {
Expand Down
24 changes: 13 additions & 11 deletions src/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {nextGraphemeBreak, previousGraphemeBreak} from './grapheme-break.js';
import {bidiIterator, emojiIterator, scriptIterator} from './itemize.js';
import * as hb from './harfbuzz.js';
import {getCascade} from './font.js';
import {nameToTag} from '../gen/script-names.js';

import type {FaceMatch} from './font.js';
import type {HbBuffer, HbFace, HbFont, AllocatedUint16Array} from './harfbuzz.js';
Expand Down Expand Up @@ -384,9 +385,7 @@ function loadHyphen(item: ShapedItem) {
const buf = hb.createBuffer();
buf.setClusterLevel(1);
buf.addText(hyphen);
buf.setScript('Latin');
buf.setDirection('ltr');
buf.setLanguage('en');
buf.guessSegmentProperties();
hb.shape(item.match.font, buf);
const glyphs = extractHbBufferGlyphs(buf);
buf.destroy();
Expand Down Expand Up @@ -1564,6 +1563,10 @@ function createIfcBuffer(text: string) {
return allocation;
}

const hbBuffer = hb.createBuffer();
hbBuffer.setClusterLevel(1);
hbBuffer.setFlags(['PRODUCE_UNSAFE_TO_CONCAT']);

export class Paragraph {
ifc: IfcInline;
string: string;
Expand Down Expand Up @@ -1730,14 +1733,13 @@ export class Paragraph {
}

shapePart(offset: number, length: number, font: HbFont, attrs: ShapingAttrs) {
const buf = hb.createBuffer();
buf.setClusterLevel(1);
buf.addUtf16(this.buffer.array.byteOffset, this.buffer.array.length, offset, length);
buf.guessSegmentProperties();
buf.setFlags(['PRODUCE_UNSAFE_TO_CONCAT']);
hb.shape(font, buf);
const array = extractHbBufferGlyphs(buf);
buf.destroy();
hbBuffer.setLength(0);
hbBuffer.addUtf16(this.buffer.array.byteOffset, this.buffer.array.length, offset, length);
hbBuffer.setScript(nameToTag.get(attrs.script)!);
hbBuffer.setLanguage(langForScript(attrs.script)); // TODO: [lang]
hbBuffer.setDirection(attrs.level & 1 ? 'rtl' : 'ltr');
hb.shape(font, hbBuffer);
const array = extractHbBufferGlyphs(hbBuffer);
return array;
}

Expand Down

0 comments on commit e9615ec

Please sign in to comment.