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 {