Added CMake presets, errors to stderr

This commit is contained in:
Chlumsky 2023-09-09 20:35:06 +02:00
parent b1af88cfca
commit 3cf874b39a
8 changed files with 352 additions and 41 deletions

1
.gitignore vendored
View File

@ -21,5 +21,6 @@
/bin/*.lib
/bin/msdf-atlas-gen
output.png
CMakeUserPresets.json
out/
/cmake-gen.bat

155
CMakePresets.json Normal file
View File

@ -0,0 +1,155 @@
{
"version": 4,
"cmakeMinimumRequired": {
"major": 3,
"minor": 23,
"patch": 0
},
"include": [
"cmake/CMakePresets.json"
],
"configurePresets": [
{
"name": "win64",
"displayName": "Windows x64 default config (static, vcpkg, Skia)",
"inherits": [ "win64-base", "vcpkg", "skia" ]
}, {
"name": "win32",
"displayName": "Windows x86 default config (static, vcpkg, Skia)",
"inherits": [ "win32-base", "vcpkg", "skia" ]
}, {
"name": "win64-dynamic",
"displayName": "Windows x64 dynamic config (vcpkg, Skia)",
"inherits": [ "win64-base", "vcpkg", "skia", "dynamic-runtime", "dynamic-lib" ],
"binaryDir": "${sourceDir}/build/win64-dynamic"
}, {
"name": "win32-dynamic",
"displayName": "Windows x86 dynamic config (vcpkg, Skia)",
"inherits": [ "win32-base", "vcpkg", "skia", "dynamic-runtime", "dynamic-lib" ],
"binaryDir": "${sourceDir}/build/win32-dynamic"
}, {
"name": "win64-no-skia",
"displayName": "Windows x64 config without Skia (static, vcpkg)",
"inherits": [ "win64-base", "vcpkg", "no-skia" ]
}, {
"name": "win32-no-skia",
"displayName": "Windows x86 config without Skia (static, vcpkg)",
"inherits": [ "win32-base", "vcpkg", "no-skia" ]
},
{
"name": "osx-vcpkg-rel",
"displayName": "Mac OS release config with vcpkg and Skia (static)",
"inherits": [ "osx-rel-base", "vcpkg", "skia" ]
}, {
"name": "osx-vcpkg-dbg",
"displayName": "Mac OS debug config with vcpkg and Skia (static)",
"inherits": [ "osx-dbg-base", "vcpkg", "skia" ]
}, {
"name": "osx-no-skia-rel",
"displayName": "Mac OS release config with system libraries and no Skia (static, install)",
"inherits": [ "osx-rel-base", "no-vcpkg", "no-skia", "install" ]
}, {
"name": "osx-no-skia-dbg",
"displayName": "Mac OS debug config with system libraries and no Skia (static, install)",
"inherits": [ "osx-dbg-base", "no-vcpkg", "no-skia", "install" ]
},
{
"name": "linux-vcpkg-rel",
"displayName": "Linux release config with vcpkg and Skia (static)",
"inherits": [ "linux-rel-base", "vcpkg", "skia" ]
}, {
"name": "linux-vcpkg-dbg",
"displayName": "Linux debug config with vcpkg and Skia (static)",
"inherits": [ "linux-dbg-base", "vcpkg", "skia" ]
}, {
"name": "linux-no-skia-rel",
"displayName": "Linux release config with system libraries and no Skia (static, install)",
"inherits": [ "linux-rel-base", "no-vcpkg", "no-skia", "install" ]
}, {
"name": "linux-no-skia-dbg",
"displayName": "Linux debug config with system libraries and no Skia (static, install)",
"inherits": [ "linux-dbg-base", "no-vcpkg", "no-skia", "install" ]
}
],
"buildPresets": [
{
"name": "win64-rel",
"configurePreset": "win64",
"configuration": "Release"
}, {
"name": "win64-dbg",
"configurePreset": "win64",
"configuration": "Debug"
}, {
"name": "win32-rel",
"configurePreset": "win32",
"configuration": "Release"
}, {
"name": "win32-dbg",
"configurePreset": "win32",
"configuration": "Debug"
}, {
"name": "win64-dynamic-rel",
"configurePreset": "win64-dynamic",
"configuration": "Release"
}, {
"name": "win64-dynamic-dbg",
"configurePreset": "win64-dynamic",
"configuration": "Debug"
}, {
"name": "win32-dynamic-rel",
"configurePreset": "win32-dynamic",
"configuration": "Release"
}, {
"name": "win32-dynamic-dbg",
"configurePreset": "win32-dynamic",
"configuration": "Debug"
}, {
"name": "win64-no-skia-rel",
"configurePreset": "win64-no-skia",
"configuration": "Release"
}, {
"name": "win64-no-skia-dbg",
"configurePreset": "win64-no-skia",
"configuration": "Debug"
}, {
"name": "win32-no-skia-rel",
"configurePreset": "win32-no-skia",
"configuration": "Release"
}, {
"name": "win32-no-skia-dbg",
"configurePreset": "win32-no-skia",
"configuration": "Debug"
},
{
"name": "osx-vcpkg-rel",
"configurePreset": "osx-vcpkg-rel"
}, {
"name": "osx-vcpkg-dbg",
"configurePreset": "osx-vcpkg-dbg"
}, {
"name": "osx-no-skia-rel",
"configurePreset": "osx-no-skia-rel"
}, {
"name": "osx-no-skia-dbg",
"configurePreset": "osx-no-skia-dbg"
},
{
"name": "linux-vcpkg-rel",
"configurePreset": "linux-vcpkg-rel"
}, {
"name": "linux-vcpkg-dbg",
"configurePreset": "linux-vcpkg-dbg"
}, {
"name": "linux-no-skia-rel",
"configurePreset": "linux-no-skia-rel"
}, {
"name": "linux-no-skia-dbg",
"configurePreset": "linux-no-skia-dbg"
}
]
}

154
cmake/CMakePresets.json Normal file
View File

@ -0,0 +1,154 @@
{
"version": 4,
"cmakeMinimumRequired": {
"major": 3,
"minor": 23,
"patch": 0
},
"configurePresets": [
{
"name": "release-only",
"displayName": "Release only configuration",
"hidden": true,
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
}, {
"name": "debug-only",
"displayName": "Debug only configuration",
"hidden": true,
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
}, {
"name": "win64-base",
"displayName": "Windows 64-bit base configuration",
"hidden": true,
"architecture": "x64",
"binaryDir": "${sourceDir}/build/win64",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
}, {
"name": "win32-base",
"displayName": "Windows 32-bit base configuration",
"hidden": true,
"architecture": "Win32",
"binaryDir": "${sourceDir}/build/win32",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
}, {
"name": "osx-base",
"displayName": "Mac OS base configuration",
"hidden": true,
"binaryDir": "${sourceDir}/build/osx",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
}
}, {
"name": "osx-rel-base",
"displayName": "Mac OS base release configuration",
"inherits": [ "osx-base", "release-only" ],
"hidden": true,
"binaryDir": "${sourceDir}/build/osx-rel"
}, {
"name": "osx-dbg-base",
"displayName": "Mac OS base debug configuration",
"inherits": [ "osx-base", "debug-only" ],
"hidden": true,
"binaryDir": "${sourceDir}/build/osx-dbg"
}, {
"name": "linux-base",
"displayName": "Linux base configuration",
"hidden": true,
"binaryDir": "${sourceDir}/build/linux",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
}
}, {
"name": "linux-rel-base",
"displayName": "Linux base release configuration",
"inherits": [ "linux-base", "release-only" ],
"hidden": true,
"binaryDir": "${sourceDir}/build/linux-rel"
}, {
"name": "linux-dbg-base",
"displayName": "Linux base debug configuration",
"inherits": [ "linux-base", "debug-only" ],
"hidden": true,
"binaryDir": "${sourceDir}/build/linux-dbg"
}, {
"name": "vcpkg",
"displayName": "Configuration with vcpkg as dependency management system",
"hidden": true,
"cacheVariables": {
"MSDF_ATLAS_USE_VCPKG": "ON"
}
}, {
"name": "no-vcpkg",
"displayName": "Configuration with dependencies not managed by vcpkg",
"hidden": true,
"cacheVariables": {
"MSDF_ATLAS_USE_VCPKG": "OFF"
}
}, {
"name": "skia",
"displayName": "Configuration with Skia geometry preprocessing",
"hidden": true,
"cacheVariables": {
"MSDF_ATLAS_USE_SKIA": "ON"
}
}, {
"name": "no-skia",
"displayName": "Configuration without Skia geometry preprocessing",
"hidden": true,
"cacheVariables": {
"MSDF_ATLAS_USE_SKIA": "OFF"
}
}, {
"name": "install",
"displayName": "Configuration with installation targets",
"hidden": true,
"cacheVariables": {
"MSDF_ATLAS_INSTALL": "ON"
}
}, {
"name": "static-runtime",
"displayName": "Configuration that links against the static runtime",
"hidden": true,
"cacheVariables": {
"MSDF_ATLAS_DYNAMIC_RUNTIME": "OFF"
}
}, {
"name": "dynamic-runtime",
"displayName": "Configuration that links against the dynamic runtime",
"hidden": true,
"cacheVariables": {
"MSDF_ATLAS_DYNAMIC_RUNTIME": "ON"
}
}, {
"name": "static-lib",
"displayName": "Configuration that builds and links msdfgen statically",
"hidden": true,
"cacheVariables": {
"BUILD_SHARED_LIBS": "OFF"
}
}, {
"name": "dynamic-lib",
"displayName": "Configuration that builds and links msdfgen dynamically",
"hidden": true,
"cacheVariables": {
"BUILD_SHARED_LIBS": "ON"
}
}
]
}

View File

@ -220,6 +220,7 @@ bool Charset::load(const char *filename, bool disableCharLiterals) {
else
goto FAIL;
} // else treat as whitespace
// fallthrough
case ' ': case '\n': case '\r': case '\t': // whitespace
if (state == TIGHT)
state = CLEAR;

View File

@ -69,17 +69,17 @@ template <int N>
bool saveImageBinary(const msdfgen::BitmapConstRef<byte, N> &bitmap, const char *filename, YDirection outputYDirection) {
bool success = false;
if (FILE *f = fopen(filename, "wb")) {
int written = 0;
size_t written = 0;
switch (outputYDirection) {
case YDirection::BOTTOM_UP:
written = fwrite(bitmap.pixels, 1, N*bitmap.width*bitmap.height, f);
written = fwrite(bitmap.pixels, 1, (size_t) N*bitmap.width*bitmap.height, f);
break;
case YDirection::TOP_DOWN:
for (int y = bitmap.height-1; y >= 0; --y)
written += fwrite(bitmap.pixels+N*bitmap.width*y, 1, N*bitmap.width, f);
written += fwrite(bitmap.pixels+(size_t) N*bitmap.width*y, 1, (size_t) N*bitmap.width, f);
break;
}
success = written == N*bitmap.width*bitmap.height;
success = written == (size_t) N*bitmap.width*bitmap.height;
fclose(f);
}
return success;
@ -95,17 +95,17 @@ bool
(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename, YDirection outputYDirection) {
bool success = false;
if (FILE *f = fopen(filename, "wb")) {
int written = 0;
size_t written = 0;
switch (outputYDirection) {
case YDirection::BOTTOM_UP:
written = fwrite(bitmap.pixels, sizeof(float), N*bitmap.width*bitmap.height, f);
written = fwrite(bitmap.pixels, sizeof(float), (size_t) N*bitmap.width*bitmap.height, f);
break;
case YDirection::TOP_DOWN:
for (int y = bitmap.height-1; y >= 0; --y)
written += fwrite(bitmap.pixels+N*bitmap.width*y, sizeof(float), N*bitmap.width, f);
written += fwrite(bitmap.pixels+(size_t) N*bitmap.width*y, sizeof(float), (size_t) N*bitmap.width, f);
break;
}
success = written == N*bitmap.width*bitmap.height;
success = written == (size_t) N*bitmap.width*bitmap.height;
fclose(f);
}
return success;
@ -121,9 +121,9 @@ bool
(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename, YDirection outputYDirection) {
bool success = false;
if (FILE *f = fopen(filename, "wb")) {
int written = 0;
size_t written = 0;
for (int y = 0; y < bitmap.height; ++y) {
const float *p = bitmap.pixels+N*bitmap.width*(outputYDirection == YDirection::TOP_DOWN ? bitmap.height-y-1 : y);
const float *p = bitmap.pixels+(size_t) N*bitmap.width*(outputYDirection == YDirection::TOP_DOWN ? bitmap.height-y-1 : y);
for (int x = 0; x < bitmap.width; ++x) {
const unsigned char *b = reinterpret_cast<const unsigned char *>(p++);
for (int i = sizeof(float)-1; i >= 0; --i)
@ -143,7 +143,7 @@ bool saveImageText(const msdfgen::BitmapConstRef<byte, N> &bitmap, const char *f
if (FILE *f = fopen(filename, "wb")) {
success = true;
for (int y = 0; y < bitmap.height; ++y) {
const byte *p = bitmap.pixels+N*bitmap.width*(outputYDirection == YDirection::TOP_DOWN ? bitmap.height-y-1 : y);
const byte *p = bitmap.pixels+(size_t) N*bitmap.width*(outputYDirection == YDirection::TOP_DOWN ? bitmap.height-y-1 : y);
for (int x = 0; x < N*bitmap.width; ++x)
success &= fprintf(f, x ? " %02X" : "%02X", (unsigned) *p++) > 0;
success &= fprintf(f, "\n") > 0;
@ -159,7 +159,7 @@ bool saveImageText(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *
if (FILE *f = fopen(filename, "wb")) {
success = true;
for (int y = 0; y < bitmap.height; ++y) {
const float *p = bitmap.pixels+N*bitmap.width*(outputYDirection == YDirection::TOP_DOWN ? bitmap.height-y-1 : y);
const float *p = bitmap.pixels+(size_t) N*bitmap.width*(outputYDirection == YDirection::TOP_DOWN ? bitmap.height-y-1 : y);
for (int x = 0; x < N*bitmap.width; ++x)
success &= fprintf(f, x ? " %g" : "%g", *p++) > 0;
success &= fprintf(f, "\n") > 0;

View File

@ -275,10 +275,10 @@ static bool makeAtlas(const std::vector<GlyphGeometry> &glyphs, const std::vecto
if (config.imageFilename) {
if (saveImage(bitmap, config.imageFormat, config.imageFilename, config.yDirection))
puts("Atlas image file saved.");
fputs("Atlas image file saved.\n", stderr);
else {
success = false;
puts("Failed to save the atlas as an image file.");
fputs("Failed to save the atlas as an image file.\n", stderr);
}
}
@ -291,10 +291,10 @@ static bool makeAtlas(const std::vector<GlyphGeometry> &glyphs, const std::vecto
arfontProps.imageFormat = config.imageFormat;
arfontProps.yDirection = config.yDirection;
if (exportArteryFont<float>(fonts.data(), fonts.size(), bitmap, config.arteryFontFilename, arfontProps))
puts("Artery Font file generated.");
fputs("Artery Font file generated.\n", stderr);
else {
success = false;
puts("Failed to generate Artery Font file.");
fputs("Failed to generate Artery Font file.\n", stderr);
}
}
#endif
@ -303,7 +303,7 @@ static bool makeAtlas(const std::vector<GlyphGeometry> &glyphs, const std::vecto
}
int main(int argc, const char * const *argv) {
#define ABORT(msg) { puts(msg); return 1; }
#define ABORT(msg) do { fputs(msg "\n", stderr); return 1; } while (false)
int result = 0;
std::vector<FontInput> fontInputs;
@ -617,7 +617,7 @@ int main(int argc, const char * const *argv) {
else if (!strcmp(argv[argPos+1], "inktrap")) config.edgeColoring = msdfgen::edgeColoringInkTrap, config.expensiveColoring = false;
else if (!strcmp(argv[argPos+1], "distance")) config.edgeColoring = msdfgen::edgeColoringByDistance, config.expensiveColoring = true;
else
puts("Unknown coloring strategy specified.");
fputs("Unknown coloring strategy specified.\n", stderr);
argPos += 2;
continue;
}
@ -691,29 +691,29 @@ int main(int argc, const char * const *argv) {
puts(helpText);
return 0;
}
printf("Unknown setting or insufficient parameters: %s\n", argv[argPos]);
fprintf(stderr, "Unknown setting or insufficient parameters: %s\n", argv[argPos]);
suggestHelp = true;
++argPos;
}
if (suggestHelp)
printf("Use -help for more information.\n");
fputs("Use -help for more information.\n", stderr);
// Nothing to do?
if (argc == 1) {
printf(
fputs(
"Usage: msdf-atlas-gen"
#ifdef _WIN32
".exe"
#endif
" -font <filename.ttf/otf> -charset <charset> <output specification> <options>\n"
"Use -help for more information.\n"
"Use -help for more information.\n", stderr
);
return 0;
}
if (!fontInput.fontFilename)
ABORT("No font specified.");
if (!(config.arteryFontFilename || config.imageFilename || config.jsonFilename || config.csvFilename || config.shadronPreviewFilename)) {
puts("No output specified.");
fputs("No output specified.\n", stderr);
return 0;
}
bool layoutOnly = !(config.arteryFontFilename || config.imageFilename);
@ -740,7 +740,7 @@ int main(int argc, const char * const *argv) {
if (config.emSize > minEmSize)
minEmSize = config.emSize;
if (!(fixedWidth > 0 && fixedHeight > 0) && !(minEmSize > 0)) {
puts("Neither atlas size nor glyph size selected, using default...");
fputs("Neither atlas size nor glyph size selected, using default...\n", stderr);
minEmSize = MSDF_ATLAS_DEFAULT_EM_SIZE;
}
if (config.imageType == ImageType::HARD_MASK || config.imageType == ImageType::SOFT_MASK) {
@ -763,7 +763,7 @@ int main(int argc, const char * const *argv) {
case msdfgen::ErrorCorrectionConfig::EDGE_PRIORITY: fallbackModeName = "auto-fast"; break;
case msdfgen::ErrorCorrectionConfig::EDGE_ONLY: fallbackModeName = "edge-fast"; break;
}
printf("Selected error correction mode not compatible with scanline mode, falling back to %s.\n", fallbackModeName);
fprintf(stderr, "Selected error correction mode not compatible with scanline mode, falling back to %s.\n", fallbackModeName);
}
config.generatorAttributes.config.errorCorrection.distanceCheckMode = msdfgen::ErrorCorrectionConfig::DO_NOT_CHECK_DISTANCE;
}
@ -790,7 +790,7 @@ int main(int argc, const char * const *argv) {
if (config.arteryFontFilename && !(config.imageFormat == ImageFormat::PNG || config.imageFormat == ImageFormat::BINARY || config.imageFormat == ImageFormat::BINARY_FLOAT)) {
config.arteryFontFilename = nullptr;
result = 1;
puts("Error: Unable to create an Artery Font file with the specified image format!");
fputs("Error: Unable to create an Artery Font file with the specified image format!\n", stderr);
// Recheck whether there is anything else to do
if (!(config.arteryFontFilename || config.imageFilename || config.jsonFilename || config.csvFilename || config.shadronPreviewFilename))
return result;
@ -811,7 +811,7 @@ int main(int argc, const char * const *argv) {
mismatch = imageExtension != config.imageFormat;
}
if (mismatch)
printf("Warning: Output image file extension does not match the image's actual format (%s)!\n", imageFormatName);
fprintf(stderr, "Warning: Output image file extension does not match the image's actual format (%s)!\n", imageFormatName);
}
imageFormatName = nullptr; // No longer consistent with imageFormat
bool floatingPointFormat = (
@ -894,21 +894,21 @@ int main(int argc, const char * const *argv) {
printf(".\n");
// List missing glyphs
if (glyphsLoaded < (int) charset.size()) {
printf("Missing %d %s", (int) charset.size()-glyphsLoaded, fontInput.glyphIdentifierType == GlyphIdentifierType::UNICODE_CODEPOINT ? "codepoints" : "glyphs");
fprintf(stderr, "Missing %d %s", (int) charset.size()-glyphsLoaded, fontInput.glyphIdentifierType == GlyphIdentifierType::UNICODE_CODEPOINT ? "codepoints" : "glyphs");
bool first = true;
switch (fontInput.glyphIdentifierType) {
case GlyphIdentifierType::GLYPH_INDEX:
for (unicode_t cp : charset)
if (!fontGeometry.getGlyph(msdfgen::GlyphIndex(cp)))
printf("%c 0x%02X", first ? ((first = false), ':') : ',', cp);
fprintf(stderr, "%c 0x%02X", first ? ((first = false), ':') : ',', cp);
break;
case GlyphIdentifierType::UNICODE_CODEPOINT:
for (unicode_t cp : charset)
if (!fontGeometry.getGlyph(cp))
printf("%c 0x%02X", first ? ((first = false), ':') : ',', cp);
fprintf(stderr, "%c 0x%02X", first ? ((first = false), ':') : ',', cp);
break;
}
printf("\n");
fprintf(stderr, "\n");
}
if (fontInput.fontName)
@ -951,7 +951,7 @@ int main(int argc, const char * const *argv) {
if (remaining < 0) {
ABORT("Failed to pack glyphs into atlas.");
} else {
printf("Error: Could not fit %d out of %d glyphs into the atlas.\n", remaining, (int) glyphs.size());
fprintf(stderr, "Error: Could not fit %d out of %d glyphs into the atlas.\n", remaining, (int) glyphs.size());
return 1;
}
}
@ -1026,18 +1026,18 @@ int main(int argc, const char * const *argv) {
if (config.csvFilename) {
if (exportCSV(fonts.data(), fonts.size(), config.width, config.height, config.yDirection, config.csvFilename))
puts("Glyph layout written into CSV file.");
fputs("Glyph layout written into CSV file.\n", stderr);
else {
result = 1;
puts("Failed to write CSV output file.");
fputs("Failed to write CSV output file.\n", stderr);
}
}
if (config.jsonFilename) {
if (exportJSON(fonts.data(), fonts.size(), config.emSize, config.pxRange, config.width, config.height, config.imageType, config.yDirection, config.jsonFilename, config.kerning))
puts("Glyph layout and metadata written into JSON file.");
fputs("Glyph layout and metadata written into JSON file.\n", stderr);
else {
result = 1;
puts("Failed to write JSON output file.");
fputs("Failed to write JSON output file.\n", stderr);
}
}
@ -1047,14 +1047,14 @@ int main(int argc, const char * const *argv) {
utf8Decode(previewText, config.shadronPreviewText);
previewText.push_back(0);
if (generateShadronPreview(fonts.data(), fonts.size(), config.imageType, config.width, config.height, config.pxRange, previewText.data(), config.imageFilename, floatingPointFormat, config.shadronPreviewFilename))
puts("Shadron preview script generated.");
fputs("Shadron preview script generated.\n", stderr);
else {
result = 1;
puts("Failed to generate Shadron preview file.");
fputs("Failed to generate Shadron preview file.\n", stderr);
}
} else {
result = 1;
puts("Shadron preview not supported in -glyphset mode.");
fputs("Shadron preview not supported in -glyphset mode.\n", stderr);
}
}

@ -1 +1 @@
Subproject commit d576034d226a5ceb8e8e1e94a09d94e58949cba1
Subproject commit 16f2057bbcdc2f634e6fb6f573d2d176c9dd1a73

View File

@ -1,5 +1,5 @@
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json",
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/master/docs/vcpkg.schema.json",
"name": "msdf-atlas-gen",
"version": "1.3.0",
"description": "Multi-channel signed distance field atlas generator",