1*c8dee2aaSAndroid Build Coastguard Worker(function(CanvasKit){ 2*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._extraInitializations = CanvasKit._extraInitializations || []; 3*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._extraInitializations.push(function() { 4*c8dee2aaSAndroid Build Coastguard Worker 5*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Paragraph.prototype.getRectsForRange = function(start, end, hStyle, wStyle) { 6*c8dee2aaSAndroid Build Coastguard Worker /** 7*c8dee2aaSAndroid Build Coastguard Worker * @type {Float32Array} 8*c8dee2aaSAndroid Build Coastguard Worker */ 9*c8dee2aaSAndroid Build Coastguard Worker var floatArray = this._getRectsForRange(start, end, hStyle, wStyle); 10*c8dee2aaSAndroid Build Coastguard Worker return floatArrayToRects(floatArray); 11*c8dee2aaSAndroid Build Coastguard Worker } 12*c8dee2aaSAndroid Build Coastguard Worker 13*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Paragraph.prototype.getRectsForPlaceholders = function() { 14*c8dee2aaSAndroid Build Coastguard Worker /** 15*c8dee2aaSAndroid Build Coastguard Worker * @type {Float32Array} 16*c8dee2aaSAndroid Build Coastguard Worker */ 17*c8dee2aaSAndroid Build Coastguard Worker var floatArray = this._getRectsForPlaceholders(); 18*c8dee2aaSAndroid Build Coastguard Worker return floatArrayToRects(floatArray); 19*c8dee2aaSAndroid Build Coastguard Worker } 20*c8dee2aaSAndroid Build Coastguard Worker 21*c8dee2aaSAndroid Build Coastguard Worker function convertDirection(glyphInfo) { 22*c8dee2aaSAndroid Build Coastguard Worker if (glyphInfo) { 23*c8dee2aaSAndroid Build Coastguard Worker if (glyphInfo['dir'] === 0) { 24*c8dee2aaSAndroid Build Coastguard Worker glyphInfo['dir'] = CanvasKit.TextDirection.RTL; 25*c8dee2aaSAndroid Build Coastguard Worker } else { 26*c8dee2aaSAndroid Build Coastguard Worker glyphInfo['dir'] = CanvasKit.TextDirection.LTR; 27*c8dee2aaSAndroid Build Coastguard Worker } 28*c8dee2aaSAndroid Build Coastguard Worker } 29*c8dee2aaSAndroid Build Coastguard Worker return glyphInfo; 30*c8dee2aaSAndroid Build Coastguard Worker } 31*c8dee2aaSAndroid Build Coastguard Worker 32*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Paragraph.prototype.getGlyphInfoAt = function(index) { 33*c8dee2aaSAndroid Build Coastguard Worker return convertDirection(this._getGlyphInfoAt(index)); 34*c8dee2aaSAndroid Build Coastguard Worker } 35*c8dee2aaSAndroid Build Coastguard Worker 36*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Paragraph.prototype.getClosestGlyphInfoAtCoordinate = function(dx, dy) { 37*c8dee2aaSAndroid Build Coastguard Worker return convertDirection(this._getClosestGlyphInfoAtCoordinate(dx, dy)); 38*c8dee2aaSAndroid Build Coastguard Worker } 39*c8dee2aaSAndroid Build Coastguard Worker 40*c8dee2aaSAndroid Build Coastguard Worker function floatArrayToRects(floatArray) { 41*c8dee2aaSAndroid Build Coastguard Worker if (!floatArray || !floatArray.length) { 42*c8dee2aaSAndroid Build Coastguard Worker return []; 43*c8dee2aaSAndroid Build Coastguard Worker } 44*c8dee2aaSAndroid Build Coastguard Worker var ret = []; 45*c8dee2aaSAndroid Build Coastguard Worker for (var i = 0; i < floatArray.length; i+=5) { 46*c8dee2aaSAndroid Build Coastguard Worker var rect = CanvasKit.LTRBRect(floatArray[i], floatArray[i+1], floatArray[i+2], floatArray[i+3]); 47*c8dee2aaSAndroid Build Coastguard Worker var dir = CanvasKit.TextDirection.LTR; 48*c8dee2aaSAndroid Build Coastguard Worker if (floatArray[i+4] === 0) { 49*c8dee2aaSAndroid Build Coastguard Worker dir = CanvasKit.TextDirection.RTL; 50*c8dee2aaSAndroid Build Coastguard Worker } 51*c8dee2aaSAndroid Build Coastguard Worker ret.push({'rect': rect, 'dir': dir}); 52*c8dee2aaSAndroid Build Coastguard Worker } 53*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._free(floatArray.byteOffset); 54*c8dee2aaSAndroid Build Coastguard Worker return ret; 55*c8dee2aaSAndroid Build Coastguard Worker } 56*c8dee2aaSAndroid Build Coastguard Worker 57*c8dee2aaSAndroid Build Coastguard Worker // Registers the font (provided as an arrayBuffer) with the alias `family`. 58*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.TypefaceFontProvider.prototype.registerFont = function(font, family) { 59*c8dee2aaSAndroid Build Coastguard Worker var typeface = CanvasKit.Typeface.MakeTypefaceFromData(font); 60*c8dee2aaSAndroid Build Coastguard Worker if (!typeface) { 61*c8dee2aaSAndroid Build Coastguard Worker Debug('Could not decode font data'); 62*c8dee2aaSAndroid Build Coastguard Worker // We do not need to free the data since the C++ will do that for us 63*c8dee2aaSAndroid Build Coastguard Worker // when the font is deleted (or fails to decode); 64*c8dee2aaSAndroid Build Coastguard Worker return null; 65*c8dee2aaSAndroid Build Coastguard Worker } 66*c8dee2aaSAndroid Build Coastguard Worker var familyPtr = cacheOrCopyString(family); 67*c8dee2aaSAndroid Build Coastguard Worker this._registerFont(typeface, familyPtr); 68*c8dee2aaSAndroid Build Coastguard Worker } 69*c8dee2aaSAndroid Build Coastguard Worker 70*c8dee2aaSAndroid Build Coastguard Worker // These helpers fill out all fields, because emscripten complains if we 71*c8dee2aaSAndroid Build Coastguard Worker // have undefined and it expects, for example, a float. 72*c8dee2aaSAndroid Build Coastguard Worker // TODO(kjlubick) For efficiency, we should probably just return opaque WASM objects so we do 73*c8dee2aaSAndroid Build Coastguard Worker // not have to keep copying them across the wire. 74*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ParagraphStyle = function(s) { 75*c8dee2aaSAndroid Build Coastguard Worker // Use [''] to tell closure not to minify the names 76*c8dee2aaSAndroid Build Coastguard Worker s['disableHinting'] = s['disableHinting'] || false; 77*c8dee2aaSAndroid Build Coastguard Worker if (s['ellipsis']) { 78*c8dee2aaSAndroid Build Coastguard Worker var str = s['ellipsis']; 79*c8dee2aaSAndroid Build Coastguard Worker s['_ellipsisPtr'] = cacheOrCopyString(str); 80*c8dee2aaSAndroid Build Coastguard Worker s['_ellipsisLen'] = lengthBytesUTF8(str); 81*c8dee2aaSAndroid Build Coastguard Worker } else { 82*c8dee2aaSAndroid Build Coastguard Worker s['_ellipsisPtr'] = nullptr; 83*c8dee2aaSAndroid Build Coastguard Worker s['_ellipsisLen'] = 0; 84*c8dee2aaSAndroid Build Coastguard Worker } 85*c8dee2aaSAndroid Build Coastguard Worker 86*c8dee2aaSAndroid Build Coastguard Worker if (s['heightMultiplier'] == null) { 87*c8dee2aaSAndroid Build Coastguard Worker s['heightMultiplier'] = -1 88*c8dee2aaSAndroid Build Coastguard Worker } 89*c8dee2aaSAndroid Build Coastguard Worker s['maxLines'] = s['maxLines'] || 0; 90*c8dee2aaSAndroid Build Coastguard Worker s['replaceTabCharacters'] = s['replaceTabCharacters'] || false; 91*c8dee2aaSAndroid Build Coastguard Worker s['strutStyle'] = strutStyle(s['strutStyle']); 92*c8dee2aaSAndroid Build Coastguard Worker s['textAlign'] = s['textAlign'] || CanvasKit.TextAlign.Start; 93*c8dee2aaSAndroid Build Coastguard Worker s['textDirection'] = s['textDirection'] || CanvasKit.TextDirection.LTR; 94*c8dee2aaSAndroid Build Coastguard Worker s['textHeightBehavior'] = s['textHeightBehavior'] || CanvasKit.TextHeightBehavior.All; 95*c8dee2aaSAndroid Build Coastguard Worker s['textStyle'] = CanvasKit.TextStyle(s['textStyle']); 96*c8dee2aaSAndroid Build Coastguard Worker s['applyRoundingHack'] = s['applyRoundingHack'] !== false; 97*c8dee2aaSAndroid Build Coastguard Worker return s; 98*c8dee2aaSAndroid Build Coastguard Worker }; 99*c8dee2aaSAndroid Build Coastguard Worker 100*c8dee2aaSAndroid Build Coastguard Worker function fontStyle(s) { 101*c8dee2aaSAndroid Build Coastguard Worker s = s || {}; 102*c8dee2aaSAndroid Build Coastguard Worker // Can't check for falsey as 0 width means "invisible". 103*c8dee2aaSAndroid Build Coastguard Worker if (s['weight'] === undefined) { 104*c8dee2aaSAndroid Build Coastguard Worker s['weight'] = CanvasKit.FontWeight.Normal; 105*c8dee2aaSAndroid Build Coastguard Worker } 106*c8dee2aaSAndroid Build Coastguard Worker s['width'] = s['width'] || CanvasKit.FontWidth.Normal; 107*c8dee2aaSAndroid Build Coastguard Worker s['slant'] = s['slant'] || CanvasKit.FontSlant.Upright; 108*c8dee2aaSAndroid Build Coastguard Worker return s; 109*c8dee2aaSAndroid Build Coastguard Worker } 110*c8dee2aaSAndroid Build Coastguard Worker 111*c8dee2aaSAndroid Build Coastguard Worker function strutStyle(s) { 112*c8dee2aaSAndroid Build Coastguard Worker s = s || {}; 113*c8dee2aaSAndroid Build Coastguard Worker s['strutEnabled'] = s['strutEnabled'] || false; 114*c8dee2aaSAndroid Build Coastguard Worker 115*c8dee2aaSAndroid Build Coastguard Worker if (s['strutEnabled'] && Array.isArray(s['fontFamilies']) && s['fontFamilies'].length) { 116*c8dee2aaSAndroid Build Coastguard Worker s['_fontFamiliesPtr'] = naiveCopyStrArray(s['fontFamilies']); 117*c8dee2aaSAndroid Build Coastguard Worker s['_fontFamiliesLen'] = s['fontFamilies'].length; 118*c8dee2aaSAndroid Build Coastguard Worker } else { 119*c8dee2aaSAndroid Build Coastguard Worker s['_fontFamiliesPtr'] = nullptr; 120*c8dee2aaSAndroid Build Coastguard Worker s['_fontFamiliesLen'] = 0; 121*c8dee2aaSAndroid Build Coastguard Worker } 122*c8dee2aaSAndroid Build Coastguard Worker s['fontStyle'] = fontStyle(s['fontStyle']); 123*c8dee2aaSAndroid Build Coastguard Worker if (s['fontSize'] == null) { 124*c8dee2aaSAndroid Build Coastguard Worker s['fontSize'] = -1 125*c8dee2aaSAndroid Build Coastguard Worker } 126*c8dee2aaSAndroid Build Coastguard Worker if (s['heightMultiplier'] == null) { 127*c8dee2aaSAndroid Build Coastguard Worker s['heightMultiplier'] = -1 128*c8dee2aaSAndroid Build Coastguard Worker } 129*c8dee2aaSAndroid Build Coastguard Worker s['halfLeading'] = s['halfLeading'] || false; 130*c8dee2aaSAndroid Build Coastguard Worker s['leading'] = s['leading'] || 0; 131*c8dee2aaSAndroid Build Coastguard Worker s['forceStrutHeight'] = s['forceStrutHeight'] || false; 132*c8dee2aaSAndroid Build Coastguard Worker return s; 133*c8dee2aaSAndroid Build Coastguard Worker } 134*c8dee2aaSAndroid Build Coastguard Worker 135*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.TextStyle = function(s) { 136*c8dee2aaSAndroid Build Coastguard Worker // Use [''] to tell closure not to minify the names 137*c8dee2aaSAndroid Build Coastguard Worker if (!s['color']) { 138*c8dee2aaSAndroid Build Coastguard Worker s['color'] = CanvasKit.BLACK; 139*c8dee2aaSAndroid Build Coastguard Worker } 140*c8dee2aaSAndroid Build Coastguard Worker 141*c8dee2aaSAndroid Build Coastguard Worker s['decoration'] = s['decoration'] || 0; 142*c8dee2aaSAndroid Build Coastguard Worker s['decorationThickness'] = s['decorationThickness'] || 0; 143*c8dee2aaSAndroid Build Coastguard Worker s['decorationStyle'] = s['decorationStyle'] || CanvasKit.DecorationStyle.Solid; 144*c8dee2aaSAndroid Build Coastguard Worker s['textBaseline'] = s['textBaseline'] || CanvasKit.TextBaseline.Alphabetic; 145*c8dee2aaSAndroid Build Coastguard Worker if (s['fontSize'] == null) { 146*c8dee2aaSAndroid Build Coastguard Worker s['fontSize'] = -1 147*c8dee2aaSAndroid Build Coastguard Worker } 148*c8dee2aaSAndroid Build Coastguard Worker s['letterSpacing'] = s['letterSpacing'] || 0; 149*c8dee2aaSAndroid Build Coastguard Worker s['wordSpacing'] = s['wordSpacing'] || 0; 150*c8dee2aaSAndroid Build Coastguard Worker if (s['heightMultiplier'] == null) { 151*c8dee2aaSAndroid Build Coastguard Worker s['heightMultiplier'] = -1 152*c8dee2aaSAndroid Build Coastguard Worker } 153*c8dee2aaSAndroid Build Coastguard Worker s['halfLeading'] = s['halfLeading'] || false; 154*c8dee2aaSAndroid Build Coastguard Worker s['fontStyle'] = fontStyle(s['fontStyle']); 155*c8dee2aaSAndroid Build Coastguard Worker 156*c8dee2aaSAndroid Build Coastguard Worker // Properties which need to be Malloc'ed are set in `copyArrays`. 157*c8dee2aaSAndroid Build Coastguard Worker 158*c8dee2aaSAndroid Build Coastguard Worker return s; 159*c8dee2aaSAndroid Build Coastguard Worker }; 160*c8dee2aaSAndroid Build Coastguard Worker 161*c8dee2aaSAndroid Build Coastguard Worker // returns a pointer to a place on the heap that has an array 162*c8dee2aaSAndroid Build Coastguard Worker // of char* (effectively a char**). For now, this does the naive thing 163*c8dee2aaSAndroid Build Coastguard Worker // and depends on the string being null-terminated. This should be used 164*c8dee2aaSAndroid Build Coastguard Worker // for simple, well-formed things (e.g. font-families), not arbitrary 165*c8dee2aaSAndroid Build Coastguard Worker // text that should be drawn. If we need this to handle more complex 166*c8dee2aaSAndroid Build Coastguard Worker // strings, it should return two pointers, a pointer of the 167*c8dee2aaSAndroid Build Coastguard Worker // string array and a pointer to an array of the strings byte lengths. 168*c8dee2aaSAndroid Build Coastguard Worker function naiveCopyStrArray(strings) { 169*c8dee2aaSAndroid Build Coastguard Worker if (!strings || !strings.length) { 170*c8dee2aaSAndroid Build Coastguard Worker return nullptr; 171*c8dee2aaSAndroid Build Coastguard Worker } 172*c8dee2aaSAndroid Build Coastguard Worker var sPtrs = []; 173*c8dee2aaSAndroid Build Coastguard Worker for (var i = 0; i < strings.length; i++) { 174*c8dee2aaSAndroid Build Coastguard Worker var strPtr = cacheOrCopyString(strings[i]); 175*c8dee2aaSAndroid Build Coastguard Worker sPtrs.push(strPtr); 176*c8dee2aaSAndroid Build Coastguard Worker } 177*c8dee2aaSAndroid Build Coastguard Worker return copy1dArray(sPtrs, 'HEAPU32'); 178*c8dee2aaSAndroid Build Coastguard Worker } 179*c8dee2aaSAndroid Build Coastguard Worker 180*c8dee2aaSAndroid Build Coastguard Worker // maps string -> malloc'd pointer 181*c8dee2aaSAndroid Build Coastguard Worker var stringCache = {}; 182*c8dee2aaSAndroid Build Coastguard Worker 183*c8dee2aaSAndroid Build Coastguard Worker // cacheOrCopyString copies a string from JS into WASM on the heap and returns the pointer 184*c8dee2aaSAndroid Build Coastguard Worker // to the memory of the string. It is expected that a caller to this helper will *not* free 185*c8dee2aaSAndroid Build Coastguard Worker // that memory, so it is cached. Thus, if a future call to this function with the same string 186*c8dee2aaSAndroid Build Coastguard Worker // will return the cached pointer, preventing the memory usage from growing unbounded (in 187*c8dee2aaSAndroid Build Coastguard Worker // a normal use case). 188*c8dee2aaSAndroid Build Coastguard Worker function cacheOrCopyString(str) { 189*c8dee2aaSAndroid Build Coastguard Worker if (stringCache[str]) { 190*c8dee2aaSAndroid Build Coastguard Worker return stringCache[str]; 191*c8dee2aaSAndroid Build Coastguard Worker } 192*c8dee2aaSAndroid Build Coastguard Worker // Add 1 for null terminator, which we need when copying/converting 193*c8dee2aaSAndroid Build Coastguard Worker var strLen = lengthBytesUTF8(str) + 1; 194*c8dee2aaSAndroid Build Coastguard Worker var strPtr = CanvasKit._malloc(strLen); 195*c8dee2aaSAndroid Build Coastguard Worker stringToUTF8(str, strPtr, strLen); 196*c8dee2aaSAndroid Build Coastguard Worker stringCache[str] = strPtr; 197*c8dee2aaSAndroid Build Coastguard Worker return strPtr; 198*c8dee2aaSAndroid Build Coastguard Worker } 199*c8dee2aaSAndroid Build Coastguard Worker 200*c8dee2aaSAndroid Build Coastguard Worker // These scratch arrays are allocated once to copy the color data into, which saves us 201*c8dee2aaSAndroid Build Coastguard Worker // having to free them after every invocation. 202*c8dee2aaSAndroid Build Coastguard Worker var scratchForegroundColorPtr = CanvasKit._malloc(4 * 4); // room for 4 32bit floats 203*c8dee2aaSAndroid Build Coastguard Worker var scratchBackgroundColorPtr = CanvasKit._malloc(4 * 4); // room for 4 32bit floats 204*c8dee2aaSAndroid Build Coastguard Worker var scratchDecorationColorPtr = CanvasKit._malloc(4 * 4); // room for 4 32bit floats 205*c8dee2aaSAndroid Build Coastguard Worker 206*c8dee2aaSAndroid Build Coastguard Worker function copyArrays(textStyle) { 207*c8dee2aaSAndroid Build Coastguard Worker // These color fields were arrays, but will set to WASM pointers before we pass this 208*c8dee2aaSAndroid Build Coastguard Worker // object over the WASM interface. 209*c8dee2aaSAndroid Build Coastguard Worker textStyle['_colorPtr'] = copyColorToWasm(textStyle['color']); 210*c8dee2aaSAndroid Build Coastguard Worker textStyle['_foregroundColorPtr'] = nullptr; // nullptr is 0, from helper.js 211*c8dee2aaSAndroid Build Coastguard Worker textStyle['_backgroundColorPtr'] = nullptr; 212*c8dee2aaSAndroid Build Coastguard Worker textStyle['_decorationColorPtr'] = nullptr; 213*c8dee2aaSAndroid Build Coastguard Worker if (textStyle['foregroundColor']) { 214*c8dee2aaSAndroid Build Coastguard Worker textStyle['_foregroundColorPtr'] = copyColorToWasm(textStyle['foregroundColor'], scratchForegroundColorPtr); 215*c8dee2aaSAndroid Build Coastguard Worker } 216*c8dee2aaSAndroid Build Coastguard Worker if (textStyle['backgroundColor']) { 217*c8dee2aaSAndroid Build Coastguard Worker textStyle['_backgroundColorPtr'] = copyColorToWasm(textStyle['backgroundColor'], scratchBackgroundColorPtr); 218*c8dee2aaSAndroid Build Coastguard Worker } 219*c8dee2aaSAndroid Build Coastguard Worker if (textStyle['decorationColor']) { 220*c8dee2aaSAndroid Build Coastguard Worker textStyle['_decorationColorPtr'] = copyColorToWasm(textStyle['decorationColor'], scratchDecorationColorPtr); 221*c8dee2aaSAndroid Build Coastguard Worker } 222*c8dee2aaSAndroid Build Coastguard Worker 223*c8dee2aaSAndroid Build Coastguard Worker if (Array.isArray(textStyle['fontFamilies']) && textStyle['fontFamilies'].length) { 224*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontFamiliesPtr'] = naiveCopyStrArray(textStyle['fontFamilies']); 225*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontFamiliesLen'] = textStyle['fontFamilies'].length; 226*c8dee2aaSAndroid Build Coastguard Worker } else { 227*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontFamiliesPtr'] = nullptr; 228*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontFamiliesLen'] = 0; 229*c8dee2aaSAndroid Build Coastguard Worker Debug('no font families provided, text may draw wrong or not at all'); 230*c8dee2aaSAndroid Build Coastguard Worker } 231*c8dee2aaSAndroid Build Coastguard Worker 232*c8dee2aaSAndroid Build Coastguard Worker if (textStyle['locale']) { 233*c8dee2aaSAndroid Build Coastguard Worker var str = textStyle['locale']; 234*c8dee2aaSAndroid Build Coastguard Worker textStyle['_localePtr'] = cacheOrCopyString(str); 235*c8dee2aaSAndroid Build Coastguard Worker textStyle['_localeLen'] = lengthBytesUTF8(str); 236*c8dee2aaSAndroid Build Coastguard Worker } else { 237*c8dee2aaSAndroid Build Coastguard Worker textStyle['_localePtr'] = nullptr; 238*c8dee2aaSAndroid Build Coastguard Worker textStyle['_localeLen'] = 0; 239*c8dee2aaSAndroid Build Coastguard Worker } 240*c8dee2aaSAndroid Build Coastguard Worker 241*c8dee2aaSAndroid Build Coastguard Worker if (Array.isArray(textStyle['shadows']) && textStyle['shadows'].length) { 242*c8dee2aaSAndroid Build Coastguard Worker var shadows = textStyle['shadows']; 243*c8dee2aaSAndroid Build Coastguard Worker var shadowColors = shadows.map(function (s) { return s['color'] || CanvasKit.BLACK; }); 244*c8dee2aaSAndroid Build Coastguard Worker var shadowBlurRadii = shadows.map(function (s) { return s['blurRadius'] || 0.0; }); 245*c8dee2aaSAndroid Build Coastguard Worker textStyle['_shadowLen'] = shadows.length; 246*c8dee2aaSAndroid Build Coastguard Worker // 2 floats per point, 4 bytes per float 247*c8dee2aaSAndroid Build Coastguard Worker var ptr = CanvasKit._malloc(shadows.length * 2 * 4); 248*c8dee2aaSAndroid Build Coastguard Worker var adjustedPtr = ptr / 4; // 4 bytes per float 249*c8dee2aaSAndroid Build Coastguard Worker for (var i = 0; i < shadows.length; i++) { 250*c8dee2aaSAndroid Build Coastguard Worker var offset = shadows[i]['offset'] || [0, 0]; 251*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.HEAPF32[adjustedPtr] = offset[0]; 252*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.HEAPF32[adjustedPtr + 1] = offset[1]; 253*c8dee2aaSAndroid Build Coastguard Worker adjustedPtr += 2; 254*c8dee2aaSAndroid Build Coastguard Worker } 255*c8dee2aaSAndroid Build Coastguard Worker textStyle['_shadowColorsPtr'] = copyFlexibleColorArray(shadowColors).colorPtr; 256*c8dee2aaSAndroid Build Coastguard Worker textStyle['_shadowOffsetsPtr'] = ptr; 257*c8dee2aaSAndroid Build Coastguard Worker textStyle['_shadowBlurRadiiPtr'] = copy1dArray(shadowBlurRadii, 'HEAPF32'); 258*c8dee2aaSAndroid Build Coastguard Worker } else { 259*c8dee2aaSAndroid Build Coastguard Worker textStyle['_shadowLen'] = 0; 260*c8dee2aaSAndroid Build Coastguard Worker textStyle['_shadowColorsPtr'] = nullptr; 261*c8dee2aaSAndroid Build Coastguard Worker textStyle['_shadowOffsetsPtr'] = nullptr; 262*c8dee2aaSAndroid Build Coastguard Worker textStyle['_shadowBlurRadiiPtr'] = nullptr; 263*c8dee2aaSAndroid Build Coastguard Worker } 264*c8dee2aaSAndroid Build Coastguard Worker 265*c8dee2aaSAndroid Build Coastguard Worker if (Array.isArray(textStyle['fontFeatures']) && textStyle['fontFeatures'].length) { 266*c8dee2aaSAndroid Build Coastguard Worker var fontFeatures = textStyle['fontFeatures']; 267*c8dee2aaSAndroid Build Coastguard Worker var fontFeatureNames = fontFeatures.map(function (s) { return s['name']; }); 268*c8dee2aaSAndroid Build Coastguard Worker var fontFeatureValues = fontFeatures.map(function (s) { return s['value']; }); 269*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontFeatureLen'] = fontFeatures.length; 270*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontFeatureNamesPtr'] = naiveCopyStrArray(fontFeatureNames); 271*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontFeatureValuesPtr'] = copy1dArray(fontFeatureValues, 'HEAPU32'); 272*c8dee2aaSAndroid Build Coastguard Worker } else { 273*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontFeatureLen'] = 0; 274*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontFeatureNamesPtr'] = nullptr; 275*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontFeatureValuesPtr'] = nullptr; 276*c8dee2aaSAndroid Build Coastguard Worker } 277*c8dee2aaSAndroid Build Coastguard Worker 278*c8dee2aaSAndroid Build Coastguard Worker if (Array.isArray(textStyle['fontVariations']) && textStyle['fontVariations'].length) { 279*c8dee2aaSAndroid Build Coastguard Worker var fontVariations = textStyle['fontVariations']; 280*c8dee2aaSAndroid Build Coastguard Worker var fontVariationAxes = fontVariations.map(function (s) { return s['axis']; }); 281*c8dee2aaSAndroid Build Coastguard Worker var fontVariationValues = fontVariations.map(function (s) { return s['value']; }); 282*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontVariationLen'] = fontVariations.length; 283*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontVariationAxesPtr'] = naiveCopyStrArray(fontVariationAxes); 284*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontVariationValuesPtr'] = copy1dArray(fontVariationValues, 'HEAPF32'); 285*c8dee2aaSAndroid Build Coastguard Worker } else { 286*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontVariationLen'] = 0; 287*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontVariationAxesPtr'] = nullptr; 288*c8dee2aaSAndroid Build Coastguard Worker textStyle['_fontVariationValuesPtr'] = nullptr; 289*c8dee2aaSAndroid Build Coastguard Worker } 290*c8dee2aaSAndroid Build Coastguard Worker } 291*c8dee2aaSAndroid Build Coastguard Worker 292*c8dee2aaSAndroid Build Coastguard Worker function freeArrays(textStyle) { 293*c8dee2aaSAndroid Build Coastguard Worker // The font family strings will get copied to a vector on the C++ side, which is owned by 294*c8dee2aaSAndroid Build Coastguard Worker // the text style. 295*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._free(textStyle['_fontFamiliesPtr']); 296*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._free(textStyle['_shadowColorsPtr']); 297*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._free(textStyle['_shadowOffsetsPtr']); 298*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._free(textStyle['_shadowBlurRadiiPtr']); 299*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._free(textStyle['_fontFeatureNamesPtr']); 300*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._free(textStyle['_fontFeatureValuesPtr']); 301*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._free(textStyle['_fontVariationAxesPtr']); 302*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._free(textStyle['_fontVariationValuesPtr']); 303*c8dee2aaSAndroid Build Coastguard Worker } 304*c8dee2aaSAndroid Build Coastguard Worker 305*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ParagraphBuilder.Make = function(paragraphStyle, fontManager) { 306*c8dee2aaSAndroid Build Coastguard Worker copyArrays(paragraphStyle['textStyle']); 307*c8dee2aaSAndroid Build Coastguard Worker 308*c8dee2aaSAndroid Build Coastguard Worker var result = CanvasKit.ParagraphBuilder._Make(paragraphStyle, fontManager); 309*c8dee2aaSAndroid Build Coastguard Worker freeArrays(paragraphStyle['textStyle']); 310*c8dee2aaSAndroid Build Coastguard Worker return result; 311*c8dee2aaSAndroid Build Coastguard Worker }; 312*c8dee2aaSAndroid Build Coastguard Worker 313*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ParagraphBuilder.MakeFromFontProvider = function(paragraphStyle, fontProvider) { 314*c8dee2aaSAndroid Build Coastguard Worker copyArrays(paragraphStyle['textStyle']); 315*c8dee2aaSAndroid Build Coastguard Worker 316*c8dee2aaSAndroid Build Coastguard Worker var result = CanvasKit.ParagraphBuilder._MakeFromFontProvider(paragraphStyle, fontProvider); 317*c8dee2aaSAndroid Build Coastguard Worker freeArrays(paragraphStyle['textStyle']); 318*c8dee2aaSAndroid Build Coastguard Worker return result; 319*c8dee2aaSAndroid Build Coastguard Worker }; 320*c8dee2aaSAndroid Build Coastguard Worker 321*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ParagraphBuilder.MakeFromFontCollection = function(paragraphStyle, fontCollection) { 322*c8dee2aaSAndroid Build Coastguard Worker copyArrays(paragraphStyle['textStyle']); 323*c8dee2aaSAndroid Build Coastguard Worker 324*c8dee2aaSAndroid Build Coastguard Worker var result = CanvasKit.ParagraphBuilder._MakeFromFontCollection( 325*c8dee2aaSAndroid Build Coastguard Worker paragraphStyle, fontCollection); 326*c8dee2aaSAndroid Build Coastguard Worker freeArrays(paragraphStyle['textStyle']); 327*c8dee2aaSAndroid Build Coastguard Worker return result; 328*c8dee2aaSAndroid Build Coastguard Worker }; 329*c8dee2aaSAndroid Build Coastguard Worker 330*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ParagraphBuilder.ShapeText = function(text, blocks, width) { 331*c8dee2aaSAndroid Build Coastguard Worker let length = 0; 332*c8dee2aaSAndroid Build Coastguard Worker for (const b of blocks) { 333*c8dee2aaSAndroid Build Coastguard Worker length += b.length; 334*c8dee2aaSAndroid Build Coastguard Worker } 335*c8dee2aaSAndroid Build Coastguard Worker if (length !== text.length) { 336*c8dee2aaSAndroid Build Coastguard Worker throw "Accumulated block lengths must equal text.length"; 337*c8dee2aaSAndroid Build Coastguard Worker } 338*c8dee2aaSAndroid Build Coastguard Worker return CanvasKit.ParagraphBuilder._ShapeText(text, blocks, width); 339*c8dee2aaSAndroid Build Coastguard Worker }; 340*c8dee2aaSAndroid Build Coastguard Worker 341*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ParagraphBuilder.prototype.pushStyle = function(textStyle) { 342*c8dee2aaSAndroid Build Coastguard Worker copyArrays(textStyle); 343*c8dee2aaSAndroid Build Coastguard Worker this._pushStyle(textStyle); 344*c8dee2aaSAndroid Build Coastguard Worker freeArrays(textStyle); 345*c8dee2aaSAndroid Build Coastguard Worker }; 346*c8dee2aaSAndroid Build Coastguard Worker 347*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ParagraphBuilder.prototype.pushPaintStyle = function(textStyle, fg, bg) { 348*c8dee2aaSAndroid Build Coastguard Worker copyArrays(textStyle); 349*c8dee2aaSAndroid Build Coastguard Worker this._pushPaintStyle(textStyle, fg, bg); 350*c8dee2aaSAndroid Build Coastguard Worker freeArrays(textStyle); 351*c8dee2aaSAndroid Build Coastguard Worker }; 352*c8dee2aaSAndroid Build Coastguard Worker 353*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ParagraphBuilder.prototype.addPlaceholder = 354*c8dee2aaSAndroid Build Coastguard Worker function(width, height, alignment, baseline, offset) { 355*c8dee2aaSAndroid Build Coastguard Worker width = width || 0; 356*c8dee2aaSAndroid Build Coastguard Worker height = height || 0; 357*c8dee2aaSAndroid Build Coastguard Worker alignment = alignment || CanvasKit.PlaceholderAlignment.Baseline; 358*c8dee2aaSAndroid Build Coastguard Worker baseline = baseline || CanvasKit.TextBaseline.Alphabetic; 359*c8dee2aaSAndroid Build Coastguard Worker offset = offset || 0; 360*c8dee2aaSAndroid Build Coastguard Worker this._addPlaceholder(width, height, alignment, baseline, offset); 361*c8dee2aaSAndroid Build Coastguard Worker }; 362*c8dee2aaSAndroid Build Coastguard Worker 363*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ParagraphBuilder.prototype.setWordsUtf8 = function(words) { 364*c8dee2aaSAndroid Build Coastguard Worker var bPtr = copy1dArray(words, 'HEAPU32'); 365*c8dee2aaSAndroid Build Coastguard Worker this._setWordsUtf8(bPtr, words && words.length || 0); 366*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(bPtr, words); 367*c8dee2aaSAndroid Build Coastguard Worker }; 368*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ParagraphBuilder.prototype.setWordsUtf16 = function(words) { 369*c8dee2aaSAndroid Build Coastguard Worker var bPtr = copy1dArray(words, 'HEAPU32'); 370*c8dee2aaSAndroid Build Coastguard Worker this._setWordsUtf16(bPtr, words && words.length || 0); 371*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(bPtr, words); 372*c8dee2aaSAndroid Build Coastguard Worker }; 373*c8dee2aaSAndroid Build Coastguard Worker 374*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ParagraphBuilder.prototype.setGraphemeBreaksUtf8 = function(graphemeBreaks) { 375*c8dee2aaSAndroid Build Coastguard Worker var bPtr = copy1dArray(graphemeBreaks, 'HEAPU32'); 376*c8dee2aaSAndroid Build Coastguard Worker this._setGraphemeBreaksUtf8(bPtr, graphemeBreaks && graphemeBreaks.length || 0); 377*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(bPtr, graphemeBreaks); 378*c8dee2aaSAndroid Build Coastguard Worker }; 379*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ParagraphBuilder.prototype.setGraphemeBreaksUtf16 = function(graphemeBreaks) { 380*c8dee2aaSAndroid Build Coastguard Worker var bPtr = copy1dArray(graphemeBreaks, 'HEAPU32'); 381*c8dee2aaSAndroid Build Coastguard Worker this._setGraphemeBreaksUtf16(bPtr, graphemeBreaks && graphemeBreaks.length || 0); 382*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(bPtr, graphemeBreaks); 383*c8dee2aaSAndroid Build Coastguard Worker }; 384*c8dee2aaSAndroid Build Coastguard Worker 385*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ParagraphBuilder.prototype.setLineBreaksUtf8 = function(lineBreaks) { 386*c8dee2aaSAndroid Build Coastguard Worker var bPtr = copy1dArray(lineBreaks, 'HEAPU32'); 387*c8dee2aaSAndroid Build Coastguard Worker this._setLineBreaksUtf8(bPtr, lineBreaks && lineBreaks.length || 0); 388*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(bPtr, lineBreaks); 389*c8dee2aaSAndroid Build Coastguard Worker }; 390*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ParagraphBuilder.prototype.setLineBreaksUtf16 = function(lineBreaks) { 391*c8dee2aaSAndroid Build Coastguard Worker var bPtr = copy1dArray(lineBreaks, 'HEAPU32'); 392*c8dee2aaSAndroid Build Coastguard Worker this._setLineBreaksUtf16(bPtr, lineBreaks && lineBreaks.length || 0); 393*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(bPtr, lineBreaks); 394*c8dee2aaSAndroid Build Coastguard Worker }; 395*c8dee2aaSAndroid Build Coastguard Worker}); 396*c8dee2aaSAndroid Build Coastguard Worker}(Module)); // When this file is loaded in, the high level object is "Module"; 397