Version 1.7

This commit is contained in:
Viktor Chlumský 2020-03-07 09:19:34 +01:00
parent fd50406d67
commit 5427fe8f5a
7 changed files with 58 additions and 23 deletions

View File

@ -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.

View File

@ -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>

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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.
*

View File

@ -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 {