2018-12-10 17:41:26 +00:00
|
|
|
// Functions dealing with parsing/stringifying fonts go here.
|
2018-12-14 20:03:41 +00:00
|
|
|
var fontStringRegex = new RegExp(
|
|
|
|
'(italic|oblique|normal|)\\s*' + // style
|
|
|
|
'(small-caps|normal|)\\s*' + // variant
|
|
|
|
'(bold|bolder|lighter|[1-9]00|normal|)\\s*' + // weight
|
|
|
|
'([\\d\\.]+)' + // size
|
|
|
|
'(px|pt|pc|in|cm|mm|%|em|ex|ch|rem|q)' + // unit
|
|
|
|
// line-height is ignored here, as per the spec
|
|
|
|
'(.+)' // family
|
|
|
|
);
|
|
|
|
|
|
|
|
function stripWhitespace(str) {
|
|
|
|
return str.replace(/^\s+|\s+$/, '');
|
|
|
|
}
|
2018-12-10 17:41:26 +00:00
|
|
|
|
2018-12-12 15:35:13 +00:00
|
|
|
var defaultHeight = 16;
|
2018-12-10 17:41:26 +00:00
|
|
|
// Based off of node-canvas's parseFont
|
2018-12-12 15:35:13 +00:00
|
|
|
// returns font size in px, which represents the em width.
|
2018-12-14 20:03:41 +00:00
|
|
|
function parseFontString(fontStr) {
|
|
|
|
|
|
|
|
var font = fontStringRegex.exec(fontStr);
|
|
|
|
if (!font) {
|
2020-10-07 20:09:22 +00:00
|
|
|
Debug('Invalid font string ' + fontStr);
|
2018-12-14 20:03:41 +00:00
|
|
|
return null;
|
2018-12-10 17:41:26 +00:00
|
|
|
}
|
2018-12-14 20:03:41 +00:00
|
|
|
|
|
|
|
var size = parseFloat(font[4]);
|
|
|
|
var sizePx = defaultHeight;
|
|
|
|
var unit = font[5];
|
2018-12-10 17:41:26 +00:00
|
|
|
switch (unit) {
|
2018-12-12 15:35:13 +00:00
|
|
|
case 'em':
|
|
|
|
case 'rem':
|
2018-12-14 20:03:41 +00:00
|
|
|
sizePx = size * defaultHeight;
|
|
|
|
break;
|
|
|
|
case 'pt':
|
|
|
|
sizePx = size * 4/3;
|
|
|
|
break;
|
2018-12-10 17:41:26 +00:00
|
|
|
case 'px':
|
2018-12-14 20:03:41 +00:00
|
|
|
sizePx = size;
|
|
|
|
break;
|
2018-12-10 17:41:26 +00:00
|
|
|
case 'pc':
|
2018-12-14 20:03:41 +00:00
|
|
|
sizePx = size * defaultHeight;
|
|
|
|
break;
|
2018-12-10 17:41:26 +00:00
|
|
|
case 'in':
|
2018-12-14 20:03:41 +00:00
|
|
|
sizePx = size * 96;
|
|
|
|
break;
|
2018-12-10 17:41:26 +00:00
|
|
|
case 'cm':
|
2018-12-14 20:03:41 +00:00
|
|
|
sizePx = size * 96.0 / 2.54;
|
|
|
|
break;
|
2018-12-10 17:41:26 +00:00
|
|
|
case 'mm':
|
2018-12-14 20:03:41 +00:00
|
|
|
sizePx = size * (96.0 / 25.4);
|
|
|
|
break;
|
2018-12-12 15:35:13 +00:00
|
|
|
case 'q': // quarter millimeters
|
2018-12-14 20:03:41 +00:00
|
|
|
sizePx = size * (96.0 / 25.4 / 4);
|
|
|
|
break;
|
2018-12-10 17:41:26 +00:00
|
|
|
case '%':
|
2018-12-14 20:03:41 +00:00
|
|
|
sizePx = size * (defaultHeight / 75);
|
|
|
|
break;
|
2018-12-10 17:41:26 +00:00
|
|
|
}
|
2018-12-14 20:03:41 +00:00
|
|
|
return {
|
|
|
|
'style': font[1],
|
|
|
|
'variant': font[2],
|
|
|
|
'weight': font[3],
|
|
|
|
'sizePx': sizePx,
|
|
|
|
'family': font[6].trim()
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function getTypeface(fontstr) {
|
|
|
|
var descriptors = parseFontString(fontstr);
|
|
|
|
var typeface = getFromFontCache(descriptors);
|
|
|
|
descriptors['typeface'] = typeface;
|
|
|
|
return descriptors;
|
|
|
|
}
|
|
|
|
|
|
|
|
// null means use the default typeface (which is currently NotoMono)
|
|
|
|
var fontCache = {
|
|
|
|
'Noto Mono': {
|
|
|
|
'*': null, // is used if we have this font family, but not the right style/variant/weight
|
|
|
|
},
|
|
|
|
'monospace': {
|
|
|
|
'*': null,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// descriptors is like https://developer.mozilla.org/en-US/docs/Web/API/FontFace/FontFace
|
|
|
|
// The ones currently supported are family, style, variant, weight.
|
|
|
|
function addToFontCache(typeface, descriptors) {
|
|
|
|
var key = (descriptors['style'] || 'normal') + '|' +
|
|
|
|
(descriptors['variant'] || 'normal') + '|' +
|
|
|
|
(descriptors['weight'] || 'normal');
|
|
|
|
var fam = descriptors['family'];
|
|
|
|
if (!fontCache[fam]) {
|
|
|
|
// preload with a fallback to this typeface
|
|
|
|
fontCache[fam] = {
|
|
|
|
'*': typeface,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
fontCache[fam][key] = typeface;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getFromFontCache(descriptors) {
|
|
|
|
var key = (descriptors['style'] || 'normal') + '|' +
|
|
|
|
(descriptors['variant'] || 'normal') + '|' +
|
|
|
|
(descriptors['weight'] || 'normal');
|
|
|
|
var fam = descriptors['family'];
|
|
|
|
if (!fontCache[fam]) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return fontCache[fam][key] || fontCache[fam]['*'];
|
|
|
|
}
|
|
|
|
|
2020-10-07 20:09:22 +00:00
|
|
|
CanvasKit._testing['parseFontString'] = parseFontString;
|