This repository was archived by the owner on Nov 16, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmeasurer.js
More file actions
71 lines (61 loc) · 1.66 KB
/
measurer.js
File metadata and controls
71 lines (61 loc) · 1.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
'use strict'
const puppeteer = require('puppeteer')
module.exports = class Measurer {
constructor({ font = '110px Verdana' } = {}) {
this.font = font
this.browser = undefined
this.page = undefined
}
async init() {
this.browser = await puppeteer.launch()
this.page = await this.browser.newPage()
await this.page.evaluate(() => {
window.canvas = document.createElement('canvas')
})
}
async destroy() {
return this.browser.close()
}
async widthOf(text) {
const { font } = this
return this.page.evaluate(
({ text, font }) => {
const ctx = window.canvas.getContext('2d')
ctx.font = font
return ctx.measureText(text).width
},
{ text, font }
)
}
async widthOfRange([lower, upper], { precision = 2 } = {}) {
const widths = []
for (let charCode = lower; charCode < upper; ++charCode) {
let width
if (charCode < 32) {
width = 0.0
} else {
const char = String.fromCharCode(charCode)
width = await this.widthOf(char)
}
widths.push(parseFloat(width.toFixed(precision)))
}
return widths
}
async kerningAdjustmentFor(
firstCharCode,
secondCharCode,
{ precision = 4 } = {}
) {
const first = String.fromCharCode(firstCharCode)
const second = String.fromCharCode(secondCharCode)
const pair = `${first}${second}`
const asPair = await this.widthOf(pair)
const individually =
(await this.widthOf(first)) + (await this.widthOf(second))
if (asPair === individually) {
return undefined
} else {
return parseFloat((asPair - individually).toFixed(precision))
}
}
}