Browse Source

Version 1.7

Viktor Chlumský 5 years ago
parent
commit
5427fe8f5a
7 changed files with 58 additions and 23 deletions
  1. 11 0
      CHANGELOG.md
  2. 8 2
      Msdfgen.vcxproj
  3. 5 0
      core/Bitmap.h
  4. 17 6
      core/shape-description.cpp
  5. 10 8
      main.cpp
  6. 2 2
      msdfgen-ext.h
  7. 5 5
      msdfgen.h

+ 11 - 0
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.

+ 8 - 2
Msdfgen.vcxproj

@@ -124,29 +124,35 @@
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <TargetName>msdfgen</TargetName>
+    <OutDir>$(Configuration)\</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|Win32'">
     <TargetName>msdfgen</TargetName>
+    <OutDir>$(Configuration)\</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <TargetName>msdfgen</TargetName>
-    <OutDir>$(SolutionDir)\bin\</OutDir>
+    <OutDir>bin\</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|Win32'">
     <TargetName>msdfgen</TargetName>
-    <OutDir>$(SolutionDir)\bin\</OutDir>
+    <OutDir>bin\</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|x64'">
     <TargetName>msdfgen</TargetName>
+    <OutDir>$(Platform)\$(Configuration)\</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <TargetName>msdfgen</TargetName>
+    <OutDir>$(Platform)\$(Configuration)\</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <TargetName>msdfgen</TargetName>
+    <OutDir>$(Platform)\$(Configuration)\</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|x64'">
     <TargetName>msdfgen</TargetName>
+    <OutDir>$(Platform)\$(Configuration)\</OutDir>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>

+ 5 - 0
core/Bitmap.h

@@ -29,8 +29,13 @@ public:
     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<T, N>();
     operator BitmapConstRef<T, N>() const;
 

+ 17 - 6
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<Contour>::const_iterator contour = shape.contours.begin(); contour != shape.contours.end(); ++contour)
+        for (std::vector<EdgeHolder>::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<Contour>::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<EdgeHolder>::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<const LinearSegment *>(&**edge);

+ 10 - 8
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<float, N> &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;

+ 2 - 2
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.
  *

+ 5 - 5
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 {