Skip to content

Commit

Permalink
🐛 Fix overflow issues and wrong initial values for bitmap font generator
Browse files Browse the repository at this point in the history
Closes #220
  • Loading branch information
CosmoMyzrailGorynych committed Aug 25, 2020
1 parent f4df658 commit 44e9bbe
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 28 deletions.
28 changes: 21 additions & 7 deletions src/node_requires/resources/fonts/bitmapFontGenerator/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ const opentype = require('opentype.js');
const draw = function draw(ctx, glyphList, descend, options) {
var dict = {};

var drawX = 0;
var drawY = 0;
var drawX = 1;
var drawY = 1;
var drawHeight = options.baseline + descend;
var mg;

Expand All @@ -25,8 +25,8 @@ const draw = function draw(ctx, glyphList, descend, options) {
drawWidth = g.width;
}
if (drawX + drawWidth > ctx.canvas.width) {
drawX = 0;
drawY += drawHeight + options.margin;
drawX = 1;
drawY += drawHeight + options.margin * 2;
}
var path = g.glyph.getPath(drawX + (drawWidth / 2) - (g.width / 2), drawY + options.baseline, options.height);
path.fill = options.fill;
Expand All @@ -43,7 +43,7 @@ const draw = function draw(ctx, glyphList, descend, options) {
};
});
}
drawX += drawWidth + options.margin;
drawX += drawWidth + options.margin * 2;
}
});

Expand All @@ -52,6 +52,7 @@ const draw = function draw(ctx, glyphList, descend, options) {
};
};

// eslint-disable-next-line max-lines-per-function
const generateBitmapFont = async function generateBitmapFont(fontSrc, outputPath, options, callback) {
const fs = require('fs-extra');
const buffer = await fs.readFile(fontSrc);
Expand All @@ -66,6 +67,7 @@ const generateBitmapFont = async function generateBitmapFont(fontSrc, outputPath

var lostChars = [];
var glyphList = [];

Array.from(options.list).forEach((char) => {
const [glyph] = font.stringToGlyphs(char);
glyph.font = font;
Expand Down Expand Up @@ -107,9 +109,20 @@ const generateBitmapFont = async function generateBitmapFont(fontSrc, outputPath
// Calculate the required canvas size
var canvasSize;
if (options.width === void 0) {
canvasSize = util.calculateCanvasSizeProp(options.list, glyphList, adjustedHeight, options.baseline + descend);
canvasSize = util.calculateCanvasSizeProp(
options.list,
glyphList,
adjustedHeight,
options.baseline + descend,
options.margin || 1
);
} else {
canvasSize = util.calculateCanvasSize(options.list, options.width, adjustedHeight);
canvasSize = util.calculateCanvasSize(
options.list,
options.width,
adjustedHeight,
options.margin || 1
);
}

// Check if the created canvas size is valid
Expand Down Expand Up @@ -141,6 +154,7 @@ const generateBitmapFont = async function generateBitmapFont(fontSrc, outputPath
'Try Using other font or characters.');
}
await util.outputBitmapFont(outputPath, canvas, callback);

return {
map: drawResult.map,
missingGlyph: drawResult.missingGlyph,
Expand Down
35 changes: 18 additions & 17 deletions src/node_requires/resources/fonts/bitmapFontGenerator/util.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable max-len */
const fs = require('fs').promises;

const calculateCanvasSize = function calculateCanvasSize(text, charWidth, charHeight) {
const calculateCanvasSize = function calculateCanvasSize(text, charWidth, charHeight, margin) {
if (charWidth <= 0 || charHeight <= 0) {
return {
width: -1, height: -1
Expand All @@ -12,13 +12,13 @@ const calculateCanvasSize = function calculateCanvasSize(text, charWidth, charHe
var canvasSquareSideSize = 1;

// Find the length of the side of a square that can contain characters
while ((canvasSquareSideSize / charWidth) * (canvasSquareSideSize / charHeight) < textSize) {
while ((canvasSquareSideSize / (charWidth + margin * 2)) * (canvasSquareSideSize / (charHeight + margin * 2)) < textSize) {
canvasSquareSideSize *= 2;
}
var canvasWidth = canvasSquareSideSize;

// CanvasSquareSideSize cannot be used because it may not be square
var tmpCanvasHeight = Math.ceil(textSize / Math.floor(canvasWidth / charWidth)) * charHeight;
var tmpCanvasHeight = Math.ceil(textSize / Math.floor(canvasWidth / (charWidth + margin * 2))) * (charHeight + margin * 2);
var canvasHeight = 1;
while (canvasHeight < tmpCanvasHeight) {
canvasHeight *= 2;
Expand All @@ -29,34 +29,35 @@ const calculateCanvasSize = function calculateCanvasSize(text, charWidth, charHe
};
};

const canGoIn = function canGoIn(canvasSize, glyphList, charHeight) {
var drawX = 0;
var drawY = 0;
const canGoIn = function canGoIn(canvasSize, glyphList, charHeight, margin) {
var drawX = 1;
var drawY = 1;

glyphList.forEach(glyph => {
if (drawX + glyph.width > canvasSize.width) {
drawX = 0;
drawY += charHeight;
if (drawX + glyph.width + margin * 2 > canvasSize.width) {
drawX = 1;
drawY += charHeight + margin * 2;
}
drawX += glyph.width;
drawX += glyph.width + margin * 2;
});

return drawY + charHeight < canvasSize.height;
return drawY + charHeight + margin * 2 < canvasSize.height;
};

const calculateCanvasSizeProp = function calculateCanvasSizeProp(
text,
glyphList,
height,
charHeight
charHeight,
margin
) {
var widthAverage = 0;
var widthMax = 0;
glyphList.forEach(glyph => {
if (glyph.width > widthMax) {
widthMax = glyph.width;
if (glyph.width + margin * 2 > widthMax) {
widthMax = glyph.width + margin * 2;
}
widthAverage += glyph.width;
widthAverage += glyph.width + margin * 2;
});
widthAverage /= glyphList.length;

Expand All @@ -66,9 +67,9 @@ const calculateCanvasSizeProp = function calculateCanvasSizeProp(
};
}
// Use the average value to calculate the approximate size
var canvasSize = calculateCanvasSize(text, widthAverage, height);
var canvasSize = calculateCanvasSize(text, widthAverage, height, margin);
// Increase the vertical width until the text can be entered
while (!canGoIn(canvasSize, glyphList, charHeight)) {
while (!canGoIn(canvasSize, glyphList, charHeight, margin)) {
canvasSize.height *= 2;
}
return canvasSize;
Expand Down
6 changes: 3 additions & 3 deletions src/node_requires/resources/fonts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ const importTtfToFont = async function importTtfToFont(src) {
italic: false,
origname: `f${uid}.ttf`,
lastmod: Number(new Date()),
pixelFont: false,
pixelFontSize: 16,
pixelFontLineHeight: 18,
bitmapFont: false,
bitmapFontSize: 16,
bitmapFontLineHeight: 18,
charsets: ['allInFont'],
customCharset: '',
uid
Expand Down
2 changes: 1 addition & 1 deletion src/riotTags/main-menu.tag
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ main-menu.flexcol
const runCtExport = require('./data/node_requires/exporter');
const exportFile = path.join(
buildFolder,
`${currentProject.settings.authoring.title || 'ct.js game'}.zip`
`${global.currentProject.settings.authoring.title || 'ct.js game'}.zip`
);
const inDir = await getExportDir();
await fs.remove(exportFile);
Expand Down

0 comments on commit 44e9bbe

Please sign in to comment.