|
|
@@ -0,0 +1,101 @@
|
|
|
+const fs = require('fs')
|
|
|
+ ,Jimp = require('jimp')
|
|
|
+
|
|
|
+ ,COLOR_MESSAGE = 0x96AFFFFF
|
|
|
+ ,COLOR_HIGHLIGHT = 0x4C9689FF //rgb(76, 150, 137);
|
|
|
+
|
|
|
+var font = {}
|
|
|
+ ,FONTNAME = __dirname +"/../res/absender1.fnt";
|
|
|
+
|
|
|
+FONTNAME = Jimp.FONT_SANS_128_BLACK;
|
|
|
+
|
|
|
+function FaviconWriter() { }
|
|
|
+
|
|
|
+function loadFont(fontname, cb) {
|
|
|
+ if (!font[fontname]) {
|
|
|
+ Jimp.loadFont(fontname).then((f) => {
|
|
|
+ font[fontname] = f;
|
|
|
+ cb(f);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ cb(font[fontname]);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function centerText(image, font, fontHeight, color, text) {
|
|
|
+ var imageWidth = image.bitmap.width
|
|
|
+ ,imageHeight = image.bitmap.height
|
|
|
+ ,fontCalc = new Jimp(imageWidth, imageHeight)
|
|
|
+ ,fontPos = {
|
|
|
+ minX: Infinity
|
|
|
+ ,maxX: -Infinity
|
|
|
+ ,minY: Infinity
|
|
|
+ ,maxY: -Infinity
|
|
|
+ };
|
|
|
+
|
|
|
+ fontCalc.print(font, 0, 0, text);
|
|
|
+ for (var i =0; i < imageWidth; i++)
|
|
|
+ for (var j =0; j < imageHeight; j++)
|
|
|
+ if (fontCalc.getPixelColor(i, j) !== 0x00000000) {
|
|
|
+ fontCalc.setPixelColor(color, i, j);
|
|
|
+ fontPos.minX = Math.min(fontPos.minX, i);
|
|
|
+ fontPos.maxX = Math.max(fontPos.maxX, i);
|
|
|
+ fontPos.minY = Math.min(fontPos.minY, j);
|
|
|
+ fontPos.maxY = Math.max(fontPos.maxY, j);
|
|
|
+ }
|
|
|
+ var margin = 10;
|
|
|
+ fontPos.minX = Math.max(fontPos.minX -margin, 0);
|
|
|
+ fontPos.maxX = Math.min(fontPos.maxX +margin, imageWidth);
|
|
|
+ var sourceWidth = fontPos.maxX -fontPos.minX
|
|
|
+ ,sourceHeight = fontPos.maxY -fontPos.minY
|
|
|
+ ,zoomFactor = Math.min(imageWidth /sourceWidth, fontHeight /sourceHeight);
|
|
|
+
|
|
|
+ fontCalc.crop(fontPos.minX, fontPos.minY, sourceWidth, sourceHeight);
|
|
|
+ fontCalc.scale(zoomFactor);
|
|
|
+
|
|
|
+ image.blit(
|
|
|
+ fontCalc, // font printed image
|
|
|
+ (imageWidth/2) - (sourceWidth *zoomFactor /2), // target x
|
|
|
+ (imageHeight/2) -(sourceHeight *zoomFactor /2), // target y
|
|
|
+ 0, // source x
|
|
|
+ 0, // source y
|
|
|
+ sourceWidth *zoomFactor, // source width
|
|
|
+ sourceHeight *zoomFactor); // source height
|
|
|
+ return image;
|
|
|
+}
|
|
|
+
|
|
|
+function newImage(text, color, cb) {
|
|
|
+ loadFont(FONTNAME, (font) => {
|
|
|
+ centerText(new Jimp(256, 256), font, 236, color, text)
|
|
|
+ .getBuffer(Jimp.MIME_PNG, (_, buf) => {
|
|
|
+ cb(buf);
|
|
|
+ });
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @param {number} unreadHi
|
|
|
+ * @param {number} unread
|
|
|
+ * @param {http.ServerResponse} res
|
|
|
+**/
|
|
|
+FaviconWriter.write = function(unreadHi, unread, cb) {
|
|
|
+ if (unreadHi) {
|
|
|
+ newImage('!' +unreadHi, COLOR_HIGHLIGHT, cb);
|
|
|
+ } else if (unread) {
|
|
|
+ newImage('' +unread, COLOR_MESSAGE, cb);
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ var stat = fs.statSync("public/favicon_ok.png")
|
|
|
+ res.setHeader('Content-Length', stat.size);
|
|
|
+ res.writeHeader("200");
|
|
|
+ fs.createReadStream("public/favicon_ok.png").pipe(res, { end: true });
|
|
|
+ } catch (e) {
|
|
|
+ console.error("WTF cannot find favicon_ok.png in public dir");
|
|
|
+ res.writeHeader("404", "Not Found");
|
|
|
+ res.end();
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+module.exports = { FaviconWriter: FaviconWriter };
|
|
|
+
|