[Cocos Creator] a solution to dynamically generate bitmap fonts using TTF and text configuration

Posted by janice on Fri, 14 Jan 2022 20:40:19 +0100

Game development requires the use of fonts.

Using TTF font directly has the advantage of easy development.

The disadvantages are fatal:

  1. The TTF font file is too large and contains unnecessary words, which increases the package and slows down the loading speed;
  2. Some platforms do not support loading TTF files; (the author has encountered this problem: the dynamic simplified TTF file can be loaded on wechat platform, but not on hand Q platform and Android platform);

In order to solve the font loading problem of the whole platform, we have to choose bitmap font.

Based on the premise of using bitmap font, we customize our solution.

The core problem of the solution is described in one sentence: how to create a bitmap font file from a text file (containing the required characters)?

Solution

If you don't want to see the principle, you can go directly to the last open source part

1. Create words Txt is used to store text

Special attention is paid to:

The save format is UTF-8. During the construction of bitmap font file, we will collect all fonts into temporary font summary text (which is not concerned by the outside world). Its format is UTF-16 LE CRLF

2. Everything is ready, but the procedure is poor

2.1 programs under Windows

The core idea is to use BMFont software to output the target file.
reference resources: Bitmap font production and use tutorial

  1. Download the official BMFont software Bitmap Font Generator(http://www.angelcode.com/products/bmfont/)

  2. Unzip the file and put bmfont1 14A move to demo build font / build_ Bmfont lower

  3. Follow the reference tutorial to generate the configuration bmfont bmfc

  4. Write npm package:

    	 "use strict";
    var __importDefault = (this && this.__importDefault) || function (mod) {
        return (mod && mod.__esModule) ? mod : { "default": mod };
    };
    Object.defineProperty(exports, "__esModule", { value: true });
    const child_process_1 = __importDefault(require("child_process"));
    const fs_extra_1 = __importDefault(require("fs-extra"));
    const minimist_1 = __importDefault(require("minimist"));
    const path_1 = __importDefault(require("path"));
    let argv = minimist_1.default(process.argv.slice(2));
    const srcPath = path_1.default.join(argv.src);
    const dstPath = path_1.default.join(argv.dst);
    const wordsTxtPath = path_1.default.join(srcPath, "Words.txt");
    const bmfcPath = path_1.default.join(srcPath, "bmfont.bmfc");
    const qhkFntPath = path_1.default.join(dstPath, "HQK.fnt");
    const allWordsTxtPath = path_1.default.join(dstPath, "AllWords.txt");
    const bmfont64exe = path_1.default.join(__dirname, "bmfont1.14a/bmfont64.exe");;
    
    console.log(">> build_bmfont >> Start");
    let callCmdSync = function (cmd, cwd) {
        console.log(`---->> stay ${cwd} Execute instructions under directory ${cmd} >>----`);
        let result = '';
        try {
            result = child_process_1.default.execSync(cmd, { cwd: cwd, encoding: 'utf-8' });
        }
        catch (error) {
            console.error(error);
        }
        console.log(result);
        return result;
    };
    
    
    console.log(`---->> Read dynamic font text ${wordsTxtPath} >>----`);
    let wordsTxtStr = fs_extra_1.default.readFileSync(wordsTxtPath, { encoding: 'utf-8' });
    console.log(wordsTxtStr);
    /**
     * It needs to be converted to utf16le and in crlf format
     * https://gist.github.com/zoellner/4af04a5a8b51f04ad653e26d3b7181ec
     */
    console.log("---->> Write text back dynamically >>----");
    const utf16buffer = Buffer.from(`\ufeff${wordsTxtStr}`, 'utf16le');
    fs_extra_1.default.writeFileSync(allWordsTxtPath, utf16buffer);
    
    callCmdSync(`${bmfont64exe} -t ${allWordsTxtPath} -c ${bmfcPath}  -o ${qhkFntPath}`, dstPath);
    
    console.log(">> build_bmfont >> End");
    
  5. In build_ Execute npm install initialization package under bmfont folder

  6. Double click to execute runwindows Bat will generate bitmap font files under dst

Open Source

Source code: demo-build-font

Use steps:

  1. Initialize environment
cd build_bmfont
npm install
  1. Double click runwindows Bat will generate bitmap fonts in the dst directory.

reference resources

Bitmap Font Generator
Making and using bitmap font
write utf-16 encoded files in node.js (both utf16be and utf16le)

Topics: cocos-creator