diff options
Diffstat (limited to 'bin/bdftofnt.js')
-rw-r--r-- | bin/bdftofnt.js | 109 |
1 files changed, 51 insertions, 58 deletions
diff --git a/bin/bdftofnt.js b/bin/bdftofnt.js index fd5a7ebcab1a..ec1047449e5a 100644 --- a/bin/bdftofnt.js +++ b/bin/bdftofnt.js @@ -1,28 +1,30 @@ -// -// Copyright (c) 2019 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com> -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +/* + Copyright (C) 2017-2020 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com> -'use strict'; + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. -const tty = require('tty'); + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +'use strict'; const fnutil = require('./fnutil.js'); const fncli = require('./fncli.js'); const fnio = require('./fnio.js'); const bdf = require('./bdf.js'); -const bmpf = require('./bmpf.js'); - +const bdfexp = require('./bdfexp.js'); +// -- Params -- class Params extends fncli.Params { constructor() { super(); @@ -33,7 +35,7 @@ class Params extends fncli.Params { } } - +// -- Options -- const HELP = ('' + 'usage: bdftofnt [-c CHARSET] [-m MINCHAR] [-f FAMILY] [-o OUTPUT] [INPUT]\n' + 'Convert a BDF font to Windows FNT\n' + @@ -41,14 +43,14 @@ const HELP = ('' + ' -c CHARSET fnt character set (default = 0, see wingdi.h ..._CHARSET)\n' + ' -m MINCHAR fnt minimum character code (8-bit CP decimal, not unicode)\n' + ' -f FAMILY fnt family: DontCare, Roman, Swiss, Modern or Decorative\n' + - ' -o OUTPUT output file (default = stdout, must not be a terminal)\n' + + ' -o OUTPUT output file (default = stdout, may not be a terminal)\n' + ' --help display this help and exit\n' + ' --version display the program version and license, and exit\n' + ' --excstk display the exception stack on error\n' + '\n' + - 'The input must be a BDF 2.1 font encoded in the unicode range.\n'); + 'The input must be a BDF 2.1 font with unicode encoding.\n'); -const VERSION = 'bdftofnt 1.55, Copyright (C) 2019 Dimitar Toshkov Zhekov\n\n' + fnutil.GPL2PLUS_LICENSE; +const VERSION = 'bdftofnt 1.60, Copyright (C) 2017-2020 Dimitar Toshkov Zhekov\n\n' + fnutil.GPL2PLUS_LICENSE; const FNT_FAMILIES = [ 'DontCare', 'Roman', 'Swiss', 'Modern', 'Decorative' ]; @@ -60,16 +62,16 @@ class Options extends fncli.Options { parse(name, value, params) { switch (name) { case '-c': - params.charSet = fnutil.parseDec('charset', value, 0, 255); + params.charSet = fnutil.parseDec('CHARSET', value, 0, 255); break; case '-m': - params.minChar = fnutil.parseDec('minchar', value, 0, 255); + params.minChar = fnutil.parseDec('MINCHAR', value, 0, 255); break; case '-f': params.fntFamily = FNT_FAMILIES.indexOf(value); if (params.fntFamily === -1) { - throw new Error('invalid fnt family'); + throw new Error('invalid FAMILY'); } break; case '-o': @@ -81,10 +83,11 @@ class Options extends fncli.Options { } } +// -- Main -- +const FNT_HEADER_SIZE = 118; +const FNT_CHARSETS = [238, 204, 0, 161, 162, 177, 178, 186, 163]; function mainProgram(nonopt, parsed) { - const WIN_FONTHEADERSIZE = 118; - if (nonopt.length > 1) { throw new Error('invalid number of arguments, try --help'); } @@ -93,10 +96,10 @@ function mainProgram(nonopt, parsed) { let minChar = parsed.minChar; // READ INPUT - let ifs = new fnio.InputStream(nonopt[0]); + let ifs = new fnio.InputFileStream(nonopt[0]); try { - var font = bmpf.Font.read(ifs); + var font = bdfexp.Font.read(ifs); ifs.close(); } catch (e) { e.message = ifs.location() + e.message; @@ -108,8 +111,6 @@ function mainProgram(nonopt, parsed) { const encoding = font.xlfd[bdf.XLFD.CHARSET_ENCODING]; if (encoding.toLowerCase().match(/^(cp)?125[0-8]$/)) { - const FNT_CHARSETS = [238, 204, 0, 161, 162, 177, 178, 186, 163]; - charSet = FNT_CHARSETS[parseInt(encoding.substring(encoding.length - 1), 10)]; } else { charSet = 255; @@ -137,16 +138,16 @@ function mainProgram(nonopt, parsed) { } // HEADER - var vtell = WIN_FONTHEADERSIZE + (numChars + 1) * 4; + var vtell = FNT_HEADER_SIZE + (numChars + 1) * 4; var bitsOffset = vtell; var ctable = []; var widthBytes = 0; // CTABLE/GLYPHS font.chars.forEach(char => { - const rowSize = char.rowSize(); + const rowSize = char.bbx.rowSize(); - ctable.push(char.width); + ctable.push(char.bbx.width); ctable.push(vtell); vtell += rowSize * font.bbx.height; widthBytes += rowSize; @@ -173,37 +174,32 @@ function mainProgram(nonopt, parsed) { } // WRITE - let ofs = new fnio.OutputStream(parsed.output); - - if (tty.isatty(ofs.fd)) { - throw new Error('binary output may not be send to a terminal, use -o or redirect/pipe it'); - } + let ofs = new fnio.OutputFileStream(parsed.output, null); try { // HEADER const family = font.xlfd[bdf.XLFD.FAMILY_NAME]; - const proportional = font.getProportional(); let copyright = font.props.get('COPYRIGHT'); copyright = (copyright != null) ? fnutil.unquote(copyright).substring(0, 60) : ''; - ofs.write16(0x0200); // font version - ofs.write32(vtell + family.length + 1); // total size + ofs.write16(0x0200); // font version + ofs.write32(vtell + family.length + 1); // total size ofs.writeZStr(copyright, 60 - copyright.length); - ofs.write16(0); // gdi, device type + ofs.write16(0); // gdi, device type ofs.write16(fnutil.round(font.bbx.height * 72 / 96)); - ofs.write16(96); // vertical resolution - ofs.write16(96); // horizontal resolution - ofs.write16(font.getAscent()); // base line - ofs.write16(0); // internal leading - ofs.write16(0); // external leading - ofs.write8(font.getItalic()); - ofs.write8(0); // underline - ofs.write8(0); // strikeout - ofs.write16(400 + 300 * font.getBold()); + ofs.write16(96); // vertical resolution + ofs.write16(96); // horizontal resolution + ofs.write16(font.pxAscender); // base line + ofs.write16(0); // internal leading + ofs.write16(0); // external leading + ofs.write8(Number(font.italic)); + ofs.write8(0); // underline + ofs.write8(0); // strikeout + ofs.write16(font.bold ? 700 : 400); ofs.write8(charSet); - ofs.write16(proportional ? 0 : font.avgWidth); + ofs.write16(font.proportional ? 0 : font.bbx.width); ofs.write16(font.bbx.height); - ofs.write8((parsed.fntFamily << 4) + proportional); + ofs.write8((parsed.fntFamily << 4) + Number(font.proportional)); ofs.write16(font.avgWidth); ofs.write16(font.bbx.width); ofs.write8(minChar); @@ -215,11 +211,9 @@ function mainProgram(nonopt, parsed) { if (font.defaultCode !== -1) { defaultIndex = font.chars.findIndex(char => char.code === font.defaultCode); } - if (minChar <= 0x20 && maxChar >= 0x20) { breakIndex = 0x20 - minChar; } - ofs.write8(defaultIndex); ofs.write8(breakIndex); ofs.write16(widthBytes); @@ -233,10 +227,10 @@ function mainProgram(nonopt, parsed) { ctable.forEach(value => ofs.write16(value)); // GLYPHS - let data = Buffer.alloc(font.bbx.height * font.bbx.rowSize()); + const data = Buffer.alloc(font.bbx.height * font.bbx.rowSize()); font.chars.forEach(char => { - const rowSize = char.rowSize(); + const rowSize = char.bbx.rowSize(); let counter = 0; // MS coordinates for (let n = 0; n < rowSize; n++) { @@ -257,7 +251,6 @@ function mainProgram(nonopt, parsed) { } } - if (require.main === module) { fncli.start('bdftofnt.js', new Options(), new Params(), mainProgram); } |