Files
2025-10-12 09:13:56 +02:00

180 lines
4.5 KiB
C++

/*
* MCU renderer fontconv
* Main module
*
* (C) 2023 Gissio
*
* License: MIT
*/
#include <fstream>
#include <iostream>
#include <set>
#include "encode.h"
#include "export.h"
#include "import_bdf.h"
#include "import_freetype.h"
#include "utils.h"
#define DEFAULT_POINT_SIZE 12
#define DEFAULT_BITS_PER_PIXEL 4
using namespace std;
void printHelp(void)
{
cout << "fontconv [options] input-file output-file\n"
<< "-h Display this help.\n"
<< "-p <size> Set point size for rasterizing fonts (default: " << DEFAULT_POINT_SIZE << ").\n"
<< "-b <size> Set bits per pixel (default: " << DEFAULT_BITS_PER_PIXEL << ").\n"
<< "-s <subset> Specify a subset of Unicode characters to convert.\n"
<< "-c <size> Override the font cap height.\n"
<< "-a <size> Override the font ascent (baseline to top of line).\n"
<< "-d <size> Override the font descent (bottom of line to baseline).\n"
<< "-n <name> Override the C-language font variable name.\n"
<< "\n"
<< "example:\n"
<< " -s 32-255 select Unicode characters 32 to 255.\n"
<< " -s 0x2e,0x30-0x39 select space and digit characters.\n";
exit(1);
}
int main(int argc, char **argv)
{
// Parse command line
vector<string> args(argv + 1, argv + argc);
string charcodes;
uint32_t pointSize = DEFAULT_POINT_SIZE;
uint32_t pixelBitNum = DEFAULT_BITS_PER_PIXEL;
int32_t overrideCapHeight = INT_MIN;
int32_t overrideAscent = INT_MIN;
int32_t overrideDescent = INT_MIN;
string variableName;
string inputFilename;
string outputFilename;
for (uint32_t i = 0; i < args.size(); i++)
{
if (args[i].compare("-h") == 0)
printHelp();
else if (args[i].compare("-p") == 0)
{
i++;
if (i < args.size())
{
int32_t value = stoi(args[i]);
if ((value >= 1) && (value <= 512))
pointSize = value;
}
}
else if (args[i].compare("-b") == 0)
{
i++;
if (i < args.size())
{
int32_t value = stoi(args[i]);
if ((value >= 1) &&
(value <= 8))
pixelBitNum = value;
}
}
else if (args[i].compare("-s") == 0)
{
i++;
if (i < args.size())
charcodes = args[i];
}
else if (args[i].compare("-c") == 0)
{
i++;
if (i < args.size())
overrideCapHeight = stoi(args[i]);
}
else if (args[i].compare("-a") == 0)
{
i++;
if (i < args.size())
overrideAscent = stoi(args[i]);
}
else if (args[i].compare("-d") == 0)
{
i++;
if (i < args.size())
overrideDescent = stoi(args[i]);
}
else if (args[i].compare("-n") == 0)
{
i++;
if (i < args.size())
variableName = args[i];
}
else if (inputFilename == "")
inputFilename = args[i];
else if (outputFilename == "")
outputFilename = args[i];
else
printHelp();
}
if ((inputFilename == "") || (outputFilename == ""))
printHelp();
// Process font
try
{
Font font;
set<Charcode> charcodeSet = parseCharcodes(charcodes);
if (to_lower(inputFilename).ends_with(".bdf"))
{
font = loadBDFFont(inputFilename,
charcodeSet);
pixelBitNum = 1;
}
else
font = loadFreeTypeFont(inputFilename,
charcodeSet,
pointSize);
if (overrideCapHeight != INT_MIN)
font.capHeight = overrideCapHeight;
if (overrideAscent != INT_MIN)
font.ascent = overrideAscent;
if (overrideDescent != INT_MIN)
font.descent = overrideDescent;
BitWriter encodedFont;
encodeFont(font,
pixelBitNum,
encodedFont);
exportFont(font,
variableName,
charcodes,
encodedFont.data,
outputFilename);
}
catch (runtime_error &e)
{
cerr << "error: " << e.what() << endl;
}
return 0;
}