• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1CanvasKit._extraInitializations = CanvasKit._extraInitializations || [];
2CanvasKit._extraInitializations.push(function() {
3
4  CanvasKit.Canvas.prototype.drawText = function(str, x, y, paint, font) {
5    // lengthBytesUTF8 and stringToUTF8Array are defined in the emscripten
6    // JS.  See https://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html#stringToUTF8
7    var strLen = lengthBytesUTF8(str);
8    // Add 1 for null terminator, which we need when copying/converting, but can ignore
9    // when we call into Skia.
10    var strPtr = CanvasKit._malloc(strLen + 1);
11    stringToUTF8(str, strPtr, strLen + 1);
12    this._drawSimpleText(strPtr, strLen, x, y, font, paint);
13    CanvasKit._free(strPtr);
14  };
15
16  // Glyphs should be a Uint16Array of glyph ids, e.g. provided by Font.getGlyphIDs.
17  // If using a Malloc'd array, be sure to use CanvasKit.MallocGlyphIDs() to get the right type.
18  // The return value will be a Float32Array that is 4 times as long as the input array. For each
19  // glyph, there will be 4 floats for left, top, right, bottom (relative to 0, 0) for that glyph.
20  CanvasKit.Font.prototype.getGlyphBounds = function(glyphs, paint, optionalOutputArray) {
21    var glyphPtr = copy1dArray(glyphs, 'HEAPU16');
22    var bytesPerRect = 4 * 4;
23    var rectPtr = CanvasKit._malloc(glyphs.length * bytesPerRect);
24    this._getGlyphWidthBounds(glyphPtr, glyphs.length, nullptr, rectPtr, paint || null);
25
26    var rects = new Float32Array(CanvasKit.HEAPU8.buffer, rectPtr, glyphs.length * 4);
27    freeArraysThatAreNotMallocedByUsers(glyphPtr, glyphs);
28    if (optionalOutputArray) {
29      optionalOutputArray.set(rects);
30      CanvasKit._free(rectPtr);
31      return optionalOutputArray;
32    }
33    var rv = Float32Array.from(rects);
34    CanvasKit._free(rectPtr);
35    return rv;
36  };
37
38  CanvasKit.Font.prototype.getGlyphIDs = function(str, numGlyphIDs, optionalOutputArray) {
39    if (!numGlyphIDs) {
40      numGlyphIDs = str.length;
41    }
42    // lengthBytesUTF8 and stringToUTF8Array are defined in the emscripten
43    // JS.  See https://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html#stringToUTF8
44    // Add 1 for null terminator
45    var strBytes = lengthBytesUTF8(str) + 1;
46    var strPtr = CanvasKit._malloc(strBytes);
47    stringToUTF8(str, strPtr, strBytes); // This includes the null terminator
48
49    var bytesPerGlyph = 2;
50    var glyphPtr = CanvasKit._malloc(numGlyphIDs * bytesPerGlyph);
51    // We don't need to compute the id for the null terminator, so subtract 1.
52    var actualIDs = this._getGlyphIDs(strPtr, strBytes - 1, numGlyphIDs, glyphPtr);
53    CanvasKit._free(strPtr);
54    if (actualIDs < 0) {
55      Debug('Could not get glyphIDs');
56      CanvasKit._free(glyphPtr);
57      return null;
58    }
59    var glyphs = new Uint16Array(CanvasKit.HEAPU8.buffer, glyphPtr, actualIDs);
60    if (optionalOutputArray) {
61      optionalOutputArray.set(glyphs);
62      CanvasKit._free(glyphPtr);
63      return optionalOutputArray;
64    }
65    var rv = Uint16Array.from(glyphs);
66    CanvasKit._free(glyphPtr);
67    return rv;
68  };
69
70  CanvasKit.Font.prototype.getGlyphIntercepts = function(glyphs, positions, top, bottom) {
71    var gPtr = copy1dArray(glyphs, 'HEAPU16');
72    var pPtr = copy1dArray(positions, 'HEAPF32');
73    return this._getGlyphIntercepts(gPtr, glyphs.length, !wasMalloced(glyphs),
74                                    pPtr, positions.length, !wasMalloced(positions),
75                                    top, bottom);
76  };
77
78  // Glyphs should be a Uint16Array of glyph ids, e.g. provided by Font.getGlyphIDs.
79  // If using a Malloc'd array, be sure to use CanvasKit.MallocGlyphIDs() to get the right type.
80  // The return value will be a Float32Array that has one width per input glyph.
81  CanvasKit.Font.prototype.getGlyphWidths = function(glyphs, paint, optionalOutputArray) {
82    var glyphPtr = copy1dArray(glyphs, 'HEAPU16');
83    var bytesPerWidth = 4;
84    var widthPtr = CanvasKit._malloc(glyphs.length * bytesPerWidth);
85    this._getGlyphWidthBounds(glyphPtr, glyphs.length, widthPtr, nullptr, paint || null);
86
87    var widths = new Float32Array(CanvasKit.HEAPU8.buffer, widthPtr, glyphs.length);
88    freeArraysThatAreNotMallocedByUsers(glyphPtr, glyphs);
89    if (optionalOutputArray) {
90      optionalOutputArray.set(widths);
91      CanvasKit._free(widthPtr);
92      return optionalOutputArray;
93    }
94    var rv = Float32Array.from(widths);
95    CanvasKit._free(widthPtr);
96    return rv;
97  };
98
99  // arguments should all be arrayBuffers or be an array of arrayBuffers.
100  CanvasKit.FontMgr.FromData = function() {
101    if (!arguments.length) {
102      Debug('Could not make FontMgr from no font sources');
103      return null;
104    }
105    var fonts = arguments;
106    if (fonts.length === 1 && Array.isArray(fonts[0])) {
107      fonts = arguments[0];
108    }
109    if (!fonts.length) {
110      Debug('Could not make FontMgr from no font sources');
111      return null;
112    }
113    var dPtrs = [];
114    var sizes = [];
115    for (var i = 0; i < fonts.length; i++) {
116      var data = new Uint8Array(fonts[i]);
117      var dptr = copy1dArray(data, 'HEAPU8');
118      dPtrs.push(dptr);
119      sizes.push(data.byteLength);
120    }
121    // Pointers are 32 bit unsigned ints
122    var datasPtr = copy1dArray(dPtrs, 'HEAPU32');
123    var sizesPtr = copy1dArray(sizes, 'HEAPU32');
124    var fm = CanvasKit.FontMgr._fromData(datasPtr, sizesPtr, fonts.length);
125    // The FontMgr has taken ownership of the bytes we allocated in the for loop.
126    CanvasKit._free(datasPtr);
127    CanvasKit._free(sizesPtr);
128    return fm;
129  };
130
131  CanvasKit.Typeface.MakeFreeTypeFaceFromData = function(fontData) {
132    var data = new Uint8Array(fontData);
133
134    var fptr = copy1dArray(data, 'HEAPU8');
135    var font = CanvasKit.Typeface._MakeFreeTypeFaceFromData(fptr, data.byteLength);
136    if (!font) {
137      Debug('Could not decode font data');
138      // We do not need to free the data since the C++ will do that for us
139      // when the font is deleted (or fails to decode);
140      return null;
141    }
142    return font;
143  };
144
145  CanvasKit.Typeface.prototype.getGlyphIDs = function(str, numGlyphIDs, optionalOutputArray) {
146    if (!numGlyphIDs) {
147      numGlyphIDs = str.length;
148    }
149    // lengthBytesUTF8 and stringToUTF8Array are defined in the emscripten
150    // JS.  See https://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html#stringToUTF8
151    // Add 1 for null terminator
152    var strBytes = lengthBytesUTF8(str) + 1;
153    var strPtr = CanvasKit._malloc(strBytes);
154    stringToUTF8(str, strPtr, strBytes); // This includes the null terminator
155
156    var bytesPerGlyph = 2;
157    var glyphPtr = CanvasKit._malloc(numGlyphIDs * bytesPerGlyph);
158    // We don't need to compute the id for the null terminator, so subtract 1.
159    var actualIDs = this._getGlyphIDs(strPtr, strBytes - 1, numGlyphIDs, glyphPtr);
160    CanvasKit._free(strPtr);
161    if (actualIDs < 0) {
162      Debug('Could not get glyphIDs');
163      CanvasKit._free(glyphPtr);
164      return null;
165    }
166    var glyphs = new Uint16Array(CanvasKit.HEAPU8.buffer, glyphPtr, actualIDs);
167    if (optionalOutputArray) {
168      optionalOutputArray.set(glyphs);
169      CanvasKit._free(glyphPtr);
170      return optionalOutputArray;
171    }
172    var rv = Uint16Array.from(glyphs);
173    CanvasKit._free(glyphPtr);
174    return rv;
175  };
176
177  CanvasKit.TextBlob.MakeOnPath = function(str, path, font, initialOffset) {
178    if (!str || !str.length) {
179      Debug('ignoring 0 length string');
180      return;
181    }
182    if (!path || !path.countPoints()) {
183      Debug('ignoring empty path');
184      return;
185    }
186    if (path.countPoints() === 1) {
187      Debug('path has 1 point, returning normal textblob');
188      return this.MakeFromText(str, font);
189    }
190
191    if (!initialOffset) {
192      initialOffset = 0;
193    }
194
195    var ids = font.getGlyphIDs(str);
196    var widths = font.getGlyphWidths(ids);
197
198    var rsx = [];
199    var meas = new CanvasKit.ContourMeasureIter(path, false, 1);
200    var cont = meas.next();
201    var dist = initialOffset;
202    var xycs = new Float32Array(4);
203    for (var i = 0; i < str.length && cont; i++) {
204      var width = widths[i];
205      dist += width/2;
206      if (dist > cont.length()) {
207        // jump to next contour
208        cont.delete();
209        cont = meas.next();
210        if (!cont) {
211          // We have come to the end of the path - terminate the string
212          // right here.
213          str = str.substring(0, i);
214          break;
215        }
216        dist = width/2;
217      }
218
219      // Gives us the (x, y) coordinates as well as the cos/sin of the tangent
220      // line at that position.
221      cont.getPosTan(dist, xycs);
222      var cx = xycs[0];
223      var cy = xycs[1];
224      var cosT = xycs[2];
225      var sinT = xycs[3];
226
227      var adjustedX = cx - (width/2 * cosT);
228      var adjustedY = cy - (width/2 * sinT);
229
230      rsx.push(cosT, sinT, adjustedX, adjustedY);
231      dist += width/2;
232    }
233    var retVal = this.MakeFromRSXform(str, rsx, font);
234    cont && cont.delete();
235    meas.delete();
236    return retVal;
237  };
238
239  CanvasKit.TextBlob.MakeFromRSXform = function(str, rsxForms, font) {
240    // lengthBytesUTF8 and stringToUTF8Array are defined in the emscripten
241    // JS.  See https://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html#stringToUTF8
242    // Add 1 for null terminator
243    var strLen = lengthBytesUTF8(str) + 1;
244    var strPtr = CanvasKit._malloc(strLen);
245    // Add 1 for the null terminator.
246    stringToUTF8(str, strPtr, strLen);
247
248    var rPtr = copy1dArray(rsxForms, 'HEAPF32');
249
250    var blob = CanvasKit.TextBlob._MakeFromRSXform(strPtr, strLen - 1, rPtr, font);
251    CanvasKit._free(strPtr);
252    if (!blob) {
253      Debug('Could not make textblob from string "' + str + '"');
254      return null;
255    }
256    return blob;
257  };
258
259  // Glyphs should be a Uint32Array of glyph ids, e.g. provided by Font.getGlyphIDs.
260  // If using a Malloc'd array, be sure to use CanvasKit.MallocGlyphIDs() to get the right type.
261  CanvasKit.TextBlob.MakeFromRSXformGlyphs = function(glyphs, rsxForms, font) {
262    // Currently on the C++ side, glyph ids are 16bit, but there is an effort to change that.
263    var glyphPtr = copy1dArray(glyphs, 'HEAPU16');
264    var bytesPerGlyph = 2;
265
266    var rPtr = copy1dArray(rsxForms, 'HEAPF32');
267
268    var blob = CanvasKit.TextBlob._MakeFromRSXformGlyphs(glyphPtr, glyphs.length * bytesPerGlyph, rPtr, font);
269    freeArraysThatAreNotMallocedByUsers(glyphPtr, glyphs);
270    if (!blob) {
271      Debug('Could not make textblob from glyphs "' + glyphs + '"');
272      return null;
273    }
274    return blob;
275  };
276
277  // Glyphs should be a Uint32Array of glyph ids, e.g. provided by Font.getGlyphIDs.
278  // If using a Malloc'd array, be sure to use CanvasKit.MallocGlyphIDs() to get the right type.
279  CanvasKit.TextBlob.MakeFromGlyphs = function(glyphs, font) {
280    // Currently on the C++ side, glyph ids are 16bit, but there is an effort to change that.
281    var glyphPtr = copy1dArray(glyphs, 'HEAPU16');
282    var bytesPerGlyph = 2;
283    var blob = CanvasKit.TextBlob._MakeFromGlyphs(glyphPtr, glyphs.length * bytesPerGlyph, font);
284    freeArraysThatAreNotMallocedByUsers(glyphPtr, glyphs);
285    if (!blob) {
286      Debug('Could not make textblob from glyphs "' + glyphs + '"');
287      return null;
288    }
289    return blob;
290  };
291
292  CanvasKit.TextBlob.MakeFromText = function(str, font) {
293    // lengthBytesUTF8 and stringToUTF8Array are defined in the emscripten
294    // JS.  See https://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html#stringToUTF8
295    // Add 1 for null terminator
296    var strLen = lengthBytesUTF8(str) + 1;
297    var strPtr = CanvasKit._malloc(strLen);
298    // Add 1 for the null terminator.
299    stringToUTF8(str, strPtr, strLen);
300
301    var blob = CanvasKit.TextBlob._MakeFromText(strPtr, strLen - 1, font);
302    CanvasKit._free(strPtr);
303    if (!blob) {
304      Debug('Could not make textblob from string "' + str + '"');
305      return null;
306    }
307    return blob;
308  };
309
310  // A helper to return the right type for GlyphIDs stored internally. When that changes, this
311  // will also be changed, which will help avoid future breakages.
312  CanvasKit.MallocGlyphIDs = function(numGlyphIDs) {
313    return CanvasKit.Malloc(Uint16Array, numGlyphIDs);
314  }
315});
316