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