1// Functions dealing with parsing/stringifying fonts go here. 2var fontStringRegex = new RegExp( 3 '(italic|oblique|normal|)\\s*' + // style 4 '(small-caps|normal|)\\s*' + // variant 5 '(bold|bolder|lighter|[1-9]00|normal|)\\s*' + // weight 6 '([\\d\\.]+)' + // size 7 '(px|pt|pc|in|cm|mm|%|em|ex|ch|rem|q)' + // unit 8 // line-height is ignored here, as per the spec 9 '(.+)' // family 10 ); 11 12function stripWhitespace(str) { 13 return str.replace(/^\s+|\s+$/, ''); 14} 15 16var defaultHeight = 16; 17// Based off of node-canvas's parseFont 18// returns font size in px, which represents the em width. 19function parseFontString(fontStr) { 20 21 var font = fontStringRegex.exec(fontStr); 22 if (!font) { 23 SkDebug('Invalid font string ' + fontStr); 24 return null; 25 } 26 27 var size = parseFloat(font[4]); 28 var sizePx = defaultHeight; 29 var unit = font[5]; 30 switch (unit) { 31 case 'em': 32 case 'rem': 33 sizePx = size * defaultHeight; 34 break; 35 case 'pt': 36 sizePx = size * 4/3; 37 break; 38 case 'px': 39 sizePx = size; 40 break; 41 case 'pc': 42 sizePx = size * defaultHeight; 43 break; 44 case 'in': 45 sizePx = size * 96; 46 break; 47 case 'cm': 48 sizePx = size * 96.0 / 2.54; 49 break; 50 case 'mm': 51 sizePx = size * (96.0 / 25.4); 52 break; 53 case 'q': // quarter millimeters 54 sizePx = size * (96.0 / 25.4 / 4); 55 break; 56 case '%': 57 sizePx = size * (defaultHeight / 75); 58 break; 59 } 60 return { 61 'style': font[1], 62 'variant': font[2], 63 'weight': font[3], 64 'sizePx': sizePx, 65 'family': font[6].trim() 66 }; 67} 68 69function getTypeface(fontstr) { 70 var descriptors = parseFontString(fontstr); 71 var typeface = getFromFontCache(descriptors); 72 descriptors['typeface'] = typeface; 73 return descriptors; 74} 75 76// null means use the default typeface (which is currently NotoMono) 77var fontCache = { 78 'Noto Mono': { 79 '*': null, // is used if we have this font family, but not the right style/variant/weight 80 }, 81 'monospace': { 82 '*': null, 83 } 84}; 85 86// descriptors is like https://developer.mozilla.org/en-US/docs/Web/API/FontFace/FontFace 87// The ones currently supported are family, style, variant, weight. 88function addToFontCache(typeface, descriptors) { 89 var key = (descriptors['style'] || 'normal') + '|' + 90 (descriptors['variant'] || 'normal') + '|' + 91 (descriptors['weight'] || 'normal'); 92 var fam = descriptors['family']; 93 if (!fontCache[fam]) { 94 // preload with a fallback to this typeface 95 fontCache[fam] = { 96 '*': typeface, 97 }; 98 } 99 fontCache[fam][key] = typeface; 100} 101 102function getFromFontCache(descriptors) { 103 var key = (descriptors['style'] || 'normal') + '|' + 104 (descriptors['variant'] || 'normal') + '|' + 105 (descriptors['weight'] || 'normal'); 106 var fam = descriptors['family']; 107 if (!fontCache[fam]) { 108 return null; 109 } 110 return fontCache[fam][key] || fontCache[fam]['*']; 111} 112 113CanvasKit._testing['parseFontString'] = parseFontString;