harfbuzzjs 0.4.14 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build.sh +1 -1
- package/config-override.h +2 -0
- package/examples/hb-subset.example.node.js +45 -45
- package/examples/hbjs.example.js +1 -1
- package/hb-subset.wasm +0 -0
- package/hb.js +1 -1
- package/hb.symbols +37 -0
- package/hb.wasm +0 -0
- package/hbjs.js +610 -16
- package/package.json +1 -1
- package/test/index.js +419 -2
package/hbjs.js
CHANGED
|
@@ -3,6 +3,7 @@ function hbjs(Module) {
|
|
|
3
3
|
|
|
4
4
|
var exports = Module.wasmExports;
|
|
5
5
|
var utf8Decoder = new TextDecoder("utf8");
|
|
6
|
+
var utf8Encoder = new TextEncoder("utf8");
|
|
6
7
|
let addFunction = Module.addFunction;
|
|
7
8
|
let removeFunction = Module.removeFunction;
|
|
8
9
|
|
|
@@ -15,24 +16,28 @@ function hbjs(Module) {
|
|
|
15
16
|
var GSUB_PHASE = 1;
|
|
16
17
|
var GPOS_PHASE = 2;
|
|
17
18
|
|
|
19
|
+
const STATIC_ARRAY_SIZE = 128
|
|
20
|
+
|
|
18
21
|
function hb_tag(s) {
|
|
19
22
|
return (
|
|
20
23
|
(s.charCodeAt(0) & 0xFF) << 24 |
|
|
21
24
|
(s.charCodeAt(1) & 0xFF) << 16 |
|
|
22
|
-
(s.charCodeAt(2) & 0xFF) <<
|
|
23
|
-
(s.charCodeAt(3) & 0xFF) <<
|
|
25
|
+
(s.charCodeAt(2) & 0xFF) << 8 |
|
|
26
|
+
(s.charCodeAt(3) & 0xFF) << 0
|
|
24
27
|
);
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
var HB_BUFFER_SERIALIZE_FORMAT_JSON
|
|
28
|
-
var HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES
|
|
30
|
+
var HB_BUFFER_SERIALIZE_FORMAT_JSON = hb_tag('JSON');
|
|
31
|
+
var HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 4;
|
|
32
|
+
|
|
33
|
+
const HB_OT_NAME_ID_INVALID = 0xFFFF;
|
|
29
34
|
|
|
30
35
|
function _hb_untag(tag) {
|
|
31
36
|
return [
|
|
32
37
|
String.fromCharCode((tag >> 24) & 0xFF),
|
|
33
38
|
String.fromCharCode((tag >> 16) & 0xFF),
|
|
34
|
-
String.fromCharCode((tag >>
|
|
35
|
-
String.fromCharCode((tag >>
|
|
39
|
+
String.fromCharCode((tag >> 8) & 0xFF),
|
|
40
|
+
String.fromCharCode((tag >> 0) & 0xFF)
|
|
36
41
|
].join('');
|
|
37
42
|
}
|
|
38
43
|
|
|
@@ -46,6 +51,19 @@ function hbjs(Module) {
|
|
|
46
51
|
return 0x0;
|
|
47
52
|
}
|
|
48
53
|
|
|
54
|
+
function _language_to_string(language) {
|
|
55
|
+
var ptr = exports.hb_language_to_string(language);
|
|
56
|
+
var str = utf8Decoder.decode(Module.HEAPU8.subarray(ptr, Module.HEAPU8.indexOf(0, ptr)));
|
|
57
|
+
return str;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function _language_from_string(str) {
|
|
61
|
+
var languageStr = createAsciiString(str);
|
|
62
|
+
var languagePtr = exports.hb_language_from_string(languageStr.ptr, -1);
|
|
63
|
+
languageStr.free();
|
|
64
|
+
return languagePtr;
|
|
65
|
+
}
|
|
66
|
+
|
|
49
67
|
/**
|
|
50
68
|
* Create an object representing a Harfbuzz blob.
|
|
51
69
|
* @param {string} blob A blob of binary data (usually the contents of a font file).
|
|
@@ -94,18 +112,18 @@ function hbjs(Module) {
|
|
|
94
112
|
* Return the binary contents of an OpenType table.
|
|
95
113
|
* @param {string} table Table name
|
|
96
114
|
*/
|
|
97
|
-
reference_table: function(table) {
|
|
115
|
+
reference_table: function (table) {
|
|
98
116
|
var blob = exports.hb_face_reference_table(ptr, hb_tag(table));
|
|
99
117
|
var length = exports.hb_blob_get_length(blob);
|
|
100
118
|
if (!length) { return; }
|
|
101
119
|
var blobptr = exports.hb_blob_get_data(blob, null);
|
|
102
|
-
var table_string = Module.HEAPU8.subarray(blobptr, blobptr+length);
|
|
120
|
+
var table_string = Module.HEAPU8.subarray(blobptr, blobptr + length);
|
|
103
121
|
return table_string;
|
|
104
122
|
},
|
|
105
123
|
/**
|
|
106
124
|
* Return variation axis infos
|
|
107
125
|
*/
|
|
108
|
-
getAxisInfos: function() {
|
|
126
|
+
getAxisInfos: function () {
|
|
109
127
|
var axis = exports.malloc(64 * 32);
|
|
110
128
|
var c = exports.malloc(4);
|
|
111
129
|
Module.HEAPU32[c / 4] = 64;
|
|
@@ -125,13 +143,180 @@ function hbjs(Module) {
|
|
|
125
143
|
/**
|
|
126
144
|
* Return unicodes the face supports
|
|
127
145
|
*/
|
|
128
|
-
collectUnicodes: function() {
|
|
146
|
+
collectUnicodes: function () {
|
|
129
147
|
var unicodeSetPtr = exports.hb_set_create();
|
|
130
148
|
exports.hb_face_collect_unicodes(ptr, unicodeSetPtr);
|
|
131
149
|
var result = typedArrayFromSet(unicodeSetPtr);
|
|
132
150
|
exports.hb_set_destroy(unicodeSetPtr);
|
|
133
151
|
return result;
|
|
134
152
|
},
|
|
153
|
+
/**
|
|
154
|
+
* Return all scripts enumerated in the specified face's
|
|
155
|
+
* GSUB table or GPOS table.
|
|
156
|
+
* @param {string} table: The table to query, either "GSUB" or "GPOS".
|
|
157
|
+
**/
|
|
158
|
+
getTableScriptTags: function (table) {
|
|
159
|
+
var tableTag = hb_tag(table);
|
|
160
|
+
var startOffset = 0;
|
|
161
|
+
var scriptCount = STATIC_ARRAY_SIZE;
|
|
162
|
+
var scriptCountPtr = Module.stackAlloc(4);
|
|
163
|
+
var scriptTagsPtr = Module.stackAlloc(STATIC_ARRAY_SIZE * 4);
|
|
164
|
+
var tags = [];
|
|
165
|
+
while (scriptCount == STATIC_ARRAY_SIZE) {
|
|
166
|
+
Module.HEAPU32[scriptCountPtr / 4] = scriptCount;
|
|
167
|
+
exports.hb_ot_layout_table_get_script_tags(ptr, tableTag, startOffset,
|
|
168
|
+
scriptCountPtr, scriptTagsPtr);
|
|
169
|
+
scriptCount = Module.HEAPU32[scriptCountPtr / 4];
|
|
170
|
+
var scriptTags = Module.HEAPU32.subarray(scriptTagsPtr / 4,
|
|
171
|
+
scriptTagsPtr / 4 + scriptCount);
|
|
172
|
+
tags.push(...Array.from(scriptTags).map(_hb_untag));
|
|
173
|
+
startOffset += scriptCount;
|
|
174
|
+
}
|
|
175
|
+
return tags;
|
|
176
|
+
},
|
|
177
|
+
/**
|
|
178
|
+
* Return all features enumerated in the specified face's
|
|
179
|
+
* GSUB table or GPOS table.
|
|
180
|
+
* @param {string} table: The table to query, either "GSUB" or "GPOS".
|
|
181
|
+
**/
|
|
182
|
+
getTableFeatureTags: function (table) {
|
|
183
|
+
var tableTag = hb_tag(table);
|
|
184
|
+
var startOffset = 0;
|
|
185
|
+
var featureCount = STATIC_ARRAY_SIZE;
|
|
186
|
+
var featureCountPtr = Module.stackAlloc(4);
|
|
187
|
+
var featureTagsPtr = Module.stackAlloc(STATIC_ARRAY_SIZE * 4);
|
|
188
|
+
var tags = [];
|
|
189
|
+
while (featureCount == STATIC_ARRAY_SIZE) {
|
|
190
|
+
Module.HEAPU32[featureCountPtr / 4] = featureCount;
|
|
191
|
+
exports.hb_ot_layout_table_get_feature_tags(ptr, tableTag, startOffset,
|
|
192
|
+
featureCountPtr, featureTagsPtr);
|
|
193
|
+
featureCount = Module.HEAPU32[featureCountPtr / 4];
|
|
194
|
+
var scriptTags = Module.HEAPU32.subarray(featureTagsPtr / 4,
|
|
195
|
+
featureTagsPtr / 4 + featureCount);
|
|
196
|
+
tags.push(...Array.from(scriptTags).map(_hb_untag));
|
|
197
|
+
startOffset += featureCount;
|
|
198
|
+
}
|
|
199
|
+
return tags;
|
|
200
|
+
},
|
|
201
|
+
/**
|
|
202
|
+
* Return language tags in the given face's GSUB or GPOS table, underneath
|
|
203
|
+
* the specified script index.
|
|
204
|
+
* @param {string} table: The table to query, either "GSUB" or "GPOS".
|
|
205
|
+
* @param {number} scriptIndex: The index of the script to query.
|
|
206
|
+
**/
|
|
207
|
+
getScriptLanguageTags: function (table, scriptIndex) {
|
|
208
|
+
var tableTag = hb_tag(table);
|
|
209
|
+
var startOffset = 0;
|
|
210
|
+
var languageCount = STATIC_ARRAY_SIZE;
|
|
211
|
+
var languageCountPtr = Module.stackAlloc(4);
|
|
212
|
+
var languageTagsPtr = Module.stackAlloc(STATIC_ARRAY_SIZE * 4);
|
|
213
|
+
var tags = [];
|
|
214
|
+
while (languageCount == STATIC_ARRAY_SIZE) {
|
|
215
|
+
Module.HEAPU32[languageCountPtr / 4] = languageCount;
|
|
216
|
+
exports.hb_ot_layout_script_get_language_tags(ptr, tableTag, scriptIndex, startOffset,
|
|
217
|
+
languageCountPtr, languageTagsPtr);
|
|
218
|
+
languageCount = Module.HEAPU32[languageCountPtr / 4];
|
|
219
|
+
var languageTags = Module.HEAPU32.subarray(languageTagsPtr / 4,
|
|
220
|
+
languageTagsPtr / 4 + languageCount);
|
|
221
|
+
tags.push(...Array.from(languageTags).map(_hb_untag));
|
|
222
|
+
startOffset += languageCount;
|
|
223
|
+
}
|
|
224
|
+
return tags;
|
|
225
|
+
},
|
|
226
|
+
/**
|
|
227
|
+
* Return all features in the specified face's GSUB table or GPOS table,
|
|
228
|
+
* underneath the specified script and language.
|
|
229
|
+
* @param {string} table: The table to query, either "GSUB" or "GPOS".
|
|
230
|
+
* @param {number} scriptIndex: The index of the script to query.
|
|
231
|
+
* @param {number} languageIndex: The index of the language to query.
|
|
232
|
+
**/
|
|
233
|
+
getLanguageFeatureTags: function (table, scriptIndex, languageIndex) {
|
|
234
|
+
var tableTag = hb_tag(table);
|
|
235
|
+
var startOffset = 0;
|
|
236
|
+
var featureCount = STATIC_ARRAY_SIZE;
|
|
237
|
+
var featureCountPtr = Module.stackAlloc(4);
|
|
238
|
+
var featureTagsPtr = Module.stackAlloc(STATIC_ARRAY_SIZE * 4);
|
|
239
|
+
var tags = [];
|
|
240
|
+
while (featureCount == STATIC_ARRAY_SIZE) {
|
|
241
|
+
Module.HEAPU32[featureCountPtr / 4] = featureCount;
|
|
242
|
+
exports.hb_ot_layout_language_get_feature_tags(ptr, tableTag, scriptIndex, languageIndex, startOffset,
|
|
243
|
+
featureCountPtr, featureTagsPtr);
|
|
244
|
+
featureCount = Module.HEAPU32[featureCountPtr / 4];
|
|
245
|
+
var featureTags = Module.HEAPU32.subarray(featureTagsPtr / 4,
|
|
246
|
+
featureTagsPtr / 4 + featureCount);
|
|
247
|
+
tags.push(...Array.from(featureTags).map(_hb_untag));
|
|
248
|
+
startOffset += featureCount;
|
|
249
|
+
}
|
|
250
|
+
return tags;
|
|
251
|
+
},
|
|
252
|
+
/**
|
|
253
|
+
* Return all names in the specified face's name table.
|
|
254
|
+
**/
|
|
255
|
+
listNames: function () {
|
|
256
|
+
var numEntriesPtr = Module.stackAlloc(4);
|
|
257
|
+
var entriesPtr = exports.hb_ot_name_list_names(ptr, numEntriesPtr);
|
|
258
|
+
var numEntries = Module.HEAPU32[numEntriesPtr / 4];
|
|
259
|
+
var entries = [];
|
|
260
|
+
for (var i = 0; i < numEntries; i++) {
|
|
261
|
+
// FIXME: this depends on the struct memory layout.
|
|
262
|
+
// A more robust way would involve ading helper C functions to access
|
|
263
|
+
// the struct and use them here.
|
|
264
|
+
entries.push({
|
|
265
|
+
nameId: Module.HEAPU32[(entriesPtr / 4) + (i * 3)],
|
|
266
|
+
language: _language_to_string(Module.HEAPU32[(entriesPtr / 4) + (i * 3) + 2])
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return entries;
|
|
270
|
+
},
|
|
271
|
+
/**
|
|
272
|
+
* Get the name of the specified face.
|
|
273
|
+
* @param {number} nameId The ID of the name to get.
|
|
274
|
+
* @param {string} language The language of the name to get.
|
|
275
|
+
**/
|
|
276
|
+
getName: function (nameId, language) {
|
|
277
|
+
var languagePtr = _language_from_string(language);
|
|
278
|
+
var nameLen = exports.hb_ot_name_get_utf16(ptr, nameId, languagePtr, 0, 0) + 1;
|
|
279
|
+
var textSizePtr = Module.stackAlloc(4);
|
|
280
|
+
var textPtr = exports.malloc(nameLen * 2);
|
|
281
|
+
Module.HEAPU32[textSizePtr / 4] = nameLen;
|
|
282
|
+
exports.hb_ot_name_get_utf16(ptr, nameId, languagePtr, textSizePtr, textPtr);
|
|
283
|
+
var name = String.fromCharCode.apply(null, Module.HEAPU16.subarray(textPtr / 2, textPtr / 2 + nameLen - 1));
|
|
284
|
+
exports.free(textPtr);
|
|
285
|
+
return name;
|
|
286
|
+
},
|
|
287
|
+
/**
|
|
288
|
+
* Get the name IDs of the specified feature.
|
|
289
|
+
* @param {string} table The table to query, either "GSUB" or "GPOS".
|
|
290
|
+
* @param {number} featureIndex The index of the feature to query.
|
|
291
|
+
**/
|
|
292
|
+
getFeatureNameIds: function (table, featureIndex) {
|
|
293
|
+
var tableTag = hb_tag(table);
|
|
294
|
+
var labelIdPtr = Module.stackAlloc(4);
|
|
295
|
+
var tooltipIdPtr = Module.stackAlloc(4);
|
|
296
|
+
var sampleIdPtr = Module.stackAlloc(4);
|
|
297
|
+
var numNamedParametersPtr = Module.stackAlloc(4);
|
|
298
|
+
var firstParameterIdPtr = Module.stackAlloc(4);
|
|
299
|
+
|
|
300
|
+
var found = exports.hb_ot_layout_feature_get_name_ids(ptr, tableTag, featureIndex,
|
|
301
|
+
labelIdPtr, tooltipIdPtr, sampleIdPtr, numNamedParametersPtr, firstParameterIdPtr);
|
|
302
|
+
|
|
303
|
+
if (found) {
|
|
304
|
+
let uiLabelNameId = Module.HEAPU32[labelIdPtr / 4];
|
|
305
|
+
let uiTooltipTextNameId = Module.HEAPU32[tooltipIdPtr / 4];
|
|
306
|
+
let sampleTextNameId = Module.HEAPU32[sampleIdPtr / 4];
|
|
307
|
+
let numNamedParameters = Module.HEAPU32[numNamedParametersPtr / 4];
|
|
308
|
+
let firstParameterId = Module.HEAPU32[firstParameterIdPtr / 4];
|
|
309
|
+
let paramUiLabelNameIds = Array(numNamedParameters).fill().map((_, i) => firstParameterId + i);
|
|
310
|
+
return {
|
|
311
|
+
uiLabelNameId: uiLabelNameId == HB_OT_NAME_ID_INVALID ? null : uiLabelNameId,
|
|
312
|
+
uiTooltipTextNameId: uiTooltipTextNameId == HB_OT_NAME_ID_INVALID ? null : uiTooltipTextNameId,
|
|
313
|
+
sampleTextNameId: sampleTextNameId == HB_OT_NAME_ID_INVALID ? null : sampleTextNameId,
|
|
314
|
+
paramUiLabelNameIds: paramUiLabelNameIds
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return null;
|
|
319
|
+
},
|
|
135
320
|
/**
|
|
136
321
|
* Free the object.
|
|
137
322
|
*/
|
|
@@ -149,9 +334,10 @@ function hbjs(Module) {
|
|
|
149
334
|
/**
|
|
150
335
|
* Create an object representing a Harfbuzz font.
|
|
151
336
|
* @param {object} blob An object returned from `createFace`.
|
|
337
|
+
* @param {number} ptr Optional pointer to an existing font.
|
|
152
338
|
**/
|
|
153
|
-
function createFont(face) {
|
|
154
|
-
var ptr = exports.hb_font_create(face.ptr);
|
|
339
|
+
function createFont(face, ptr) {
|
|
340
|
+
var ptr = ptr ? exports.hb_font_reference(ptr) : exports.hb_font_create(face.ptr);
|
|
155
341
|
var drawFuncsPtr = null;
|
|
156
342
|
var moveToPtr = null;
|
|
157
343
|
var lineToPtr = null;
|
|
@@ -216,8 +402,110 @@ function hbjs(Module) {
|
|
|
216
402
|
|
|
217
403
|
return {
|
|
218
404
|
ptr: ptr,
|
|
405
|
+
/**
|
|
406
|
+
* Create a sub font.
|
|
407
|
+
* @returns {object} Object representing the sub font.
|
|
408
|
+
**/
|
|
409
|
+
subFont: function () {
|
|
410
|
+
return createFont(null, exports.hb_font_create_sub_font(ptr));
|
|
411
|
+
},
|
|
412
|
+
/**
|
|
413
|
+
* Return font horizontal extents.
|
|
414
|
+
* @returns {object} Object with ascender, descender, and lineGap properties.
|
|
415
|
+
**/
|
|
416
|
+
hExtents: function () {
|
|
417
|
+
var extentsPtr = Module.stackAlloc(12);
|
|
418
|
+
exports.hb_font_get_h_extents(ptr, extentsPtr);
|
|
419
|
+
return {
|
|
420
|
+
ascender: Module.HEAP32[extentsPtr / 4],
|
|
421
|
+
descender: Module.HEAP32[extentsPtr / 4 + 1],
|
|
422
|
+
lineGap: Module.HEAP32[extentsPtr / 4 + 2],
|
|
423
|
+
};
|
|
424
|
+
},
|
|
425
|
+
/**
|
|
426
|
+
* Return font vertical extents.
|
|
427
|
+
* @returns {object} Object with ascender, descender, and lineGap properties.
|
|
428
|
+
**/
|
|
429
|
+
vExtents: function () {
|
|
430
|
+
var extentsPtr = Module.stackAlloc(12);
|
|
431
|
+
exports.hb_font_get_v_extents(ptr, extentsPtr);
|
|
432
|
+
return {
|
|
433
|
+
ascender: Module.HEAP32[extentsPtr / 4],
|
|
434
|
+
descender: Module.HEAP32[extentsPtr / 4 + 1],
|
|
435
|
+
lineGap: Module.HEAP32[extentsPtr / 4 + 2],
|
|
436
|
+
};
|
|
437
|
+
},
|
|
219
438
|
glyphName: glyphName,
|
|
220
439
|
glyphToPath: glyphToPath,
|
|
440
|
+
/**
|
|
441
|
+
* Return glyph horizontal advance.
|
|
442
|
+
* @param {number} glyphId ID of the requested glyph in the font.
|
|
443
|
+
**/
|
|
444
|
+
glyphHAdvance: function (glyphId) {
|
|
445
|
+
return exports.hb_font_get_glyph_h_advance(ptr, glyphId);
|
|
446
|
+
},
|
|
447
|
+
/**
|
|
448
|
+
* Return glyph vertical advance.
|
|
449
|
+
* @param {number} glyphId ID of the requested glyph in the font.
|
|
450
|
+
**/
|
|
451
|
+
glyphVAdvance: function (glyphId) {
|
|
452
|
+
return exports.hb_font_get_glyph_v_advance(ptr, glyphId);
|
|
453
|
+
},
|
|
454
|
+
/**
|
|
455
|
+
* Return glyph horizontal origin.
|
|
456
|
+
* @param {number} glyphId ID of the requested glyph in the font.
|
|
457
|
+
**/
|
|
458
|
+
glyphHOrigin: function (glyphId) {
|
|
459
|
+
let xPtr = Module.stackAlloc(4);
|
|
460
|
+
let yPtr = Module.stackAlloc(4);
|
|
461
|
+
if (exports.hb_font_get_glyph_h_origin(ptr, glyphId, xPtr, yPtr)) {
|
|
462
|
+
return [Module.HEAP32[xPtr / 4], Module.HEAP32[yPtr / 4]];
|
|
463
|
+
}
|
|
464
|
+
return null;
|
|
465
|
+
},
|
|
466
|
+
/**
|
|
467
|
+
* Return glyph vertical origin.
|
|
468
|
+
* @param {number} glyphId ID of the requested glyph in the font.
|
|
469
|
+
**/
|
|
470
|
+
glyphVOrigin: function (glyphId) {
|
|
471
|
+
let xPtr = Module.stackAlloc(4);
|
|
472
|
+
let yPtr = Module.stackAlloc(4);
|
|
473
|
+
if (exports.hb_font_get_glyph_v_origin(ptr, glyphId, xPtr, yPtr)) {
|
|
474
|
+
return [Module.HEAP32[xPtr / 4], Module.HEAP32[yPtr / 4]];
|
|
475
|
+
}
|
|
476
|
+
return null;
|
|
477
|
+
},
|
|
478
|
+
/**
|
|
479
|
+
* Return glyph extents.
|
|
480
|
+
* @param {number} glyphId ID of the requested glyph in the font.
|
|
481
|
+
**/
|
|
482
|
+
glyphExtents: function (glyphId) {
|
|
483
|
+
var extentsPtr = Module.stackAlloc(16);
|
|
484
|
+
if (exports.hb_font_get_glyph_extents(ptr, glyphId, extentsPtr)) {
|
|
485
|
+
return {
|
|
486
|
+
xBearing: Module.HEAP32[extentsPtr / 4],
|
|
487
|
+
yBearing: Module.HEAP32[extentsPtr / 4 + 1],
|
|
488
|
+
width: Module.HEAP32[extentsPtr / 4 + 2],
|
|
489
|
+
height: Module.HEAP32[extentsPtr / 4 + 3]
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
return null;
|
|
493
|
+
},
|
|
494
|
+
/**
|
|
495
|
+
* Return glyph ID from name.
|
|
496
|
+
* @param {string} name Name of the requested glyph in the font.
|
|
497
|
+
**/
|
|
498
|
+
glyphFromName: function (name) {
|
|
499
|
+
var glyphId = null;
|
|
500
|
+
var glyphIdPtr = Module.stackAlloc(4);
|
|
501
|
+
var namePtr = exports.malloc(name.length + 1);
|
|
502
|
+
utf8Encoder.encodeInto(name, Module.HEAPU8.subarray(namePtr, namePtr + name.length));
|
|
503
|
+
if (exports.hb_font_get_glyph_from_name(ptr, namePtr, name.length, glyphIdPtr)) {
|
|
504
|
+
glyphId = Module.HEAPU32[glyphIdPtr / 4];
|
|
505
|
+
}
|
|
506
|
+
exports.free(namePtr);
|
|
507
|
+
return glyphId;
|
|
508
|
+
},
|
|
221
509
|
/**
|
|
222
510
|
* Return a glyph as a JSON path string
|
|
223
511
|
* based on format described on https://svgwg.org/specs/paths/#InterfaceSVGPathSegment
|
|
@@ -254,6 +542,13 @@ function hbjs(Module) {
|
|
|
254
542
|
exports.free(vars);
|
|
255
543
|
},
|
|
256
544
|
/**
|
|
545
|
+
* Set the font's font functions.
|
|
546
|
+
* @param {object} fontFuncs The font functions.
|
|
547
|
+
**/
|
|
548
|
+
setFuncs: function (fontFuncs) {
|
|
549
|
+
exports.hb_font_set_funcs(ptr, fontFuncs.ptr);
|
|
550
|
+
},
|
|
551
|
+
/**
|
|
257
552
|
* Free the object.
|
|
258
553
|
*/
|
|
259
554
|
destroy: function () {
|
|
@@ -271,6 +566,304 @@ function hbjs(Module) {
|
|
|
271
566
|
};
|
|
272
567
|
}
|
|
273
568
|
|
|
569
|
+
/**
|
|
570
|
+
* Create a object representing a HarfBuzz font functions.
|
|
571
|
+
**/
|
|
572
|
+
function createFontFuncs() {
|
|
573
|
+
var ptr = exports.hb_font_funcs_create();
|
|
574
|
+
return {
|
|
575
|
+
ptr: ptr,
|
|
576
|
+
/**
|
|
577
|
+
* Set the font's glyph extents function.
|
|
578
|
+
* @param {function} func The function to set.
|
|
579
|
+
*
|
|
580
|
+
* The function takes the following arguments:
|
|
581
|
+
* @param {object} font The font.
|
|
582
|
+
* @param {number} glyph The glyph ID.
|
|
583
|
+
*
|
|
584
|
+
* The function should return an object with the following properties, or null on failure:
|
|
585
|
+
* @param {number} xBearing The x bearing of the glyph.
|
|
586
|
+
* @param {number} yBearing The y bearing of the glyph.
|
|
587
|
+
* @param {number} width The width of the glyph.
|
|
588
|
+
* @param {number} height The height of the glyph.
|
|
589
|
+
**/
|
|
590
|
+
setGlyphExtentsFunc: function (func) {
|
|
591
|
+
let funcPtr = addFunction(function (fontPtr, font_data, glyph, extentsPtr, user_data) {
|
|
592
|
+
let font = createFont(null, fontPtr);
|
|
593
|
+
let extents = func(font, glyph);
|
|
594
|
+
font.destroy();
|
|
595
|
+
if (extents) {
|
|
596
|
+
Module.HEAP32[extentsPtr / 4] = extents.xBearing;
|
|
597
|
+
Module.HEAP32[extentsPtr / 4 + 1] = extents.yBearing;
|
|
598
|
+
Module.HEAP32[extentsPtr / 4 + 2] = extents.width;
|
|
599
|
+
Module.HEAP32[extentsPtr / 4 + 3] = extents.height;
|
|
600
|
+
return 1;
|
|
601
|
+
}
|
|
602
|
+
return 0;
|
|
603
|
+
}, 'ippipp');
|
|
604
|
+
exports.hb_font_funcs_set_glyph_extents_func(ptr, funcPtr, 0, 0);
|
|
605
|
+
},
|
|
606
|
+
/**
|
|
607
|
+
* Set the font's glyph from name function.
|
|
608
|
+
* @param {function} func The function to set.
|
|
609
|
+
*
|
|
610
|
+
* The function takes the following arguments:
|
|
611
|
+
* @param {object} font The font.
|
|
612
|
+
* @param {string} name The glyph name.
|
|
613
|
+
*
|
|
614
|
+
* The function should return an object with the following properties, or null on failure:
|
|
615
|
+
* @param {number} glyph The glyph ID.
|
|
616
|
+
**/
|
|
617
|
+
setGlyphFromNameFunc: function (func) {
|
|
618
|
+
let funcPtr = addFunction(function (fontPtr, font_data, namePtr, len, glyphPtr, user_data) {
|
|
619
|
+
let font = createFont(null, fontPtr);
|
|
620
|
+
let name = utf8Decoder.decode(Module.HEAPU8.subarray(namePtr, namePtr + len));
|
|
621
|
+
let glyph = func(font, name);
|
|
622
|
+
font.destroy();
|
|
623
|
+
if (glyph) {
|
|
624
|
+
Module.HEAPU32[glyphPtr / 4] = glyph;
|
|
625
|
+
return 1;
|
|
626
|
+
}
|
|
627
|
+
return 0;
|
|
628
|
+
}, 'ipppipp');
|
|
629
|
+
exports.hb_font_funcs_set_glyph_from_name_func(ptr, funcPtr, 0, 0);
|
|
630
|
+
},
|
|
631
|
+
/**
|
|
632
|
+
* Set the font's glyph horizontal advance function.
|
|
633
|
+
* @param {function} func The function to set.
|
|
634
|
+
*
|
|
635
|
+
* The function takes the following arguments:
|
|
636
|
+
* @param {object} font The font.
|
|
637
|
+
* @param {number} glyph The glyph ID.
|
|
638
|
+
*
|
|
639
|
+
* The function should return the horizontal advance of the glyph.
|
|
640
|
+
**/
|
|
641
|
+
setGlyphHAdvanceFunc: function (func) {
|
|
642
|
+
let funcPtr = addFunction(function (fontPtr, font_data, glyph, user_data) {
|
|
643
|
+
let font = createFont(null, fontPtr);
|
|
644
|
+
let advance = func(font, glyph);
|
|
645
|
+
font.destroy();
|
|
646
|
+
return advance;
|
|
647
|
+
}, 'ippip');
|
|
648
|
+
exports.hb_font_funcs_set_glyph_h_advance_func(ptr, funcPtr, 0, 0);
|
|
649
|
+
},
|
|
650
|
+
/**
|
|
651
|
+
* Set the font's glyph vertical advance function.
|
|
652
|
+
* @param {function} func The function to set.
|
|
653
|
+
*
|
|
654
|
+
* The function takes the following arguments:
|
|
655
|
+
* @param {object} font The font.
|
|
656
|
+
* @param {number} glyph The glyph ID.
|
|
657
|
+
*
|
|
658
|
+
* The function should return the vertical advance of the glyph.
|
|
659
|
+
**/
|
|
660
|
+
setGlyphVAdvanceFunc: function (func) {
|
|
661
|
+
let funcPtr = addFunction(function (fontPtr, font_data, glyph, user_data) {
|
|
662
|
+
let font = createFont(null, fontPtr);
|
|
663
|
+
let advance = func(font, glyph);
|
|
664
|
+
font.destroy();
|
|
665
|
+
return advance;
|
|
666
|
+
}, 'ippip');
|
|
667
|
+
exports.hb_font_funcs_set_glyph_v_advance_func(ptr, funcPtr, 0, 0);
|
|
668
|
+
},
|
|
669
|
+
/**
|
|
670
|
+
* Set the font's glyph horizontal origin function.
|
|
671
|
+
* @param {function} func The function to set.
|
|
672
|
+
*
|
|
673
|
+
* The function takes the following arguments:
|
|
674
|
+
* @param {object} font The font.
|
|
675
|
+
* @param {number} glyph The glyph ID.
|
|
676
|
+
*
|
|
677
|
+
* The function should return the x and y horizontal origin of the glyph, or null on failure.
|
|
678
|
+
**/
|
|
679
|
+
setGlyphHOriginFunc: function (func) {
|
|
680
|
+
let funcPtr = addFunction(function (fontPtr, font_data, glyph, xPtr, yPtr, user_data) {
|
|
681
|
+
let font = createFont(null, fontPtr);
|
|
682
|
+
let origin = func(font, glyph);
|
|
683
|
+
font.destroy();
|
|
684
|
+
if (origin) {
|
|
685
|
+
Module.HEAP32[xPtr / 4] = origin[0];
|
|
686
|
+
Module.HEAP32[yPtr / 4] = origin[1];
|
|
687
|
+
return 1;
|
|
688
|
+
}
|
|
689
|
+
return 0;
|
|
690
|
+
}, 'ippippp');
|
|
691
|
+
exports.hb_font_funcs_set_glyph_h_origin_func(ptr, funcPtr, 0, 0);
|
|
692
|
+
},
|
|
693
|
+
/**
|
|
694
|
+
* Set the font's glyph vertical origin function.
|
|
695
|
+
* @param {function} func The function to set.
|
|
696
|
+
*
|
|
697
|
+
* The function takes the following arguments:
|
|
698
|
+
* @param {object} font The font.
|
|
699
|
+
* @param {number} glyph The glyph ID.
|
|
700
|
+
*
|
|
701
|
+
* The function should return the x and y vertical origin of the glyph, or null on failure.
|
|
702
|
+
**/
|
|
703
|
+
setGlyphVOriginFunc: function (func) {
|
|
704
|
+
let funcPtr = addFunction(function (fontPtr, font_data, glyph, xPtr, yPtr, user_data) {
|
|
705
|
+
let font = createFont(null, fontPtr);
|
|
706
|
+
let origin = func(font, glyph);
|
|
707
|
+
font.destroy();
|
|
708
|
+
if (origin) {
|
|
709
|
+
Module.HEAP32[xPtr / 4] = origin[0];
|
|
710
|
+
Module.HEAP32[yPtr / 4] = origin[1];
|
|
711
|
+
return 1;
|
|
712
|
+
}
|
|
713
|
+
return 0;
|
|
714
|
+
}, 'ippippp');
|
|
715
|
+
exports.hb_font_funcs_set_glyph_v_origin_func(ptr, funcPtr, 0, 0);
|
|
716
|
+
},
|
|
717
|
+
/**
|
|
718
|
+
* Set the font's glyph horizontal kerning function.
|
|
719
|
+
* @param {function} func The function to set.
|
|
720
|
+
*
|
|
721
|
+
* The function takes the following arguments:
|
|
722
|
+
* @param {object} font The font.
|
|
723
|
+
* @param {number} firstGlyph The first glyph ID.
|
|
724
|
+
* @param {number} secondGlyph The second glyph ID.
|
|
725
|
+
*
|
|
726
|
+
* The function should return the horizontal kerning of the glyphs.
|
|
727
|
+
**/
|
|
728
|
+
setGlyphHKerningFunc: function (func) {
|
|
729
|
+
let funcPtr = addFunction(function (fontPtr, font_data, firstGlyph, secondGlyph, user_data) {
|
|
730
|
+
let font = createFont(null, fontPtr);
|
|
731
|
+
let kerning = func(font, firstGlyph, secondGlyph);
|
|
732
|
+
font.destroy();
|
|
733
|
+
return kerning;
|
|
734
|
+
}, 'ippiip');
|
|
735
|
+
exports.hb_font_funcs_set_glyph_h_kerning_func(ptr, funcPtr, 0, 0);
|
|
736
|
+
},
|
|
737
|
+
/**
|
|
738
|
+
* Set the font's glyph name function.
|
|
739
|
+
* @param {function} func The function to set.
|
|
740
|
+
*
|
|
741
|
+
* The function takes the following arguments:
|
|
742
|
+
* @param {object} font The font.
|
|
743
|
+
* @param {number} glyph The glyph ID.
|
|
744
|
+
*
|
|
745
|
+
* The function should return the name of the glyph, or null on failure.
|
|
746
|
+
**/
|
|
747
|
+
setGlyphNameFunc: function (func) {
|
|
748
|
+
let funcPtr = addFunction(function (fontPtr, font_data, glyph, namePtr, size, user_data) {
|
|
749
|
+
let font = createFont(null, fontPtr);
|
|
750
|
+
let name = func(font, glyph);
|
|
751
|
+
font.destroy();
|
|
752
|
+
if (name) {
|
|
753
|
+
utf8Encoder.encodeInto(name, Module.HEAPU8.subarray(namePtr, namePtr + size));
|
|
754
|
+
return 1;
|
|
755
|
+
}
|
|
756
|
+
return 0;
|
|
757
|
+
}, 'ippipip');
|
|
758
|
+
exports.hb_font_funcs_set_glyph_name_func(ptr, funcPtr, 0, 0);
|
|
759
|
+
},
|
|
760
|
+
/**
|
|
761
|
+
* Set the font's nominal glyph function.
|
|
762
|
+
* @param {function} func The function to set.
|
|
763
|
+
*
|
|
764
|
+
* The function takes the following arguments:
|
|
765
|
+
* @param {object} font The font.
|
|
766
|
+
* @param {number} unicode The unicode.
|
|
767
|
+
*
|
|
768
|
+
* The function should return the nominal glyph of the unicode, or null on failure.
|
|
769
|
+
**/
|
|
770
|
+
setNominalGlyphFunc: function (func) {
|
|
771
|
+
let funcPtr = addFunction(function (fontPtr, font_data, unicode, glyphPtr, user_data) {
|
|
772
|
+
let font = createFont(null, fontPtr);
|
|
773
|
+
let glyph = func(font, unicode);
|
|
774
|
+
font.destroy();
|
|
775
|
+
if (glyph) {
|
|
776
|
+
Module.HEAPU32[glyphPtr / 4] = glyph;
|
|
777
|
+
return 1;
|
|
778
|
+
}
|
|
779
|
+
return 0;
|
|
780
|
+
}, 'ippipp');
|
|
781
|
+
exports.hb_font_funcs_set_nominal_glyph_func(ptr, funcPtr, 0, 0);
|
|
782
|
+
},
|
|
783
|
+
/**
|
|
784
|
+
* Set the font's variation glyph function.
|
|
785
|
+
* @param {function} func The function to set.
|
|
786
|
+
*
|
|
787
|
+
* The function takes the following arguments:
|
|
788
|
+
* @param {object} font The font.
|
|
789
|
+
* @param {number} unicode The unicode.
|
|
790
|
+
* @param {number} variationSelector The variation selector.
|
|
791
|
+
*
|
|
792
|
+
* The function should return the variation glyph of the unicode, or null on failure.
|
|
793
|
+
**/
|
|
794
|
+
setVariationGlyphFunc: function (func) {
|
|
795
|
+
let funcPtr = addFunction(function (fontPtr, font_data, unicode, variationSelector, glyphPtr, user_data) {
|
|
796
|
+
let font = createFont(null, fontPtr);
|
|
797
|
+
let glyph = func(font, unicode, variationSelector);
|
|
798
|
+
font.destroy();
|
|
799
|
+
if (glyph) {
|
|
800
|
+
Module.HEAPU32[glyphPtr / 4] = glyph;
|
|
801
|
+
return 1;
|
|
802
|
+
}
|
|
803
|
+
return 0;
|
|
804
|
+
}, 'ippiipp');
|
|
805
|
+
exports.hb_font_funcs_set_variation_glyph_func(ptr, funcPtr, 0, 0);
|
|
806
|
+
},
|
|
807
|
+
/**
|
|
808
|
+
* Set the font's horizontal extents function.
|
|
809
|
+
* @param {function} func The function to set.
|
|
810
|
+
*
|
|
811
|
+
* The function takes the following arguments:
|
|
812
|
+
* @param {object} font The font.
|
|
813
|
+
*
|
|
814
|
+
* The function should return an object with the following properties, or null on failure:
|
|
815
|
+
* @param {number} ascender The ascender of the font.
|
|
816
|
+
* @param {number} descender The descender of the font.
|
|
817
|
+
* @param {number} lineGap The line gap of the font.
|
|
818
|
+
**/
|
|
819
|
+
setFontHExtentsFunc: function (func) {
|
|
820
|
+
let funcPtr = addFunction(function (fontPtr, font_data, extentsPtr, user_data) {
|
|
821
|
+
let font = createFont(null, fontPtr);
|
|
822
|
+
let extents = func(font);
|
|
823
|
+
font.destroy();
|
|
824
|
+
if (extents) {
|
|
825
|
+
Module.HEAP32[extentsPtr / 4] = extents.ascender;
|
|
826
|
+
Module.HEAP32[extentsPtr / 4 + 1] = extents.descender;
|
|
827
|
+
Module.HEAP32[extentsPtr / 4 + 2] = extents.lineGap;
|
|
828
|
+
return 1;
|
|
829
|
+
}
|
|
830
|
+
return 0;
|
|
831
|
+
}, 'ipppp');
|
|
832
|
+
exports.hb_font_funcs_set_font_h_extents_func(ptr, funcPtr, 0, 0);
|
|
833
|
+
},
|
|
834
|
+
/**
|
|
835
|
+
* Set the font's vertical extents function.
|
|
836
|
+
* @param {function} func The function to set.
|
|
837
|
+
*
|
|
838
|
+
* The function takes the following arguments:
|
|
839
|
+
* @param {object} font The font.
|
|
840
|
+
*
|
|
841
|
+
* The function should return an object with the following properties, or null on failure:
|
|
842
|
+
* @param {number} ascender The ascender of the font.
|
|
843
|
+
* @param {number} descender The descender of the font.
|
|
844
|
+
* @param {number} lineGap The line gap of the font.
|
|
845
|
+
**/
|
|
846
|
+
setFontVExtentsFunc: function (func) {
|
|
847
|
+
let funcPtr = addFunction(function (fontPtr, font_data, extentsPtr, user_data) {
|
|
848
|
+
let font = createFont(null, fontPtr);
|
|
849
|
+
let extents = func(font);
|
|
850
|
+
font.destroy();
|
|
851
|
+
if (extents) {
|
|
852
|
+
Module.HEAP32[extentsPtr / 4] = extents.ascender;
|
|
853
|
+
Module.HEAP32[extentsPtr / 4 + 1] = extents.descender;
|
|
854
|
+
Module.HEAP32[extentsPtr / 4 + 2] = extents.lineGap;
|
|
855
|
+
return 1;
|
|
856
|
+
}
|
|
857
|
+
return 0;
|
|
858
|
+
}, 'ipppp');
|
|
859
|
+
exports.hb_font_funcs_set_font_v_extents_func(ptr, funcPtr, 0, 0);
|
|
860
|
+
},
|
|
861
|
+
destroy: function () {
|
|
862
|
+
exports.hb_font_funcs_destroy(ptr);
|
|
863
|
+
}
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
|
|
274
867
|
/**
|
|
275
868
|
* Use when you know the input range should be ASCII.
|
|
276
869
|
* Faster than encoding to UTF-8
|
|
@@ -353,7 +946,7 @@ function hbjs(Module) {
|
|
|
353
946
|
flagValue |= _buffer_flag(s);
|
|
354
947
|
})
|
|
355
948
|
|
|
356
|
-
exports.hb_buffer_set_flags(ptr,flagValue);
|
|
949
|
+
exports.hb_buffer_set_flags(ptr, flagValue);
|
|
357
950
|
},
|
|
358
951
|
/**
|
|
359
952
|
* Set buffer language explicitly.
|
|
@@ -361,7 +954,7 @@ function hbjs(Module) {
|
|
|
361
954
|
*/
|
|
362
955
|
setLanguage: function (language) {
|
|
363
956
|
var str = createAsciiString(language);
|
|
364
|
-
exports.hb_buffer_set_language(ptr, exports.hb_language_from_string(str.ptr
|
|
957
|
+
exports.hb_buffer_set_language(ptr, exports.hb_language_from_string(str.ptr, -1));
|
|
365
958
|
str.free();
|
|
366
959
|
},
|
|
367
960
|
/**
|
|
@@ -370,7 +963,7 @@ function hbjs(Module) {
|
|
|
370
963
|
*/
|
|
371
964
|
setScript: function (script) {
|
|
372
965
|
var str = createAsciiString(script);
|
|
373
|
-
exports.hb_buffer_set_script(ptr, exports.hb_script_from_string(str.ptr
|
|
966
|
+
exports.hb_buffer_set_script(ptr, exports.hb_script_from_string(str.ptr, -1));
|
|
374
967
|
str.free();
|
|
375
968
|
},
|
|
376
969
|
|
|
@@ -548,6 +1141,7 @@ function hbjs(Module) {
|
|
|
548
1141
|
createBlob: createBlob,
|
|
549
1142
|
createFace: createFace,
|
|
550
1143
|
createFont: createFont,
|
|
1144
|
+
createFontFuncs: createFontFuncs,
|
|
551
1145
|
createBuffer: createBuffer,
|
|
552
1146
|
shape: shape,
|
|
553
1147
|
shapeWithTrace: shapeWithTrace,
|
|
@@ -559,4 +1153,4 @@ function hbjs(Module) {
|
|
|
559
1153
|
// Should be replaced with something more reliable
|
|
560
1154
|
try {
|
|
561
1155
|
module.exports = hbjs;
|
|
562
|
-
} catch (e) {}
|
|
1156
|
+
} catch (e) { }
|