gctGenerator/site/.vuepress/components/codes/text.js
sup39 3a730390ac Customized Display 0.4
- Rewrote with C2
- Implemented a more complex assembler/compiler to support function call
- Add options
  - Invincibility Timer
  - Pollution Degree
  - Spin Jump Condition Check
2023-01-31 22:06:41 +09:00

54 lines
1.4 KiB
JavaScript

/** @typedef {{index: number, kerning: number, width: number, code: number}} CharInfo */
import charInfoJP from '../../data/charInfo-JP.json';
import charInfoEU from '../../data/charInfo-EU.json';
/**
* @param {string} version
*/
const getFontInfo = (version) =>
['GMSJ01', 'GMSJ0A'].includes(version)
? {
// JP
charInfo: /**@type{Record<string, CharInfo>}*/ (charInfoJP),
rowSize: 24, // how many char in a row of the img
}
: {
// EU (TODO US)
charInfo: /**@type{Record<string, CharInfo>}*/ (charInfoEU),
rowSize: 16, // how many char in a row of the img
};
/**
* @param {string} text
* @param {string} version
*/
export function measureText(text, version) {
const { charInfo, rowSize } = getFontInfo(version);
/** @type {{x: number, y: number, u: number, v: number}[]} */
const chars = [];
let x = 0;
let y = 0;
let w = 0;
let useKerning = false;
text.split('').forEach((c) => {
const { index, kerning, width } = charInfo[c] ?? charInfo['?'];
if (c === '\n') {
useKerning = false;
x = 0;
y += 20;
return;
}
if (useKerning) x -= kerning;
useKerning = true;
// uv
const [u, v] = [(index % rowSize) * 20, ((index / rowSize) | 0) * 20];
chars.push({ x, y, u, v });
// next
x += width + kerning;
// update width
if (x > w) w = x;
});
return { chars, width: w, height: y + 20 };
}