Skip to content

Commit 9129399

Browse files
authored
Merge pull request #891 from yever/master
Parse font using parse-css-font and units-css
2 parents 610e3ad + 3d54505 commit 9129399

File tree

3 files changed

+46
-39
lines changed

3 files changed

+46
-39
lines changed

lib/context2d.js

Lines changed: 31 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ var canvas = require('./bindings')
1616
, CanvasPattern = canvas.CanvasPattern
1717
, ImageData = canvas.ImageData;
1818

19+
var parseCssFont = require('parse-css-font');
20+
21+
var unitsCss = require('units-css');
22+
1923
/**
2024
* Export `Context2d` as the module.
2125
*/
@@ -34,26 +38,6 @@ var cache = {};
3438

3539
var baselines = ['alphabetic', 'top', 'bottom', 'middle', 'ideographic', 'hanging'];
3640

37-
/**
38-
* Font RegExp helpers.
39-
*/
40-
41-
var weights = 'normal|bold|bolder|lighter|[1-9]00'
42-
, styles = 'normal|italic|oblique'
43-
, units = 'px|pt|pc|in|cm|mm|%'
44-
, string = '\'([^\']+)\'|"([^"]+)"|[\\w-]+';
45-
46-
/**
47-
* Font parser RegExp;
48-
*/
49-
50-
var fontre = new RegExp('^ *'
51-
+ '(?:(' + weights + ') *)?'
52-
+ '(?:(' + styles + ') *)?'
53-
+ '([\\d\\.]+)(' + units + ') *'
54-
+ '((?:' + string + ')( *, *(?:' + string + '))*)'
55-
);
56-
5741
/**
5842
* Parse font `str`.
5943
*
@@ -62,42 +46,51 @@ var fontre = new RegExp('^ *'
6246
* @api private
6347
*/
6448

65-
var parseFont = exports.parseFont = function(str){
66-
var font = {}
67-
, captures = fontre.exec(str);
49+
var parseFont = exports.parseFont = function(str) {
50+
var parsedFont;
6851

69-
// Invalid
70-
if (!captures) return;
52+
// Try to parse the font string using parse-css-font.
53+
// It will throw an exception if it fails.
54+
try {
55+
parsedFont = parseCssFont(str);
56+
}
57+
catch (e) {
58+
// Invalid
59+
return;
60+
}
7161

7262
// Cached
7363
if (cache[str]) return cache[str];
7464

75-
// Populate font object
76-
font.weight = captures[1] || 'normal';
77-
font.style = captures[2] || 'normal';
78-
font.size = parseFloat(captures[3]);
79-
font.unit = captures[4];
80-
font.family = captures[5].replace(/["']/g, '').split(',').map(function (family) {
81-
return family.trim();
82-
}).join(',');
65+
// Parse size into value and unit using units-css
66+
var size = unitsCss.parse(parsedFont.size);
8367

8468
// TODO: dpi
8569
// TODO: remaining unit conversion
86-
switch (font.unit) {
70+
switch (size.unit) {
8771
case 'pt':
88-
font.size /= .75;
72+
size.value /= .75;
8973
break;
9074
case 'in':
91-
font.size *= 96;
75+
size.value *= 96;
9276
break;
9377
case 'mm':
94-
font.size *= 96.0 / 25.4;
78+
size.value *= 96.0 / 25.4;
9579
break;
9680
case 'cm':
97-
font.size *= 96.0 / 2.54;
81+
size.value *= 96.0 / 2.54;
9882
break;
9983
}
10084

85+
// Populate font object
86+
var font = {
87+
weight: parsedFont.weight,
88+
style: parsedFont.style,
89+
size: size.value,
90+
unit: size.unit,
91+
family: parsedFont.family.join(',')
92+
};
93+
10194
return cache[str] = font;
10295
};
10396

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
"test-server": "node test/server.js"
3030
},
3131
"dependencies": {
32-
"nan": "^2.4.0"
32+
"nan": "^2.4.0",
33+
"parse-css-font": "^2.0.2",
34+
"units-css": "^0.4.0"
3335
},
3436
"devDependencies": {
3537
"express": "^4.14.0",

test/public/tests.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,18 @@ tests['font family invalid'] = function (ctx) {
999999
ctx.fillText('14px Invalid, Impact', 100, 100)
10001000
}
10011001

1002+
tests['font style variant weight size family'] = function (ctx) {
1003+
ctx.strokeStyle = '#666'
1004+
ctx.strokeRect(0, 0, 200, 200)
1005+
ctx.lineTo(0, 100)
1006+
ctx.lineTo(200, 100)
1007+
ctx.stroke()
1008+
1009+
ctx.font = 'normal normal normal 16px Impact'
1010+
ctx.textAlign = 'center'
1011+
ctx.fillText('normal normal normal 16px', 100, 100)
1012+
}
1013+
10021014
tests['globalCompositeOperation source-over'] = function (ctx) {
10031015
ctx.fillStyle = 'blue'
10041016
ctx.fillRect(0, 0, 100, 100)

0 commit comments

Comments
 (0)