Added -yorigin setting
This commit is contained in:
parent
84e8c25241
commit
67510959f1
|
|
@ -154,10 +154,23 @@ bool exportArteryFont(const FontGeometry *fonts, int fontCount, const msdfgen::B
|
||||||
return false;
|
return false;
|
||||||
image.encoding = artery_font::IMAGE_RAW_BINARY;
|
image.encoding = artery_font::IMAGE_RAW_BINARY;
|
||||||
image.rawBinaryFormat.rowLength = N*sizeof(T)*atlas.width;
|
image.rawBinaryFormat.rowLength = N*sizeof(T)*atlas.width;
|
||||||
image.rawBinaryFormat.orientation = artery_font::ORIENTATION_BOTTOM_UP;
|
|
||||||
image.data = artery_font::StdByteArray(N*sizeof(T)*atlas.width*atlas.height);
|
image.data = artery_font::StdByteArray(N*sizeof(T)*atlas.width*atlas.height);
|
||||||
|
switch (properties.yDirection) {
|
||||||
|
case YDirection::BOTTOM_UP:
|
||||||
|
image.rawBinaryFormat.orientation = artery_font::ORIENTATION_BOTTOM_UP;
|
||||||
memcpy((byte *) image.data, atlas.pixels, N*sizeof(T)*atlas.width*atlas.height);
|
memcpy((byte *) image.data, atlas.pixels, N*sizeof(T)*atlas.width*atlas.height);
|
||||||
break;
|
break;
|
||||||
|
case YDirection::TOP_DOWN: {
|
||||||
|
image.rawBinaryFormat.orientation = artery_font::ORIENTATION_TOP_DOWN;
|
||||||
|
byte *imageData = (byte *) image.data;
|
||||||
|
for (int y = atlas.height-1; y >= 0; --y) {
|
||||||
|
memcpy(imageData, atlas.pixels+N*atlas.width*y, N*sizeof(T)*atlas.width);
|
||||||
|
imageData += N*sizeof(T)*atlas.width;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ struct ArteryFontExportProperties {
|
||||||
double pxRange;
|
double pxRange;
|
||||||
ImageType imageType;
|
ImageType imageType;
|
||||||
ImageFormat imageFormat;
|
ImageFormat imageFormat;
|
||||||
|
YDirection yDirection;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Encodes the atlas bitmap and its layout into an Artery Atlas Font file
|
/// Encodes the atlas bitmap and its layout into an Artery Atlas Font file
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
namespace msdf_atlas {
|
namespace msdf_atlas {
|
||||||
|
|
||||||
bool exportCSV(const FontGeometry *fonts, int fontCount, const char *filename) {
|
bool exportCSV(const FontGeometry *fonts, int fontCount, int atlasWidth, int atlasHeight, YDirection yDirection, const char *filename) {
|
||||||
FILE *f = fopen(filename, "w");
|
FILE *f = fopen(filename, "w");
|
||||||
if (!f)
|
if (!f)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -18,9 +18,23 @@ bool exportCSV(const FontGeometry *fonts, int fontCount, const char *filename) {
|
||||||
fprintf(f, "%d,", i);
|
fprintf(f, "%d,", i);
|
||||||
fprintf(f, "%d,%.17g,", glyph.getIdentifier(fonts[i].getPreferredIdentifierType()), glyph.getAdvance());
|
fprintf(f, "%d,%.17g,", glyph.getIdentifier(fonts[i].getPreferredIdentifierType()), glyph.getAdvance());
|
||||||
glyph.getQuadPlaneBounds(l, b, r, t);
|
glyph.getQuadPlaneBounds(l, b, r, t);
|
||||||
|
switch (yDirection) {
|
||||||
|
case YDirection::BOTTOM_UP:
|
||||||
fprintf(f, "%.17g,%.17g,%.17g,%.17g,", l, b, r, t);
|
fprintf(f, "%.17g,%.17g,%.17g,%.17g,", l, b, r, t);
|
||||||
|
break;
|
||||||
|
case YDirection::TOP_DOWN:
|
||||||
|
fprintf(f, "%.17g,%.17g,%.17g,%.17g,", l, -t, r, -b);
|
||||||
|
break;
|
||||||
|
}
|
||||||
glyph.getQuadAtlasBounds(l, b, r, t);
|
glyph.getQuadAtlasBounds(l, b, r, t);
|
||||||
|
switch (yDirection) {
|
||||||
|
case YDirection::BOTTOM_UP:
|
||||||
fprintf(f, "%.17g,%.17g,%.17g,%.17g\n", l, b, r, t);
|
fprintf(f, "%.17g,%.17g,%.17g,%.17g\n", l, b, r, t);
|
||||||
|
break;
|
||||||
|
case YDirection::TOP_DOWN:
|
||||||
|
fprintf(f, "%.17g,%.17g,%.17g,%.17g\n", l, atlasHeight-t, r, atlasHeight-b);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,6 @@ namespace msdf_atlas {
|
||||||
* Writes the positioning data and atlas layout of the glyphs into a CSV file
|
* Writes the positioning data and atlas layout of the glyphs into a CSV file
|
||||||
* The columns are: font variant index (if fontCount > 1), glyph identifier (index or Unicode), horizontal advance, plane bounds (l, b, r, t), atlas bounds (l, b, r, t)
|
* The columns are: font variant index (if fontCount > 1), glyph identifier (index or Unicode), horizontal advance, plane bounds (l, b, r, t), atlas bounds (l, b, r, t)
|
||||||
*/
|
*/
|
||||||
bool exportCSV(const FontGeometry *fonts, int fontCount, const char *filename);
|
bool exportCSV(const FontGeometry *fonts, int fontCount, int atlasWidth, int atlasHeight, YDirection yDirection, const char *filename);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ namespace msdf_atlas {
|
||||||
|
|
||||||
/// Saves the bitmap as an image file with the specified format
|
/// Saves the bitmap as an image file with the specified format
|
||||||
template <typename T, int N>
|
template <typename T, int N>
|
||||||
bool saveImage(const msdfgen::BitmapConstRef<T, N> &bitmap, ImageFormat format, const char *filename);
|
bool saveImage(const msdfgen::BitmapConstRef<T, N> &bitmap, ImageFormat format, const char *filename, YDirection outputYDirection = YDirection::BOTTOM_UP);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,19 @@
|
||||||
namespace msdf_atlas {
|
namespace msdf_atlas {
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
bool saveImageBinary(const msdfgen::BitmapConstRef<byte, N> &bitmap, const char *filename);
|
bool saveImageBinary(const msdfgen::BitmapConstRef<byte, N> &bitmap, const char *filename, YDirection outputYDirection);
|
||||||
template <int N>
|
template <int N>
|
||||||
bool saveImageBinaryLE(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename);
|
bool saveImageBinaryLE(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename, YDirection outputYDirection);
|
||||||
template <int N>
|
template <int N>
|
||||||
bool saveImageBinaryBE(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename);
|
bool saveImageBinaryBE(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename, YDirection outputYDirection);
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
bool saveImageText(const msdfgen::BitmapConstRef<byte, N> &bitmap, const char *filename);
|
bool saveImageText(const msdfgen::BitmapConstRef<byte, N> &bitmap, const char *filename, YDirection outputYDirection);
|
||||||
template <int N>
|
template <int N>
|
||||||
bool saveImageText(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename);
|
bool saveImageText(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename, YDirection outputYDirection);
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
bool saveImage(const msdfgen::BitmapConstRef<byte, N> &bitmap, ImageFormat format, const char *filename) {
|
bool saveImage(const msdfgen::BitmapConstRef<byte, N> &bitmap, ImageFormat format, const char *filename, YDirection outputYDirection) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case ImageFormat::PNG:
|
case ImageFormat::PNG:
|
||||||
return msdfgen::savePng(bitmap, filename);
|
return msdfgen::savePng(bitmap, filename);
|
||||||
|
|
@ -28,11 +28,11 @@ bool saveImage(const msdfgen::BitmapConstRef<byte, N> &bitmap, ImageFormat forma
|
||||||
case ImageFormat::TIFF:
|
case ImageFormat::TIFF:
|
||||||
return false;
|
return false;
|
||||||
case ImageFormat::TEXT:
|
case ImageFormat::TEXT:
|
||||||
return saveImageText(bitmap, filename);
|
return saveImageText(bitmap, filename, outputYDirection);
|
||||||
case ImageFormat::TEXT_FLOAT:
|
case ImageFormat::TEXT_FLOAT:
|
||||||
return false;
|
return false;
|
||||||
case ImageFormat::BINARY:
|
case ImageFormat::BINARY:
|
||||||
return saveImageBinary(bitmap, filename);
|
return saveImageBinary(bitmap, filename, outputYDirection);
|
||||||
case ImageFormat::BINARY_FLOAT:
|
case ImageFormat::BINARY_FLOAT:
|
||||||
case ImageFormat::BINARY_FLOAT_BE:
|
case ImageFormat::BINARY_FLOAT_BE:
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -42,7 +42,7 @@ bool saveImage(const msdfgen::BitmapConstRef<byte, N> &bitmap, ImageFormat forma
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
bool saveImage(const msdfgen::BitmapConstRef<float, N> &bitmap, ImageFormat format, const char *filename) {
|
bool saveImage(const msdfgen::BitmapConstRef<float, N> &bitmap, ImageFormat format, const char *filename, YDirection outputYDirection) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case ImageFormat::PNG:
|
case ImageFormat::PNG:
|
||||||
return msdfgen::savePng(bitmap, filename);
|
return msdfgen::savePng(bitmap, filename);
|
||||||
|
|
@ -53,63 +53,84 @@ bool saveImage(const msdfgen::BitmapConstRef<float, N> &bitmap, ImageFormat form
|
||||||
case ImageFormat::TEXT:
|
case ImageFormat::TEXT:
|
||||||
return false;
|
return false;
|
||||||
case ImageFormat::TEXT_FLOAT:
|
case ImageFormat::TEXT_FLOAT:
|
||||||
return saveImageText(bitmap, filename);
|
return saveImageText(bitmap, filename, outputYDirection);
|
||||||
case ImageFormat::BINARY:
|
case ImageFormat::BINARY:
|
||||||
return false;
|
return false;
|
||||||
case ImageFormat::BINARY_FLOAT:
|
case ImageFormat::BINARY_FLOAT:
|
||||||
return saveImageBinaryLE(bitmap, filename);
|
return saveImageBinaryLE(bitmap, filename, outputYDirection);
|
||||||
case ImageFormat::BINARY_FLOAT_BE:
|
case ImageFormat::BINARY_FLOAT_BE:
|
||||||
return saveImageBinaryBE(bitmap, filename);
|
return saveImageBinaryBE(bitmap, filename, outputYDirection);
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
bool saveImageBinary(const msdfgen::BitmapConstRef<byte, N> &bitmap, const char *filename) {
|
bool saveImageBinary(const msdfgen::BitmapConstRef<byte, N> &bitmap, const char *filename, YDirection outputYDirection) {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (FILE *f = fopen(filename, "wb")) {
|
if (FILE *f = fopen(filename, "wb")) {
|
||||||
success = fwrite(bitmap.pixels, 1, N*bitmap.width*bitmap.height, f) == N*bitmap.width*bitmap.height;
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int N>
|
|
||||||
bool
|
|
||||||
#ifdef __BIG_ENDIAN__
|
|
||||||
saveImageBinaryBE
|
|
||||||
#else
|
|
||||||
saveImageBinaryLE
|
|
||||||
#endif
|
|
||||||
(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename) {
|
|
||||||
bool success = false;
|
|
||||||
if (FILE *f = fopen(filename, "wb")) {
|
|
||||||
success = fwrite(bitmap.pixels, sizeof(float), N*bitmap.width*bitmap.height, f) == N*bitmap.width*bitmap.height;
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int N>
|
|
||||||
bool
|
|
||||||
#ifdef __BIG_ENDIAN__
|
|
||||||
saveImageBinaryLE
|
|
||||||
#else
|
|
||||||
saveImageBinaryBE
|
|
||||||
#endif
|
|
||||||
(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename) {
|
|
||||||
bool success = false;
|
|
||||||
if (FILE *f = fopen(filename, "wb")) {
|
|
||||||
const float *p = bitmap.pixels;
|
|
||||||
int count = N*bitmap.width*bitmap.height;
|
|
||||||
int written = 0;
|
int written = 0;
|
||||||
for (int i = 0; i < count; ++i) {
|
switch (outputYDirection) {
|
||||||
|
case YDirection::BOTTOM_UP:
|
||||||
|
written = fwrite(bitmap.pixels, 1, 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);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
success = written == N*bitmap.width*bitmap.height;
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
bool
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
saveImageBinaryBE
|
||||||
|
#else
|
||||||
|
saveImageBinaryLE
|
||||||
|
#endif
|
||||||
|
(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename, YDirection outputYDirection) {
|
||||||
|
bool success = false;
|
||||||
|
if (FILE *f = fopen(filename, "wb")) {
|
||||||
|
int written = 0;
|
||||||
|
switch (outputYDirection) {
|
||||||
|
case YDirection::BOTTOM_UP:
|
||||||
|
written = fwrite(bitmap.pixels, sizeof(float), 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);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
success = written == N*bitmap.width*bitmap.height;
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
bool
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
saveImageBinaryLE
|
||||||
|
#else
|
||||||
|
saveImageBinaryBE
|
||||||
|
#endif
|
||||||
|
(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename, YDirection outputYDirection) {
|
||||||
|
bool success = false;
|
||||||
|
if (FILE *f = fopen(filename, "wb")) {
|
||||||
|
int 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);
|
||||||
|
for (int x = 0; x < bitmap.width; ++x) {
|
||||||
const unsigned char *b = reinterpret_cast<const unsigned char *>(p++);
|
const unsigned char *b = reinterpret_cast<const unsigned char *>(p++);
|
||||||
for (int i = sizeof(float)-1; i >= 0; --i)
|
for (int i = sizeof(float)-1; i >= 0; --i)
|
||||||
written += fwrite(b+i, 1, 1, f);
|
written += fwrite(b+i, 1, 1, f);
|
||||||
}
|
}
|
||||||
success = written == sizeof(float)*count;
|
}
|
||||||
|
success = written == sizeof(float)*N*bitmap.width*bitmap.height;
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
|
|
@ -117,11 +138,11 @@ bool
|
||||||
|
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
bool saveImageText(const msdfgen::BitmapConstRef<byte, N> &bitmap, const char *filename) {
|
bool saveImageText(const msdfgen::BitmapConstRef<byte, N> &bitmap, const char *filename, YDirection outputYDirection) {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (FILE *f = fopen(filename, "wb")) {
|
if (FILE *f = fopen(filename, "wb")) {
|
||||||
const byte *p = bitmap.pixels;
|
|
||||||
for (int y = 0; y < bitmap.height; ++y) {
|
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);
|
||||||
for (int x = 0; x < N*bitmap.width; ++x) {
|
for (int x = 0; x < N*bitmap.width; ++x) {
|
||||||
fprintf(f, x ? " %02X" : "%02X", (unsigned) *p++);
|
fprintf(f, x ? " %02X" : "%02X", (unsigned) *p++);
|
||||||
}
|
}
|
||||||
|
|
@ -133,11 +154,11 @@ bool saveImageText(const msdfgen::BitmapConstRef<byte, N> &bitmap, const char *f
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
bool saveImageText(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename) {
|
bool saveImageText(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename, YDirection outputYDirection) {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (FILE *f = fopen(filename, "wb")) {
|
if (FILE *f = fopen(filename, "wb")) {
|
||||||
const float *p = bitmap.pixels;
|
|
||||||
for (int y = 0; y < bitmap.height; ++y) {
|
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);
|
||||||
for (int x = 0; x < N*bitmap.width; ++x) {
|
for (int x = 0; x < N*bitmap.width; ++x) {
|
||||||
fprintf(f, x ? " %g" : "%g", *p++);
|
fprintf(f, x ? " %g" : "%g", *p++);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ static const char * imageTypeString(ImageType type) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool exportJSON(const FontGeometry *fonts, int fontCount, double fontSize, double pxRange, int atlasWidth, int atlasHeight, ImageType imageType, const char *filename, bool kerning) {
|
bool exportJSON(const FontGeometry *fonts, int fontCount, double fontSize, double pxRange, int atlasWidth, int atlasHeight, ImageType imageType, YDirection yDirection, const char *filename, bool kerning) {
|
||||||
FILE *f = fopen(filename, "w");
|
FILE *f = fopen(filename, "w");
|
||||||
if (!f)
|
if (!f)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -72,7 +72,7 @@ bool exportJSON(const FontGeometry *fonts, int fontCount, double fontSize, doubl
|
||||||
fprintf(f, "\"size\":%.17g,", fontSize);
|
fprintf(f, "\"size\":%.17g,", fontSize);
|
||||||
fprintf(f, "\"width\":%d,", atlasWidth);
|
fprintf(f, "\"width\":%d,", atlasWidth);
|
||||||
fprintf(f, "\"height\":%d,", atlasHeight);
|
fprintf(f, "\"height\":%d,", atlasHeight);
|
||||||
fputs("\"yOrigin\":\"bottom\"", f);
|
fprintf(f, "\"yOrigin\":\"%s\"", yDirection == YDirection::TOP_DOWN ? "top" : "bottom");
|
||||||
} fputs("},", f);
|
} fputs("},", f);
|
||||||
|
|
||||||
if (fontCount > 1)
|
if (fontCount > 1)
|
||||||
|
|
@ -89,12 +89,13 @@ bool exportJSON(const FontGeometry *fonts, int fontCount, double fontSize, doubl
|
||||||
|
|
||||||
// Font metrics
|
// Font metrics
|
||||||
fputs("\"metrics\":{", f); {
|
fputs("\"metrics\":{", f); {
|
||||||
|
double yFactor = yDirection == YDirection::TOP_DOWN ? -1 : 1;
|
||||||
const msdfgen::FontMetrics &metrics = font.getMetrics();
|
const msdfgen::FontMetrics &metrics = font.getMetrics();
|
||||||
fprintf(f, "\"emSize\":%.17g,", metrics.emSize);
|
fprintf(f, "\"emSize\":%.17g,", metrics.emSize);
|
||||||
fprintf(f, "\"lineHeight\":%.17g,", metrics.lineHeight);
|
fprintf(f, "\"lineHeight\":%.17g,", metrics.lineHeight);
|
||||||
fprintf(f, "\"ascender\":%.17g,", metrics.ascenderY);
|
fprintf(f, "\"ascender\":%.17g,", yFactor*metrics.ascenderY);
|
||||||
fprintf(f, "\"descender\":%.17g,", metrics.descenderY);
|
fprintf(f, "\"descender\":%.17g,", yFactor*metrics.descenderY);
|
||||||
fprintf(f, "\"underlineY\":%.17g,", metrics.underlineY);
|
fprintf(f, "\"underlineY\":%.17g,", yFactor*metrics.underlineY);
|
||||||
fprintf(f, "\"underlineThickness\":%.17g", metrics.underlineThickness);
|
fprintf(f, "\"underlineThickness\":%.17g", metrics.underlineThickness);
|
||||||
} fputs("},", f);
|
} fputs("},", f);
|
||||||
|
|
||||||
|
|
@ -114,11 +115,27 @@ bool exportJSON(const FontGeometry *fonts, int fontCount, double fontSize, doubl
|
||||||
fprintf(f, "\"advance\":%.17g", glyph.getAdvance());
|
fprintf(f, "\"advance\":%.17g", glyph.getAdvance());
|
||||||
double l, b, r, t;
|
double l, b, r, t;
|
||||||
glyph.getQuadPlaneBounds(l, b, r, t);
|
glyph.getQuadPlaneBounds(l, b, r, t);
|
||||||
if (l || b || r || t)
|
if (l || b || r || t) {
|
||||||
|
switch (yDirection) {
|
||||||
|
case YDirection::BOTTOM_UP:
|
||||||
fprintf(f, ",\"planeBounds\":{\"left\":%.17g,\"bottom\":%.17g,\"right\":%.17g,\"top\":%.17g}", l, b, r, t);
|
fprintf(f, ",\"planeBounds\":{\"left\":%.17g,\"bottom\":%.17g,\"right\":%.17g,\"top\":%.17g}", l, b, r, t);
|
||||||
|
break;
|
||||||
|
case YDirection::TOP_DOWN:
|
||||||
|
fprintf(f, ",\"planeBounds\":{\"left\":%.17g,\"top\":%.17g,\"right\":%.17g,\"bottom\":%.17g}", l, -t, r, -b);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
glyph.getQuadAtlasBounds(l, b, r, t);
|
glyph.getQuadAtlasBounds(l, b, r, t);
|
||||||
if (l || b || r || t)
|
if (l || b || r || t) {
|
||||||
|
switch (yDirection) {
|
||||||
|
case YDirection::BOTTOM_UP:
|
||||||
fprintf(f, ",\"atlasBounds\":{\"left\":%.17g,\"bottom\":%.17g,\"right\":%.17g,\"top\":%.17g}", l, b, r, t);
|
fprintf(f, ",\"atlasBounds\":{\"left\":%.17g,\"bottom\":%.17g,\"right\":%.17g,\"top\":%.17g}", l, b, r, t);
|
||||||
|
break;
|
||||||
|
case YDirection::TOP_DOWN:
|
||||||
|
fprintf(f, ",\"atlasBounds\":{\"left\":%.17g,\"top\":%.17g,\"right\":%.17g,\"bottom\":%.17g}", l, atlasHeight-t, r, atlasHeight-b);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
fputs("}", f);
|
fputs("}", f);
|
||||||
firstGlyph = false;
|
firstGlyph = false;
|
||||||
} fputs("]", f);
|
} fputs("]", f);
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,6 @@
|
||||||
namespace msdf_atlas {
|
namespace msdf_atlas {
|
||||||
|
|
||||||
/// Writes the font and glyph metrics and atlas layout data into a comprehensive JSON file
|
/// Writes the font and glyph metrics and atlas layout data into a comprehensive JSON file
|
||||||
bool exportJSON(const FontGeometry *fonts, int fontCount, double fontSize, double pxRange, int atlasWidth, int atlasHeight, ImageType imageType, const char *filename, bool kerning);
|
bool exportJSON(const FontGeometry *fonts, int fontCount, double fontSize, double pxRange, int atlasWidth, int atlasHeight, ImageType imageType, YDirection yDirection, const char *filename, bool kerning);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,8 @@ ATLAS CONFIGURATION
|
||||||
-pots / -potr / -square / -square2 / -square4
|
-pots / -potr / -square / -square2 / -square4
|
||||||
Picks the minimum atlas dimensions that fit all glyphs and satisfy the selected constraint:
|
Picks the minimum atlas dimensions that fit all glyphs and satisfy the selected constraint:
|
||||||
power of two square / ... rectangle / any square / square with side divisible by 2 / ... 4
|
power of two square / ... rectangle / any square / square with side divisible by 2 / ... 4
|
||||||
|
-yorigin <bottom / top>
|
||||||
|
Determines whether the Y-axis is oriented upwards (bottom origin, default) or downwards (top origin).
|
||||||
|
|
||||||
OUTPUT SPECIFICATION - one or more can be specified
|
OUTPUT SPECIFICATION - one or more can be specified
|
||||||
-imageout <filename.*>
|
-imageout <filename.*>
|
||||||
|
|
@ -167,6 +169,7 @@ struct FontInput {
|
||||||
struct Configuration {
|
struct Configuration {
|
||||||
ImageType imageType;
|
ImageType imageType;
|
||||||
ImageFormat imageFormat;
|
ImageFormat imageFormat;
|
||||||
|
YDirection yDirection;
|
||||||
int width, height;
|
int width, height;
|
||||||
double emSize;
|
double emSize;
|
||||||
double pxRange;
|
double pxRange;
|
||||||
|
|
@ -196,7 +199,7 @@ static bool makeAtlas(const std::vector<GlyphGeometry> &glyphs, const std::vecto
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
if (config.imageFilename) {
|
if (config.imageFilename) {
|
||||||
if (saveImage(bitmap, config.imageFormat, config.imageFilename))
|
if (saveImage(bitmap, config.imageFormat, config.imageFilename, config.yDirection))
|
||||||
puts("Atlas image file saved.");
|
puts("Atlas image file saved.");
|
||||||
else {
|
else {
|
||||||
success = false;
|
success = false;
|
||||||
|
|
@ -210,6 +213,7 @@ static bool makeAtlas(const std::vector<GlyphGeometry> &glyphs, const std::vecto
|
||||||
arfontProps.pxRange = config.pxRange;
|
arfontProps.pxRange = config.pxRange;
|
||||||
arfontProps.imageType = config.imageType;
|
arfontProps.imageType = config.imageType;
|
||||||
arfontProps.imageFormat = config.imageFormat;
|
arfontProps.imageFormat = config.imageFormat;
|
||||||
|
arfontProps.yDirection = config.yDirection;
|
||||||
if (exportArteryFont<float>(fonts.data(), fonts.size(), bitmap, config.arteryFontFilename, arfontProps))
|
if (exportArteryFont<float>(fonts.data(), fonts.size(), bitmap, config.arteryFontFilename, arfontProps))
|
||||||
puts("Artery Font file generated.");
|
puts("Artery Font file generated.");
|
||||||
else {
|
else {
|
||||||
|
|
@ -230,9 +234,10 @@ int main(int argc, const char * const *argv) {
|
||||||
Configuration config = { };
|
Configuration config = { };
|
||||||
fontInput.glyphIdentifierType = GlyphIdentifierType::UNICODE_CODEPOINT;
|
fontInput.glyphIdentifierType = GlyphIdentifierType::UNICODE_CODEPOINT;
|
||||||
fontInput.fontScale = -1;
|
fontInput.fontScale = -1;
|
||||||
config.kerning = true;
|
|
||||||
config.imageType = ImageType::MSDF;
|
config.imageType = ImageType::MSDF;
|
||||||
config.imageFormat = ImageFormat::UNSPECIFIED;
|
config.imageFormat = ImageFormat::UNSPECIFIED;
|
||||||
|
config.yDirection = YDirection::BOTTOM_UP;
|
||||||
|
config.kerning = true;
|
||||||
const char *imageFormatName = nullptr;
|
const char *imageFormatName = nullptr;
|
||||||
int fixedWidth = -1, fixedHeight = -1;
|
int fixedWidth = -1, fixedHeight = -1;
|
||||||
config.preprocessGeometry = (
|
config.preprocessGeometry = (
|
||||||
|
|
@ -412,6 +417,17 @@ int main(int argc, const char * const *argv) {
|
||||||
++argPos;
|
++argPos;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
ARG_CASE("-yorigin", 1) {
|
||||||
|
arg = argv[++argPos];
|
||||||
|
if (!strcmp(arg, "bottom"))
|
||||||
|
config.yDirection = YDirection::BOTTOM_UP;
|
||||||
|
else if (!strcmp(arg, "top"))
|
||||||
|
config.yDirection = YDirection::TOP_DOWN;
|
||||||
|
else
|
||||||
|
ABORT("Invalid Y-axis origin. Use bottom or top.");
|
||||||
|
++argPos;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
ARG_CASE("-size", 1) {
|
ARG_CASE("-size", 1) {
|
||||||
double s;
|
double s;
|
||||||
if (!(parseDouble(s, argv[++argPos]) && s > 0))
|
if (!(parseDouble(s, argv[++argPos]) && s > 0))
|
||||||
|
|
@ -839,7 +855,7 @@ int main(int argc, const char * const *argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.csvFilename) {
|
if (config.csvFilename) {
|
||||||
if (exportCSV(fonts.data(), fonts.size(), config.csvFilename))
|
if (exportCSV(fonts.data(), fonts.size(), config.width, config.height, config.yDirection, config.csvFilename))
|
||||||
puts("Glyph layout written into CSV file.");
|
puts("Glyph layout written into CSV file.");
|
||||||
else {
|
else {
|
||||||
result = 1;
|
result = 1;
|
||||||
|
|
@ -847,7 +863,7 @@ int main(int argc, const char * const *argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (config.jsonFilename) {
|
if (config.jsonFilename) {
|
||||||
if (exportJSON(fonts.data(), fonts.size(), config.emSize, config.pxRange, config.width, config.height, config.imageType, config.jsonFilename, config.kerning))
|
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.");
|
puts("Glyph layout and metadata written into JSON file.");
|
||||||
else {
|
else {
|
||||||
result = 1;
|
result = 1;
|
||||||
|
|
|
||||||
|
|
@ -43,4 +43,10 @@ enum class GlyphIdentifierType {
|
||||||
UNICODE_CODEPOINT
|
UNICODE_CODEPOINT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Direction of the Y-axis
|
||||||
|
enum class YDirection {
|
||||||
|
BOTTOM_UP,
|
||||||
|
TOP_DOWN
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue