-
Notifications
You must be signed in to change notification settings - Fork 6
/
index.js
94 lines (85 loc) · 2.87 KB
/
index.js
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
const log = require('loglevel');
const { PNG } = require('pngjs');
const fonts = {
sevenPlus: require('./data/seven-plus.json'),
slumbers: require('./data/slumbers.json')
};
const gap = [[0]];
const areTouching = (first, second) => {
for (let i = 0; i < first.length; ++i) {
if (first[i] && first[i][first[i].length - 1] === 1) {
for (j = -1; j <= 1; ++j) {
if (second[i+j] && second[i+j][0] === 1) {
return true;
}
}
}
}
}
const renderLine = (text, font) => {
const letters = text.split("");
const characters = [];
let maxHeight = 0;
for (let letter of letters) {
let glyph = font.glyphs[""];
if (font.glyphs[letter]) {
glyph = font.glyphs[letter]
} else {
log.warn(`Missing letter ${letter}`)
}
let newCharacter = [];
glyph.pixels.forEach((row, index) => {
newCharacter[index + glyph.offset] = row;
});
maxHeight = Math.max(maxHeight, newCharacter.length);
if (font.isFixedWidth ||
(characters.length && areTouching(characters[characters.length-1], newCharacter))) {
characters.push(gap);
}
characters.push(newCharacter);
}
return characters.reduce((acc, cur) => {
const blankRow = Array(cur[cur.length - 1].length).fill(0);
for (let i = 0; i < maxHeight; ++i) {
const row = cur[i] || blankRow;
acc[i].push(...row);
}
return acc;
}, Array(maxHeight).fill(0).map(_ => []));
}
const renderPixels = (text, font) => {
const lines = text.split("\n").map(line => [[0]].concat(renderLine(line, font)));
lines[0].shift();
return [].concat(...lines);
};
const withAlpha = ([r, g, b, a = 255]) => [r, g, b, a];
const renderImage = (text, font, { foreground, background, scale = 1}) => {
const pixels = renderPixels(text, font);
const width = pixels.reduce((acc, cur) => Math.max(acc, cur.length), 0);
const height = pixels.length;
const png = new PNG({
width: width * scale,
height: height * scale
});
const foregroundColour = withAlpha(foreground);
const backgroundColour = withAlpha(background);
for (let y = 0; y < height; ++y) {
for(let x = 0; x < width; ++x) {
const colour = pixels[y][x] ? foregroundColour : backgroundColour;
for(let j = 0; j < scale; ++j) {
for (let i = 0; i < scale; ++i) {
for(let component = 0; component < 4; ++component) {
png.data[(((x * scale + i) + ((y * scale + j) * png.width)) << 2) + component] =
colour[component];
}
}
}
}
}
return png.pack();
}
module.exports = {
fonts,
renderPixels,
renderImage
}