diff --git a/CHANGELOG.md b/CHANGELOG.md index 065fca45..18dcfdb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,15 @@ +## Version 1.7 (2020-03-07) + +- Added `mtsdf` mode - a combination of `msdf` with `sdf` in the alpha channel +- Distance fields can now be stored as uncompressed TIFF image files with floating point precision +- Bitmap class refactor - template argument split into data type and number of channels, bitmap reference classes introduced +- Added a secondary "ink trap" edge coloring heuristic, can be selected using `-coloringstrategy inktrap` +- Added computation of estimated rendering error for a given SDF +- Added computation of bounding box that includes sharp mitered corners +- The API for bounds computation of the `Shape` class changed for clarity +- Fixed several edge case bugs + ## Version 1.6 (2019-04-08) - Core algorithm rewritten to split up advanced edge selection logic into modular template arguments. diff --git a/Msdfgen.vcxproj b/Msdfgen.vcxproj index 7308dd91..8c508f1a 100644 --- a/Msdfgen.vcxproj +++ b/Msdfgen.vcxproj @@ -124,29 +124,35 @@ msdfgen + $(Configuration)\ msdfgen + $(Configuration)\ msdfgen - $(SolutionDir)\bin\ + bin\ msdfgen - $(SolutionDir)\bin\ + bin\ msdfgen + $(Platform)\$(Configuration)\ msdfgen + $(Platform)\$(Configuration)\ msdfgen + $(Platform)\$(Configuration)\ msdfgen + $(Platform)\$(Configuration)\ diff --git a/core/Bitmap.h b/core/Bitmap.h index 3ad23a8e..14407d6c 100644 --- a/core/Bitmap.h +++ b/core/Bitmap.h @@ -29,8 +29,13 @@ class Bitmap { int height() const; T * operator()(int x, int y); const T * operator()(int x, int y) const; +#ifdef MSDFGEN_USE_CPP11 explicit operator T *(); explicit operator const T *() const; +#else + operator T *(); + operator const T *() const; +#endif operator BitmapRef(); operator BitmapConstRef() const; diff --git a/core/shape-description.cpp b/core/shape-description.cpp index 97d09cf4..0bbb7959 100644 --- a/core/shape-description.cpp +++ b/core/shape-description.cpp @@ -220,9 +220,18 @@ bool readShapeDescription(const char *input, Shape &output, bool *colorsSpecifie } } +static bool isColored(const Shape &shape) { + for (std::vector::const_iterator contour = shape.contours.begin(); contour != shape.contours.end(); ++contour) + for (std::vector::const_iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) + if ((*edge)->color != WHITE) + return true; + return false; +} + bool writeShapeDescription(FILE *output, const Shape &shape) { if (!shape.validate()) return false; + bool writeColors = isColored(shape); if (shape.inverseYAxis) fprintf(output, "@invert-y\n"); for (std::vector::const_iterator contour = shape.contours.begin(); contour != shape.contours.end(); ++contour) { @@ -230,12 +239,14 @@ bool writeShapeDescription(FILE *output, const Shape &shape) { if (!contour->edges.empty()) { for (std::vector::const_iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) { char colorCode = '\0'; - switch ((*edge)->color) { - case YELLOW: colorCode = 'y'; break; - case MAGENTA: colorCode = 'm'; break; - case CYAN: colorCode = 'c'; break; - case WHITE: colorCode = 'w'; break; - default:; + if (writeColors) { + switch ((*edge)->color) { + case YELLOW: colorCode = 'y'; break; + case MAGENTA: colorCode = 'm'; break; + case CYAN: colorCode = 'c'; break; + case WHITE: colorCode = 'w'; break; + default:; + } } { const LinearSegment *e = dynamic_cast(&**edge); diff --git a/main.cpp b/main.cpp index ed672baa..9d64d514 100644 --- a/main.cpp +++ b/main.cpp @@ -1,8 +1,8 @@ /* - * MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.6 (2019-04-08) - standalone console program + * MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.7 (2020-03-07) - standalone console program * -------------------------------------------------------------------------------------------- - * A utility by Viktor Chlumsky, (c) 2014 - 2019 + * A utility by Viktor Chlumsky, (c) 2014 - 2020 * */ @@ -33,7 +33,7 @@ enum Format { TEXT_FLOAT, BINARY, BINARY_FLOAT, - BINART_FLOAT_BE + BINARY_FLOAT_BE }; static bool is8bitFormat(Format format) { @@ -228,14 +228,14 @@ static const char * writeOutput(const BitmapConstRef &bitmap, const ch fclose(file); return NULL; } - case BINARY: case BINARY_FLOAT: case BINART_FLOAT_BE: { + case BINARY: case BINARY_FLOAT: case BINARY_FLOAT_BE: { FILE *file = fopen(filename, "wb"); if (!file) return "Failed to write output binary file."; if (format == BINARY) writeBinBitmap(file, bitmap.pixels, N*bitmap.width*bitmap.height); else if (format == BINARY_FLOAT) writeBinBitmapFloat(file, bitmap.pixels, N*bitmap.width*bitmap.height); - else if (format == BINART_FLOAT_BE) + else if (format == BINARY_FLOAT_BE) writeBinBitmapFloatBE(file, bitmap.pixels, N*bitmap.width*bitmap.height); fclose(file); return NULL; @@ -498,7 +498,7 @@ int main(int argc, const char * const *argv) { else if (!strcmp(argv[argPos+1], "textfloat") || !strcmp(argv[argPos+1], "txtfloat")) SET_FORMAT(TEXT_FLOAT, "txt"); else if (!strcmp(argv[argPos+1], "bin") || !strcmp(argv[argPos+1], "binary")) SET_FORMAT(BINARY, "bin"); else if (!strcmp(argv[argPos+1], "binfloat") || !strcmp(argv[argPos+1], "binfloatle")) SET_FORMAT(BINARY_FLOAT, "bin"); - else if (!strcmp(argv[argPos+1], "binfloatbe")) SET_FORMAT(BINART_FLOAT_BE, "bin"); + else if (!strcmp(argv[argPos+1], "binfloatbe")) SET_FORMAT(BINARY_FLOAT_BE, "bin"); else puts("Unknown format specified."); argPos += 2; @@ -657,8 +657,10 @@ int main(int argc, const char * const *argv) { argPos += 2; continue; } - ARG_CASE("-help", 0) - ABORT(helpText); + ARG_CASE("-help", 0) { + puts(helpText); + return 0; + } printf("Unknown setting or insufficient parameters: %s\n", arg); suggestHelp = true; ++argPos; diff --git a/msdfgen-ext.h b/msdfgen-ext.h index 8445464b..7fb5f5de 100644 --- a/msdfgen-ext.h +++ b/msdfgen-ext.h @@ -2,9 +2,9 @@ #pragma once /* - * MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.6 (2019-04-08) - extensions + * MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.7 (2020-03-07) - extensions * ---------------------------------------------------------------------------- - * A utility by Viktor Chlumsky, (c) 2014 - 2019 + * A utility by Viktor Chlumsky, (c) 2014 - 2020 * * The extension module provides ways to easily load input and save output using popular formats. * diff --git a/msdfgen.h b/msdfgen.h index 96bbc8ce..c7261964 100644 --- a/msdfgen.h +++ b/msdfgen.h @@ -2,16 +2,16 @@ #pragma once /* - * MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.6 (2019-04-08) + * MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.7 (2020-03-07) * --------------------------------------------------------------- - * A utility by Viktor Chlumsky, (c) 2014 - 2019 + * A utility by Viktor Chlumsky, (c) 2014 - 2020 * * The technique used to generate multi-channel distance fields in this code * has been developed by Viktor Chlumsky in 2014 for his master's thesis, * "Shape Decomposition for Multi-Channel Distance Fields". It provides improved - * quality of sharp corners in glyphs and other 2D shapes in comparison to monochrome + * quality of sharp corners in glyphs and other 2D shapes compared to monochrome * distance fields. To reconstruct an image of the shape, apply the median of three - * operation on the triplet of sampled distance field values. + * operation on the triplet of sampled signed distance values. * */ @@ -30,7 +30,7 @@ #include "core/save-tiff.h" #include "core/shape-description.h" -#define MSDFGEN_VERSION "1.6" +#define MSDFGEN_VERSION "1.7" #define MSDFGEN_DEFAULT_ERROR_CORRECTION_THRESHOLD 1.001 namespace msdfgen {