69 lines
1.9 KiB
JavaScript

// Write font data into png images
'use strict';
const path = require('path');
const { PNG } = require('pngjs');
const AppError = require('../app_error');
const utils = require('../utils');
const normal_color = [ 255, 255, 255 ];
const outside_color = [ 255, 127, 184 ];
module.exports = function write_images(args, font) {
if (!args.output) throw new AppError('Output is required for "dump" writer');
let files = {};
let glyphs = font.glyphs.map(glyph => utils.set_depth(glyph, args.bpp));
for (let glyph of glyphs) {
let { code, advanceWidth, bbox, pixels } = glyph;
advanceWidth = Math.round(advanceWidth);
let minX = bbox.x;
let maxX = Math.max(bbox.x + bbox.width - 1, bbox.x);
let minY = Math.min(bbox.y, font.typoDescent);
let maxY = Math.max(bbox.y + bbox.height - 1, font.typoAscent);
let png = new PNG({ width: maxX - minX + 1, height: maxY - minY + 1 });
/* eslint-disable max-depth */
for (let pos = 0, y = maxY; y >= minY; y--) {
for (let x = minX; x <= maxX; x++) {
let value = 0;
if (x >= bbox.x && x < bbox.x + bbox.width && y >= bbox.y && y < bbox.y + bbox.height) {
value = pixels[bbox.height - (y - bbox.y) - 1][x - bbox.x];
}
let r, g, b;
if (x < 0 || x >= advanceWidth || y < font.typoDescent || y > font.typoAscent) {
[ r, g, b ] = outside_color;
} else {
[ r, g, b ] = normal_color;
}
png.data[pos++] = (255 - value) * r / 255;
png.data[pos++] = (255 - value) * g / 255;
png.data[pos++] = (255 - value) * b / 255;
png.data[pos++] = 255;
}
}
files[path.join(args.output, `${code.toString(16)}.png`)] = PNG.sync.write(png);
}
files[path.join(args.output, 'font_info.json')] = JSON.stringify(
font,
(k, v) => (k === 'pixels' && !args.full_info ? undefined : v),
2);
return files;
};