faviconWriter.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. const fs = require('fs')
  2. ,Jimp = require('jimp')
  3. ,COLOR_MESSAGE = 0x96AFFFFF
  4. ,COLOR_HIGHLIGHT = 0x4C9689FF //rgb(76, 150, 137);
  5. var font = {}
  6. ,FONTNAME = __dirname +"/../res/absender1.fnt";
  7. FONTNAME = Jimp.FONT_SANS_128_BLACK;
  8. function FaviconWriter() { }
  9. function loadFont(fontname, cb) {
  10. if (!font[fontname]) {
  11. Jimp.loadFont(fontname).then((f) => {
  12. font[fontname] = f;
  13. cb(f);
  14. });
  15. } else {
  16. cb(font[fontname]);
  17. }
  18. }
  19. function centerText(image, font, fontHeight, color, text) {
  20. var imageWidth = image.bitmap.width
  21. ,imageHeight = image.bitmap.height
  22. ,fontCalc = new Jimp(imageWidth, imageHeight)
  23. ,fontPos = {
  24. minX: Infinity
  25. ,maxX: -Infinity
  26. ,minY: Infinity
  27. ,maxY: -Infinity
  28. };
  29. fontCalc.print(font, 0, 0, text);
  30. for (var i =0; i < imageWidth; i++)
  31. for (var j =0; j < imageHeight; j++)
  32. if (fontCalc.getPixelColor(i, j) !== 0x00000000) {
  33. fontCalc.setPixelColor(color, i, j);
  34. fontPos.minX = Math.min(fontPos.minX, i);
  35. fontPos.maxX = Math.max(fontPos.maxX, i);
  36. fontPos.minY = Math.min(fontPos.minY, j);
  37. fontPos.maxY = Math.max(fontPos.maxY, j);
  38. }
  39. var margin = 10;
  40. fontPos.minX = Math.max(fontPos.minX -margin, 0);
  41. fontPos.maxX = Math.min(fontPos.maxX +margin, imageWidth);
  42. var sourceWidth = fontPos.maxX -fontPos.minX
  43. ,sourceHeight = fontPos.maxY -fontPos.minY
  44. ,zoomFactor = Math.min(imageWidth /sourceWidth, fontHeight /sourceHeight);
  45. fontCalc.crop(fontPos.minX, fontPos.minY, sourceWidth, sourceHeight);
  46. fontCalc.scale(zoomFactor);
  47. image.blit(
  48. fontCalc, // font printed image
  49. (imageWidth/2) - (sourceWidth *zoomFactor /2), // target x
  50. (imageHeight/2) -(sourceHeight *zoomFactor /2), // target y
  51. 0, // source x
  52. 0, // source y
  53. sourceWidth *zoomFactor, // source width
  54. sourceHeight *zoomFactor); // source height
  55. return image;
  56. }
  57. function newImage(text, color, cb) {
  58. loadFont(FONTNAME, (font) => {
  59. centerText(new Jimp(256, 256), font, 236, color, text)
  60. .getBuffer(Jimp.MIME_PNG, (_, buf) => {
  61. cb(buf);
  62. });
  63. });
  64. }
  65. /**
  66. * @param {number} unreadHi
  67. * @param {number} unread
  68. * @param {http.ServerResponse} res
  69. **/
  70. FaviconWriter.write = function(unreadHi, unread, cb) {
  71. if (unreadHi) {
  72. newImage('!' +unreadHi, COLOR_HIGHLIGHT, cb);
  73. } else if (unread) {
  74. newImage('' +unread, COLOR_MESSAGE, cb);
  75. } else {
  76. try {
  77. var stat = fs.statSync("public/favicon_ok.png")
  78. res.setHeader('Content-Length', stat.size);
  79. res.writeHeader("200");
  80. fs.createReadStream("public/favicon_ok.png").pipe(res, { end: true });
  81. } catch (e) {
  82. console.error("WTF cannot find favicon_ok.png in public dir");
  83. res.writeHeader("404", "Not Found");
  84. res.end();
  85. }
  86. }
  87. };
  88. module.exports = { FaviconWriter: FaviconWriter };