You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-31 18:41:20 +00:00
msdfgen: Update to 1.13
Remove unused `export-svg` and `save-*` files.
This commit is contained in:
@@ -23,6 +23,7 @@ if env["builtin_msdfgen"]:
|
|||||||
"core/Scanline.cpp",
|
"core/Scanline.cpp",
|
||||||
"core/Shape.cpp",
|
"core/Shape.cpp",
|
||||||
"core/contour-combiners.cpp",
|
"core/contour-combiners.cpp",
|
||||||
|
"core/convergent-curve-ordering.cpp",
|
||||||
"core/edge-coloring.cpp",
|
"core/edge-coloring.cpp",
|
||||||
"core/edge-segments.cpp",
|
"core/edge-segments.cpp",
|
||||||
"core/edge-selectors.cpp",
|
"core/edge-selectors.cpp",
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ if env["msdfgen_enabled"] and env["freetype_enabled"]:
|
|||||||
"core/Scanline.cpp",
|
"core/Scanline.cpp",
|
||||||
"core/Shape.cpp",
|
"core/Shape.cpp",
|
||||||
"core/contour-combiners.cpp",
|
"core/contour-combiners.cpp",
|
||||||
|
"core/convergent-curve-ordering.cpp",
|
||||||
"core/edge-coloring.cpp",
|
"core/edge-coloring.cpp",
|
||||||
"core/edge-segments.cpp",
|
"core/edge-segments.cpp",
|
||||||
"core/edge-selectors.cpp",
|
"core/edge-selectors.cpp",
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ if env["msdfgen_enabled"] and env["freetype_enabled"]:
|
|||||||
"core/Scanline.cpp",
|
"core/Scanline.cpp",
|
||||||
"core/Shape.cpp",
|
"core/Shape.cpp",
|
||||||
"core/contour-combiners.cpp",
|
"core/contour-combiners.cpp",
|
||||||
|
"core/convergent-curve-ordering.cpp",
|
||||||
"core/edge-coloring.cpp",
|
"core/edge-coloring.cpp",
|
||||||
"core/edge-segments.cpp",
|
"core/edge-segments.cpp",
|
||||||
"core/edge-selectors.cpp",
|
"core/edge-selectors.cpp",
|
||||||
|
|||||||
8
thirdparty/README.md
vendored
8
thirdparty/README.md
vendored
@@ -850,15 +850,19 @@ Collection of single-file libraries used in Godot components.
|
|||||||
## msdfgen
|
## msdfgen
|
||||||
|
|
||||||
- Upstream: https://github.com/Chlumsky/msdfgen
|
- Upstream: https://github.com/Chlumsky/msdfgen
|
||||||
- Version: 1.12.1 (6574da1310df433c97ca0fddcab7e463c31e58f8, 2025)
|
- Version: 1.13 (1874bcf7d9624ccc85b4bc9a85d78116f690f35b, 2025)
|
||||||
- License: MIT
|
- License: MIT
|
||||||
|
|
||||||
Files extracted from the upstream source:
|
Files extracted from the upstream source:
|
||||||
|
|
||||||
- `msdfgen.h`
|
- `msdfgen.h`
|
||||||
- Files in `core/` folder
|
- Files in `core/` folder, minus `export-svg.*` and `save-*.*` files
|
||||||
- `LICENSE.txt`
|
- `LICENSE.txt`
|
||||||
|
|
||||||
|
Patches:
|
||||||
|
|
||||||
|
- `0001-remove-unused-save-features.patch` ([GH-113965](https://github.com/godotengine/godot/issues/113965))
|
||||||
|
|
||||||
|
|
||||||
## openxr
|
## openxr
|
||||||
|
|
||||||
|
|||||||
14
thirdparty/msdfgen/core/Bitmap.h
vendored
14
thirdparty/msdfgen/core/Bitmap.h
vendored
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "YAxisOrientation.h"
|
||||||
#include "BitmapRef.hpp"
|
#include "BitmapRef.hpp"
|
||||||
|
|
||||||
namespace msdfgen {
|
namespace msdfgen {
|
||||||
@@ -11,14 +12,16 @@ class Bitmap {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Bitmap();
|
Bitmap();
|
||||||
Bitmap(int width, int height);
|
Bitmap(int width, int height, YAxisOrientation yOrientation = MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION);
|
||||||
Bitmap(const BitmapConstRef<T, N> &orig);
|
explicit Bitmap(const BitmapConstRef<T, N> &orig);
|
||||||
|
explicit Bitmap(const BitmapConstSection<T, N> &orig);
|
||||||
Bitmap(const Bitmap<T, N> &orig);
|
Bitmap(const Bitmap<T, N> &orig);
|
||||||
#ifdef MSDFGEN_USE_CPP11
|
#ifdef MSDFGEN_USE_CPP11
|
||||||
Bitmap(Bitmap<T, N> &&orig);
|
Bitmap(Bitmap<T, N> &&orig);
|
||||||
#endif
|
#endif
|
||||||
~Bitmap();
|
~Bitmap();
|
||||||
Bitmap<T, N> &operator=(const BitmapConstRef<T, N> &orig);
|
Bitmap<T, N> &operator=(const BitmapConstRef<T, N> &orig);
|
||||||
|
Bitmap<T, N> &operator=(const BitmapConstSection<T, N> &orig);
|
||||||
Bitmap<T, N> &operator=(const Bitmap<T, N> &orig);
|
Bitmap<T, N> &operator=(const Bitmap<T, N> &orig);
|
||||||
#ifdef MSDFGEN_USE_CPP11
|
#ifdef MSDFGEN_USE_CPP11
|
||||||
Bitmap<T, N> &operator=(Bitmap<T, N> &&orig);
|
Bitmap<T, N> &operator=(Bitmap<T, N> &&orig);
|
||||||
@@ -38,10 +41,17 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
operator BitmapRef<T, N>();
|
operator BitmapRef<T, N>();
|
||||||
operator BitmapConstRef<T, N>() const;
|
operator BitmapConstRef<T, N>() const;
|
||||||
|
operator BitmapSection<T, N>();
|
||||||
|
operator BitmapConstSection<T, N>() const;
|
||||||
|
/// Returns a reference to a rectangular section of the bitmap specified by bounds (excluding xMax, yMax).
|
||||||
|
BitmapSection<T, N> getSection(int xMin, int yMin, int xMax, int yMax);
|
||||||
|
/// Returns a constant reference to a rectangular section of the bitmap specified by bounds (excluding xMax, yMax).
|
||||||
|
BitmapConstSection<T, N> getConstSection(int xMin, int yMin, int xMax, int yMax) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T *pixels;
|
T *pixels;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
YAxisOrientation yOrientation;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
77
thirdparty/msdfgen/core/Bitmap.hpp
vendored
77
thirdparty/msdfgen/core/Bitmap.hpp
vendored
@@ -7,28 +7,41 @@
|
|||||||
namespace msdfgen {
|
namespace msdfgen {
|
||||||
|
|
||||||
template <typename T, int N>
|
template <typename T, int N>
|
||||||
Bitmap<T, N>::Bitmap() : pixels(NULL), w(0), h(0) { }
|
Bitmap<T, N>::Bitmap() : pixels(NULL), w(0), h(0), yOrientation(MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION) { }
|
||||||
|
|
||||||
template <typename T, int N>
|
template <typename T, int N>
|
||||||
Bitmap<T, N>::Bitmap(int width, int height) : w(width), h(height) {
|
Bitmap<T, N>::Bitmap(int width, int height, YAxisOrientation yOrientation) : w(width), h(height), yOrientation(yOrientation) {
|
||||||
pixels = new T[N*w*h];
|
pixels = new T[N*w*h];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, int N>
|
template <typename T, int N>
|
||||||
Bitmap<T, N>::Bitmap(const BitmapConstRef<T, N> &orig) : w(orig.width), h(orig.height) {
|
Bitmap<T, N>::Bitmap(const BitmapConstRef<T, N> &orig) : w(orig.width), h(orig.height), yOrientation(orig.yOrientation) {
|
||||||
pixels = new T[N*w*h];
|
pixels = new T[N*w*h];
|
||||||
memcpy(pixels, orig.pixels, sizeof(T)*N*w*h);
|
memcpy(pixels, orig.pixels, sizeof(T)*N*w*h);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, int N>
|
template <typename T, int N>
|
||||||
Bitmap<T, N>::Bitmap(const Bitmap<T, N> &orig) : w(orig.w), h(orig.h) {
|
Bitmap<T, N>::Bitmap(const BitmapConstSection<T, N> &orig) : w(orig.width), h(orig.height), yOrientation(orig.yOrientation) {
|
||||||
|
pixels = new T[N*w*h];
|
||||||
|
T *dst = pixels;
|
||||||
|
const T *src = orig.pixels;
|
||||||
|
int rowLength = N*w;
|
||||||
|
for (int y = 0; y < h; ++y) {
|
||||||
|
memcpy(dst, src, sizeof(T)*rowLength);
|
||||||
|
dst += rowLength;
|
||||||
|
src += orig.rowStride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, int N>
|
||||||
|
Bitmap<T, N>::Bitmap(const Bitmap<T, N> &orig) : w(orig.w), h(orig.h), yOrientation(orig.yOrientation) {
|
||||||
pixels = new T[N*w*h];
|
pixels = new T[N*w*h];
|
||||||
memcpy(pixels, orig.pixels, sizeof(T)*N*w*h);
|
memcpy(pixels, orig.pixels, sizeof(T)*N*w*h);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MSDFGEN_USE_CPP11
|
#ifdef MSDFGEN_USE_CPP11
|
||||||
template <typename T, int N>
|
template <typename T, int N>
|
||||||
Bitmap<T, N>::Bitmap(Bitmap<T, N> &&orig) : pixels(orig.pixels), w(orig.w), h(orig.h) {
|
Bitmap<T, N>::Bitmap(Bitmap<T, N> &&orig) : pixels(orig.pixels), w(orig.w), h(orig.h), yOrientation(orig.yOrientation) {
|
||||||
orig.pixels = NULL;
|
orig.pixels = NULL;
|
||||||
orig.w = 0, orig.h = 0;
|
orig.w = 0, orig.h = 0;
|
||||||
}
|
}
|
||||||
@@ -36,25 +49,46 @@ Bitmap<T, N>::Bitmap(Bitmap<T, N> &&orig) : pixels(orig.pixels), w(orig.w), h(or
|
|||||||
|
|
||||||
template <typename T, int N>
|
template <typename T, int N>
|
||||||
Bitmap<T, N>::~Bitmap() {
|
Bitmap<T, N>::~Bitmap() {
|
||||||
delete [] pixels;
|
delete[] pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, int N>
|
template <typename T, int N>
|
||||||
Bitmap<T, N> &Bitmap<T, N>::operator=(const BitmapConstRef<T, N> &orig) {
|
Bitmap<T, N> &Bitmap<T, N>::operator=(const BitmapConstRef<T, N> &orig) {
|
||||||
if (pixels != orig.pixels) {
|
if (pixels != orig.pixels) {
|
||||||
delete [] pixels;
|
delete[] pixels;
|
||||||
w = orig.width, h = orig.height;
|
w = orig.width, h = orig.height;
|
||||||
|
yOrientation = orig.yOrientation;
|
||||||
pixels = new T[N*w*h];
|
pixels = new T[N*w*h];
|
||||||
memcpy(pixels, orig.pixels, sizeof(T)*N*w*h);
|
memcpy(pixels, orig.pixels, sizeof(T)*N*w*h);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, int N>
|
||||||
|
Bitmap<T, N> &Bitmap<T, N>::operator=(const BitmapConstSection<T, N> &orig) {
|
||||||
|
if (orig.pixels && orig.pixels >= pixels && orig.pixels < pixels+N*w*h)
|
||||||
|
return *this = Bitmap<T, N>(orig);
|
||||||
|
delete[] pixels;
|
||||||
|
w = orig.width, h = orig.height;
|
||||||
|
yOrientation = orig.yOrientation;
|
||||||
|
pixels = new T[N*w*h];
|
||||||
|
T *dst = pixels;
|
||||||
|
const T *src = orig.pixels;
|
||||||
|
int rowLength = N*w;
|
||||||
|
for (int y = 0; y < h; ++y) {
|
||||||
|
memcpy(dst, src, sizeof(T)*rowLength);
|
||||||
|
dst += rowLength;
|
||||||
|
src += orig.rowStride;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, int N>
|
template <typename T, int N>
|
||||||
Bitmap<T, N> &Bitmap<T, N>::operator=(const Bitmap<T, N> &orig) {
|
Bitmap<T, N> &Bitmap<T, N>::operator=(const Bitmap<T, N> &orig) {
|
||||||
if (this != &orig) {
|
if (this != &orig) {
|
||||||
delete [] pixels;
|
delete[] pixels;
|
||||||
w = orig.w, h = orig.h;
|
w = orig.w, h = orig.h;
|
||||||
|
yOrientation = orig.yOrientation;
|
||||||
pixels = new T[N*w*h];
|
pixels = new T[N*w*h];
|
||||||
memcpy(pixels, orig.pixels, sizeof(T)*N*w*h);
|
memcpy(pixels, orig.pixels, sizeof(T)*N*w*h);
|
||||||
}
|
}
|
||||||
@@ -65,9 +99,10 @@ Bitmap<T, N> &Bitmap<T, N>::operator=(const Bitmap<T, N> &orig) {
|
|||||||
template <typename T, int N>
|
template <typename T, int N>
|
||||||
Bitmap<T, N> &Bitmap<T, N>::operator=(Bitmap<T, N> &&orig) {
|
Bitmap<T, N> &Bitmap<T, N>::operator=(Bitmap<T, N> &&orig) {
|
||||||
if (this != &orig) {
|
if (this != &orig) {
|
||||||
delete [] pixels;
|
delete[] pixels;
|
||||||
pixels = orig.pixels;
|
pixels = orig.pixels;
|
||||||
w = orig.w, h = orig.h;
|
w = orig.w, h = orig.h;
|
||||||
|
yOrientation = orig.yOrientation;
|
||||||
orig.pixels = NULL;
|
orig.pixels = NULL;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
@@ -106,12 +141,32 @@ Bitmap<T, N>::operator const T *() const {
|
|||||||
|
|
||||||
template <typename T, int N>
|
template <typename T, int N>
|
||||||
Bitmap<T, N>::operator BitmapRef<T, N>() {
|
Bitmap<T, N>::operator BitmapRef<T, N>() {
|
||||||
return BitmapRef<T, N>(pixels, w, h);
|
return BitmapRef<T, N>(pixels, w, h, yOrientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, int N>
|
template <typename T, int N>
|
||||||
Bitmap<T, N>::operator BitmapConstRef<T, N>() const {
|
Bitmap<T, N>::operator BitmapConstRef<T, N>() const {
|
||||||
return BitmapConstRef<T, N>(pixels, w, h);
|
return BitmapConstRef<T, N>(pixels, w, h, yOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, int N>
|
||||||
|
Bitmap<T, N>::operator BitmapSection<T, N>() {
|
||||||
|
return BitmapSection<T, N>(pixels, w, h, yOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, int N>
|
||||||
|
Bitmap<T, N>::operator BitmapConstSection<T, N>() const {
|
||||||
|
return BitmapConstSection<T, N>(pixels, w, h, yOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, int N>
|
||||||
|
BitmapSection<T, N> Bitmap<T, N>::getSection(int xMin, int yMin, int xMax, int yMax) {
|
||||||
|
return BitmapSection<T, N>(pixels+N*(w*yMin+xMin), xMax-xMin, yMax-yMin, N*w, yOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, int N>
|
||||||
|
BitmapConstSection<T, N> Bitmap<T, N>::getConstSection(int xMin, int yMin, int xMax, int yMax) const {
|
||||||
|
return BitmapConstSection<T, N>(pixels+N*(w*yMin+xMin), xMax-xMin, yMax-yMin, N*w, yOrientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
129
thirdparty/msdfgen/core/BitmapRef.hpp
vendored
129
thirdparty/msdfgen/core/BitmapRef.hpp
vendored
@@ -1,41 +1,154 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "base.h"
|
#include "YAxisOrientation.h"
|
||||||
|
|
||||||
namespace msdfgen {
|
namespace msdfgen {
|
||||||
|
|
||||||
/// Reference to a 2D image bitmap or a buffer acting as one. Pixel storage not owned or managed by the object.
|
/// Reference to a 2D image bitmap or a buffer acting as one. Pixel storage not owned or managed by the object.
|
||||||
template <typename T, int N = 1>
|
template <typename T, int N = 1>
|
||||||
|
struct BitmapRef;
|
||||||
|
/// Constant reference to a 2D image bitmap or a buffer acting as one. Pixel storage not owned or managed by the object.
|
||||||
|
template <typename T, int N = 1>
|
||||||
|
struct BitmapConstRef;
|
||||||
|
/// Reference to a 2D image bitmap with non-contiguous rows of pixels. Pixel storage not owned or managed by the object. Can represent e.g. a section of a larger bitmap, bitmap with padded rows, or vertically flipped bitmap (rowStride can be negative).
|
||||||
|
template <typename T, int N = 1>
|
||||||
|
struct BitmapSection;
|
||||||
|
/// Constant reference to a 2D image bitmap with non-contiguous rows of pixels. Pixel storage not owned or managed by the object. Can represent e.g. a section of a larger bitmap, bitmap with padded rows, or vertically flipped bitmap (rowStride can be negative).
|
||||||
|
template <typename T, int N = 1>
|
||||||
|
struct BitmapConstSection;
|
||||||
|
|
||||||
|
template <typename T, int N>
|
||||||
struct BitmapRef {
|
struct BitmapRef {
|
||||||
|
|
||||||
T *pixels;
|
T *pixels;
|
||||||
int width, height;
|
int width, height;
|
||||||
|
YAxisOrientation yOrientation;
|
||||||
|
|
||||||
inline BitmapRef() : pixels(NULL), width(0), height(0) { }
|
inline BitmapRef() : pixels(NULL), width(0), height(0), yOrientation(MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION) { }
|
||||||
inline BitmapRef(T *pixels, int width, int height) : pixels(pixels), width(width), height(height) { }
|
inline BitmapRef(T *pixels, int width, int height, YAxisOrientation yOrientation = MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION) : pixels(pixels), width(width), height(height), yOrientation(yOrientation) { }
|
||||||
|
|
||||||
inline T *operator()(int x, int y) const {
|
inline T *operator()(int x, int y) const {
|
||||||
return pixels+N*(width*y+x);
|
return pixels+N*(width*y+x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to a rectangular section of the bitmap specified by bounds (excluding xMax, yMax).
|
||||||
|
inline BitmapSection<T, N> getSection(int xMin, int yMin, int xMax, int yMax) const {
|
||||||
|
return BitmapSection<T, N>(pixels+N*(width*yMin+xMin), xMax-xMin, yMax-yMin, N*width, yOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a constant reference to a rectangular section of the bitmap specified by bounds (excluding xMax, yMax).
|
||||||
|
inline BitmapConstSection<T, N> getConstSection(int xMin, int yMin, int xMax, int yMax) const {
|
||||||
|
return BitmapConstSection<T, N>(pixels+N*(width*yMin+xMin), xMax-xMin, yMax-yMin, N*width, yOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Constant reference to a 2D image bitmap or a buffer acting as one. Pixel storage not owned or managed by the object.
|
template <typename T, int N>
|
||||||
template <typename T, int N = 1>
|
|
||||||
struct BitmapConstRef {
|
struct BitmapConstRef {
|
||||||
|
|
||||||
const T *pixels;
|
const T *pixels;
|
||||||
int width, height;
|
int width, height;
|
||||||
|
YAxisOrientation yOrientation;
|
||||||
|
|
||||||
inline BitmapConstRef() : pixels(NULL), width(0), height(0) { }
|
inline BitmapConstRef() : pixels(NULL), width(0), height(0), yOrientation(MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION) { }
|
||||||
inline BitmapConstRef(const T *pixels, int width, int height) : pixels(pixels), width(width), height(height) { }
|
inline BitmapConstRef(const T *pixels, int width, int height, YAxisOrientation yOrientation = MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION) : pixels(pixels), width(width), height(height), yOrientation(yOrientation) { }
|
||||||
inline BitmapConstRef(const BitmapRef<T, N> &orig) : pixels(orig.pixels), width(orig.width), height(orig.height) { }
|
inline BitmapConstRef(const BitmapRef<T, N> &orig) : pixels(orig.pixels), width(orig.width), height(orig.height), yOrientation(orig.yOrientation) { }
|
||||||
|
|
||||||
inline const T *operator()(int x, int y) const {
|
inline const T *operator()(int x, int y) const {
|
||||||
return pixels+N*(width*y+x);
|
return pixels+N*(width*y+x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a constant reference to a rectangular section of the bitmap specified by bounds (excluding xMax, yMax).
|
||||||
|
inline BitmapConstSection<T, N> getSection(int xMin, int yMin, int xMax, int yMax) const {
|
||||||
|
return BitmapConstSection<T, N>(pixels+N*(width*yMin+xMin), xMax-xMin, yMax-yMin, N*width, yOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a constant reference to a rectangular section of the bitmap specified by bounds (excluding xMax, yMax).
|
||||||
|
inline BitmapConstSection<T, N> getConstSection(int xMin, int yMin, int xMax, int yMax) const {
|
||||||
|
return getSection(xMin, yMin, xMax, yMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, int N>
|
||||||
|
struct BitmapSection {
|
||||||
|
|
||||||
|
T *pixels;
|
||||||
|
int width, height;
|
||||||
|
/// Specifies the difference between the beginnings of adjacent pixel rows as the number of T elements, can be negative.
|
||||||
|
int rowStride;
|
||||||
|
YAxisOrientation yOrientation;
|
||||||
|
|
||||||
|
inline BitmapSection() : pixels(NULL), width(0), height(0), rowStride(0), yOrientation(MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION) { }
|
||||||
|
inline BitmapSection(T *pixels, int width, int height, YAxisOrientation yOrientation = MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION) : pixels(pixels), width(width), height(height), rowStride(N*width), yOrientation(yOrientation) { }
|
||||||
|
inline BitmapSection(T *pixels, int width, int height, int rowStride, YAxisOrientation yOrientation = MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION) : pixels(pixels), width(width), height(height), rowStride(rowStride), yOrientation(yOrientation) { }
|
||||||
|
inline BitmapSection(const BitmapRef<T, N> &orig) : pixels(orig.pixels), width(orig.width), height(orig.height), rowStride(N*orig.width), yOrientation(orig.yOrientation) { }
|
||||||
|
|
||||||
|
inline T *operator()(int x, int y) const {
|
||||||
|
return pixels+rowStride*y+N*x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to a rectangular subsection of the bitmap specified by bounds (excluding xMax, yMax).
|
||||||
|
inline BitmapSection<T, N> getSection(int xMin, int yMin, int xMax, int yMax) const {
|
||||||
|
return BitmapSection<T, N>(pixels+rowStride*yMin+N*xMin, xMax-xMin, yMax-yMin, rowStride, yOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a constant reference to a rectangular subsection of the bitmap specified by bounds (excluding xMax, yMax).
|
||||||
|
inline BitmapConstSection<T, N> getConstSection(int xMin, int yMin, int xMax, int yMax) const {
|
||||||
|
return BitmapConstSection<T, N>(pixels+rowStride*yMin+N*xMin, xMax-xMin, yMax-yMin, rowStride, yOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Makes sure that the section's Y-axis orientation matches the argument by potentially reordering its rows.
|
||||||
|
inline void reorient(YAxisOrientation newYAxisOrientation) {
|
||||||
|
if (yOrientation != newYAxisOrientation) {
|
||||||
|
pixels += rowStride*(height-1);
|
||||||
|
rowStride = -rowStride;
|
||||||
|
yOrientation = newYAxisOrientation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, int N>
|
||||||
|
struct BitmapConstSection {
|
||||||
|
|
||||||
|
const T *pixels;
|
||||||
|
int width, height;
|
||||||
|
/// Specifies the difference between the beginnings of adjacent pixel rows as the number of T elements, can be negative.
|
||||||
|
int rowStride;
|
||||||
|
YAxisOrientation yOrientation;
|
||||||
|
|
||||||
|
inline BitmapConstSection() : pixels(NULL), width(0), height(0), rowStride(0), yOrientation(MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION) { }
|
||||||
|
inline BitmapConstSection(const T *pixels, int width, int height, YAxisOrientation yOrientation = MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION) : pixels(pixels), width(width), height(height), rowStride(N*width), yOrientation(yOrientation) { }
|
||||||
|
inline BitmapConstSection(const T *pixels, int width, int height, int rowStride, YAxisOrientation yOrientation = MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION) : pixels(pixels), width(width), height(height), rowStride(rowStride), yOrientation(yOrientation) { }
|
||||||
|
inline BitmapConstSection(const BitmapRef<T, N> &orig) : pixels(orig.pixels), width(orig.width), height(orig.height), rowStride(N*orig.width), yOrientation(orig.yOrientation) { }
|
||||||
|
inline BitmapConstSection(const BitmapConstRef<T, N> &orig) : pixels(orig.pixels), width(orig.width), height(orig.height), rowStride(N*orig.width), yOrientation(orig.yOrientation) { }
|
||||||
|
inline BitmapConstSection(const BitmapSection<T, N> &orig) : pixels(orig.pixels), width(orig.width), height(orig.height), rowStride(orig.rowStride), yOrientation(orig.yOrientation) { }
|
||||||
|
|
||||||
|
inline const T *operator()(int x, int y) const {
|
||||||
|
return pixels+rowStride*y+N*x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a constant reference to a rectangular subsection of the bitmap specified by bounds (excluding xMax, yMax).
|
||||||
|
inline BitmapConstSection<T, N> getSection(int xMin, int yMin, int xMax, int yMax) const {
|
||||||
|
return BitmapConstSection<T, N>(pixels+rowStride*yMin+N*xMin, xMax-xMin, yMax-yMin, rowStride, yOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a constant reference to a rectangular subsection of the bitmap specified by bounds (excluding xMax, yMax).
|
||||||
|
inline BitmapConstSection<T, N> getConstSection(int xMin, int yMin, int xMax, int yMax) const {
|
||||||
|
return getSection(xMin, yMin, xMax, yMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Makes sure that the section's Y-axis orientation matches the argument by potentially reordering its rows.
|
||||||
|
inline void reorient(YAxisOrientation newYAxisOrientation) {
|
||||||
|
if (yOrientation != newYAxisOrientation) {
|
||||||
|
pixels += rowStride*(height-1);
|
||||||
|
rowStride = -rowStride;
|
||||||
|
yOrientation = newYAxisOrientation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
18
thirdparty/msdfgen/core/Contour.cpp
vendored
18
thirdparty/msdfgen/core/Contour.cpp
vendored
@@ -24,19 +24,19 @@ EdgeHolder &Contour::addEdge() {
|
|||||||
return edges.back();
|
return edges.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void boundPoint(double &l, double &b, double &r, double &t, Point2 p) {
|
static void boundPoint(double &xMin, double &yMin, double &xMax, double &yMax, Point2 p) {
|
||||||
if (p.x < l) l = p.x;
|
if (p.x < xMin) xMin = p.x;
|
||||||
if (p.y < b) b = p.y;
|
if (p.y < yMin) yMin = p.y;
|
||||||
if (p.x > r) r = p.x;
|
if (p.x > xMax) xMax = p.x;
|
||||||
if (p.y > t) t = p.y;
|
if (p.y > yMax) yMax = p.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Contour::bound(double &l, double &b, double &r, double &t) const {
|
void Contour::bound(double &xMin, double &yMin, double &xMax, double &yMax) const {
|
||||||
for (std::vector<EdgeHolder>::const_iterator edge = edges.begin(); edge != edges.end(); ++edge)
|
for (std::vector<EdgeHolder>::const_iterator edge = edges.begin(); edge != edges.end(); ++edge)
|
||||||
(*edge)->bound(l, b, r, t);
|
(*edge)->bound(xMin, yMin, xMax, yMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Contour::boundMiters(double &l, double &b, double &r, double &t, double border, double miterLimit, int polarity) const {
|
void Contour::boundMiters(double &xMin, double &yMin, double &xMax, double &yMax, double border, double miterLimit, int polarity) const {
|
||||||
if (edges.empty())
|
if (edges.empty())
|
||||||
return;
|
return;
|
||||||
Vector2 prevDir = edges.back()->direction(1).normalize(true);
|
Vector2 prevDir = edges.back()->direction(1).normalize(true);
|
||||||
@@ -48,7 +48,7 @@ void Contour::boundMiters(double &l, double &b, double &r, double &t, double bor
|
|||||||
if (q > 0)
|
if (q > 0)
|
||||||
miterLength = min(1/sqrt(q), miterLimit);
|
miterLength = min(1/sqrt(q), miterLimit);
|
||||||
Point2 miter = (*edge)->point(0)+border*miterLength*(prevDir+dir).normalize(true);
|
Point2 miter = (*edge)->point(0)+border*miterLength*(prevDir+dir).normalize(true);
|
||||||
boundPoint(l, b, r, t, miter);
|
boundPoint(xMin, yMin, xMax, yMax, miter);
|
||||||
}
|
}
|
||||||
prevDir = (*edge)->direction(1).normalize(true);
|
prevDir = (*edge)->direction(1).normalize(true);
|
||||||
}
|
}
|
||||||
|
|||||||
4
thirdparty/msdfgen/core/Contour.h
vendored
4
thirdparty/msdfgen/core/Contour.h
vendored
@@ -21,9 +21,9 @@ public:
|
|||||||
/// Creates a new edge in the contour and returns its reference.
|
/// Creates a new edge in the contour and returns its reference.
|
||||||
EdgeHolder &addEdge();
|
EdgeHolder &addEdge();
|
||||||
/// Adjusts the bounding box to fit the contour.
|
/// Adjusts the bounding box to fit the contour.
|
||||||
void bound(double &l, double &b, double &r, double &t) const;
|
void bound(double &xMin, double &yMin, double &xMax, double &yMax) const;
|
||||||
/// Adjusts the bounding box to fit the contour border's mitered corners.
|
/// Adjusts the bounding box to fit the contour border's mitered corners.
|
||||||
void boundMiters(double &l, double &b, double &r, double &t, double border, double miterLimit, int polarity) const;
|
void boundMiters(double &xMin, double &yMin, double &xMax, double &yMax, double border, double miterLimit, int polarity) const;
|
||||||
/// Computes the winding of the contour. Returns 1 if positive, -1 if negative.
|
/// Computes the winding of the contour. Returns 1 if positive, -1 if negative.
|
||||||
int winding() const;
|
int winding() const;
|
||||||
/// Reverses the sequence of edges on the contour.
|
/// Reverses the sequence of edges on the contour.
|
||||||
|
|||||||
126
thirdparty/msdfgen/core/MSDFErrorCorrection.cpp
vendored
126
thirdparty/msdfgen/core/MSDFErrorCorrection.cpp
vendored
@@ -87,17 +87,15 @@ public:
|
|||||||
Point2 shapeCoord, sdfCoord;
|
Point2 shapeCoord, sdfCoord;
|
||||||
const float *msd;
|
const float *msd;
|
||||||
bool protectedFlag;
|
bool protectedFlag;
|
||||||
inline ShapeDistanceChecker(const BitmapConstRef<float, N> &sdf, const Shape &shape, const Projection &projection, DistanceMapping distanceMapping, double minImproveRatio) : distanceFinder(shape), sdf(sdf), distanceMapping(distanceMapping), minImproveRatio(minImproveRatio) {
|
inline ShapeDistanceChecker(const BitmapConstSection<float, N> &sdf, const Shape &shape, const Projection &projection, DistanceMapping distanceMapping, double minImproveRatio) : distanceFinder(shape), sdf(sdf), distanceMapping(distanceMapping), minImproveRatio(minImproveRatio) {
|
||||||
texelSize = projection.unprojectVector(Vector2(1));
|
texelSize = projection.unprojectVector(Vector2(1));
|
||||||
if (shape.inverseYAxis)
|
|
||||||
texelSize.y = -texelSize.y;
|
|
||||||
}
|
}
|
||||||
inline ArtifactClassifier classifier(const Vector2 &direction, double span) {
|
inline ArtifactClassifier classifier(const Vector2 &direction, double span) {
|
||||||
return ArtifactClassifier(this, direction, span);
|
return ArtifactClassifier(this, direction, span);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
ShapeDistanceFinder<ContourCombiner<PerpendicularDistanceSelector> > distanceFinder;
|
ShapeDistanceFinder<ContourCombiner<PerpendicularDistanceSelector> > distanceFinder;
|
||||||
BitmapConstRef<float, N> sdf;
|
BitmapConstSection<float, N> sdf;
|
||||||
DistanceMapping distanceMapping;
|
DistanceMapping distanceMapping;
|
||||||
Vector2 texelSize;
|
Vector2 texelSize;
|
||||||
double minImproveRatio;
|
double minImproveRatio;
|
||||||
@@ -105,10 +103,11 @@ private:
|
|||||||
|
|
||||||
MSDFErrorCorrection::MSDFErrorCorrection() { }
|
MSDFErrorCorrection::MSDFErrorCorrection() { }
|
||||||
|
|
||||||
MSDFErrorCorrection::MSDFErrorCorrection(const BitmapRef<byte, 1> &stencil, const SDFTransformation &transformation) : stencil(stencil), transformation(transformation) {
|
MSDFErrorCorrection::MSDFErrorCorrection(const BitmapSection<byte, 1> &stencil, const SDFTransformation &transformation) : stencil(stencil), transformation(transformation) {
|
||||||
minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio;
|
minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio;
|
||||||
minImproveRatio = ErrorCorrectionConfig::defaultMinImproveRatio;
|
minImproveRatio = ErrorCorrectionConfig::defaultMinImproveRatio;
|
||||||
memset(stencil.pixels, 0, sizeof(byte)*stencil.width*stencil.height);
|
for (int y = 0; y < stencil.height; ++y)
|
||||||
|
memset(stencil(0, y), 0, sizeof(byte)*stencil.width);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MSDFErrorCorrection::setMinDeviationRatio(double minDeviationRatio) {
|
void MSDFErrorCorrection::setMinDeviationRatio(double minDeviationRatio) {
|
||||||
@@ -120,6 +119,7 @@ void MSDFErrorCorrection::setMinImproveRatio(double minImproveRatio) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MSDFErrorCorrection::protectCorners(const Shape &shape) {
|
void MSDFErrorCorrection::protectCorners(const Shape &shape) {
|
||||||
|
stencil.reorient(shape.getYAxisOrientation());
|
||||||
for (std::vector<Contour>::const_iterator contour = shape.contours.begin(); contour != shape.contours.end(); ++contour)
|
for (std::vector<Contour>::const_iterator contour = shape.contours.begin(); contour != shape.contours.end(); ++contour)
|
||||||
if (!contour->edges.empty()) {
|
if (!contour->edges.empty()) {
|
||||||
const EdgeSegment *prevEdge = contour->edges.back();
|
const EdgeSegment *prevEdge = contour->edges.back();
|
||||||
@@ -131,8 +131,6 @@ void MSDFErrorCorrection::protectCorners(const Shape &shape) {
|
|||||||
Point2 p = transformation.project((*edge)->point(0));
|
Point2 p = transformation.project((*edge)->point(0));
|
||||||
int l = (int) floor(p.x-.5);
|
int l = (int) floor(p.x-.5);
|
||||||
int b = (int) floor(p.y-.5);
|
int b = (int) floor(p.y-.5);
|
||||||
if (shape.inverseYAxis)
|
|
||||||
b = stencil.height-b-2;
|
|
||||||
int r = l+1;
|
int r = l+1;
|
||||||
int t = b+1;
|
int t = b+1;
|
||||||
// Check that the positions are within bounds.
|
// Check that the positions are within bounds.
|
||||||
@@ -189,8 +187,9 @@ static void protectExtremeChannels(byte *stencil, const float *msd, float m, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
void MSDFErrorCorrection::protectEdges(const BitmapConstRef<float, N> &sdf) {
|
void MSDFErrorCorrection::protectEdges(const BitmapConstSection<float, N> &sdf) {
|
||||||
float radius;
|
float radius;
|
||||||
|
stencil.reorient(sdf.yOrientation);
|
||||||
// Horizontal texel pairs
|
// Horizontal texel pairs
|
||||||
radius = float(PROTECTION_RADIUS_TOLERANCE*transformation.unprojectVector(Vector2(transformation.distanceMapping(DistanceMapping::Delta(1)), 0)).length());
|
radius = float(PROTECTION_RADIUS_TOLERANCE*transformation.unprojectVector(Vector2(transformation.distanceMapping(DistanceMapping::Delta(1)), 0)).length());
|
||||||
for (int y = 0; y < sdf.height; ++y) {
|
for (int y = 0; y < sdf.height; ++y) {
|
||||||
@@ -251,9 +250,11 @@ void MSDFErrorCorrection::protectEdges(const BitmapConstRef<float, N> &sdf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MSDFErrorCorrection::protectAll() {
|
void MSDFErrorCorrection::protectAll() {
|
||||||
byte *end = stencil.pixels+stencil.width*stencil.height;
|
for (int y = 0; y < stencil.height; ++y) {
|
||||||
for (byte *mask = stencil.pixels; mask < end; ++mask)
|
byte *mask = stencil(0, y);
|
||||||
*mask |= (byte) PROTECTED;
|
for (int x = 0; x < stencil.width; ++x)
|
||||||
|
*mask++ |= (byte) PROTECTED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the median of the linear interpolation of texels a, b at t.
|
/// Returns the median of the linear interpolation of texels a, b at t.
|
||||||
@@ -273,16 +274,6 @@ static float interpolatedMedian(const float *a, const float *l, const float *q,
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines if the interpolated median xm is an artifact.
|
|
||||||
static bool isArtifact(bool isProtected, double axSpan, double bxSpan, float am, float bm, float xm) {
|
|
||||||
return (
|
|
||||||
// For protected texels, only report an artifact if it would cause fill inversion (change between positive and negative distance).
|
|
||||||
(!isProtected || (am > .5f && bm > .5f && xm <= .5f) || (am < .5f && bm < .5f && xm >= .5f)) &&
|
|
||||||
// This is an artifact if the interpolated median is outside the range of possible values based on its distance from a, b.
|
|
||||||
!(xm >= am-axSpan && xm <= am+axSpan && xm >= bm-bxSpan && xm <= bm+bxSpan)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks if a linear interpolation artifact will occur at a point where two specific color channels are equal - such points have extreme median values.
|
/// Checks if a linear interpolation artifact will occur at a point where two specific color channels are equal - such points have extreme median values.
|
||||||
template <class ArtifactClassifier>
|
template <class ArtifactClassifier>
|
||||||
static bool hasLinearArtifactInner(const ArtifactClassifier &artifactClassifier, float am, float bm, const float *a, const float *b, float dA, float dB) {
|
static bool hasLinearArtifactInner(const ArtifactClassifier &artifactClassifier, float am, float bm, const float *a, const float *b, float dA, float dB) {
|
||||||
@@ -390,7 +381,8 @@ static bool hasDiagonalArtifact(const ArtifactClassifier &artifactClassifier, fl
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
void MSDFErrorCorrection::findErrors(const BitmapConstRef<float, N> &sdf) {
|
void MSDFErrorCorrection::findErrors(const BitmapConstSection<float, N> &sdf) {
|
||||||
|
stencil.reorient(sdf.yOrientation);
|
||||||
// Compute the expected deltas between values of horizontally, vertically, and diagonally adjacent texels.
|
// Compute the expected deltas between values of horizontally, vertically, and diagonally adjacent texels.
|
||||||
double hSpan = minDeviationRatio*transformation.unprojectVector(Vector2(transformation.distanceMapping(DistanceMapping::Delta(1)), 0)).length();
|
double hSpan = minDeviationRatio*transformation.unprojectVector(Vector2(transformation.distanceMapping(DistanceMapping::Delta(1)), 0)).length();
|
||||||
double vSpan = minDeviationRatio*transformation.unprojectVector(Vector2(0, transformation.distanceMapping(DistanceMapping::Delta(1)))).length();
|
double vSpan = minDeviationRatio*transformation.unprojectVector(Vector2(0, transformation.distanceMapping(DistanceMapping::Delta(1)))).length();
|
||||||
@@ -418,7 +410,9 @@ void MSDFErrorCorrection::findErrors(const BitmapConstRef<float, N> &sdf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <template <typename> class ContourCombiner, int N>
|
template <template <typename> class ContourCombiner, int N>
|
||||||
void MSDFErrorCorrection::findErrors(const BitmapConstRef<float, N> &sdf, const Shape &shape) {
|
void MSDFErrorCorrection::findErrors(BitmapConstSection<float, N> sdf, const Shape &shape) {
|
||||||
|
sdf.reorient(shape.getYAxisOrientation());
|
||||||
|
stencil.reorient(sdf.yOrientation);
|
||||||
// Compute the expected deltas between values of horizontally, vertically, and diagonally adjacent texels.
|
// Compute the expected deltas between values of horizontally, vertically, and diagonally adjacent texels.
|
||||||
double hSpan = minDeviationRatio*transformation.unprojectVector(Vector2(transformation.distanceMapping(DistanceMapping::Delta(1)), 0)).length();
|
double hSpan = minDeviationRatio*transformation.unprojectVector(Vector2(transformation.distanceMapping(DistanceMapping::Delta(1)), 0)).length();
|
||||||
double vSpan = minDeviationRatio*transformation.unprojectVector(Vector2(0, transformation.distanceMapping(DistanceMapping::Delta(1)))).length();
|
double vSpan = minDeviationRatio*transformation.unprojectVector(Vector2(0, transformation.distanceMapping(DistanceMapping::Delta(1)))).length();
|
||||||
@@ -428,69 +422,75 @@ void MSDFErrorCorrection::findErrors(const BitmapConstRef<float, N> &sdf, const
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ShapeDistanceChecker<ContourCombiner, N> shapeDistanceChecker(sdf, shape, transformation, transformation.distanceMapping, minImproveRatio);
|
ShapeDistanceChecker<ContourCombiner, N> shapeDistanceChecker(sdf, shape, transformation, transformation.distanceMapping, minImproveRatio);
|
||||||
bool rightToLeft = false;
|
int xDirection = 1;
|
||||||
// Inspect all texels.
|
// Inspect all texels.
|
||||||
#ifdef MSDFGEN_USE_OPENMP
|
#ifdef MSDFGEN_USE_OPENMP
|
||||||
#pragma omp for
|
#pragma omp for
|
||||||
#endif
|
#endif
|
||||||
for (int y = 0; y < sdf.height; ++y) {
|
for (int y = 0; y < sdf.height; ++y) {
|
||||||
int row = shape.inverseYAxis ? sdf.height-y-1 : y;
|
int x = xDirection < 0 ? sdf.width-1 : 0;
|
||||||
for (int col = 0; col < sdf.width; ++col) {
|
for (int col = 0; col < sdf.width; ++col, x += xDirection) {
|
||||||
int x = rightToLeft ? sdf.width-col-1 : col;
|
if ((*stencil(x, y)&ERROR))
|
||||||
if ((*stencil(x, row)&ERROR))
|
|
||||||
continue;
|
continue;
|
||||||
const float *c = sdf(x, row);
|
const float *c = sdf(x, y);
|
||||||
shapeDistanceChecker.shapeCoord = transformation.unproject(Point2(x+.5, y+.5));
|
shapeDistanceChecker.shapeCoord = transformation.unproject(Point2(x+.5, y+.5));
|
||||||
shapeDistanceChecker.sdfCoord = Point2(x+.5, row+.5);
|
shapeDistanceChecker.sdfCoord = Point2(x+.5, y+.5);
|
||||||
shapeDistanceChecker.msd = c;
|
shapeDistanceChecker.msd = c;
|
||||||
shapeDistanceChecker.protectedFlag = (*stencil(x, row)&PROTECTED) != 0;
|
shapeDistanceChecker.protectedFlag = (*stencil(x, y)&PROTECTED) != 0;
|
||||||
float cm = median(c[0], c[1], c[2]);
|
float cm = median(c[0], c[1], c[2]);
|
||||||
const float *l = NULL, *b = NULL, *r = NULL, *t = NULL;
|
const float *l = NULL, *b = NULL, *r = NULL, *t = NULL;
|
||||||
// Mark current texel c with the error flag if an artifact occurs when it's interpolated with any of its 8 neighbors.
|
// Mark current texel c with the error flag if an artifact occurs when it's interpolated with any of its 8 neighbors.
|
||||||
*stencil(x, row) |= (byte) (ERROR*(
|
*stencil(x, y) |= (byte) (ERROR*(
|
||||||
(x > 0 && ((l = sdf(x-1, row)), hasLinearArtifact(shapeDistanceChecker.classifier(Vector2(-1, 0), hSpan), cm, c, l))) ||
|
(x > 0 && ((l = sdf(x-1, y)), hasLinearArtifact(shapeDistanceChecker.classifier(Vector2(-1, 0), hSpan), cm, c, l))) ||
|
||||||
(row > 0 && ((b = sdf(x, row-1)), hasLinearArtifact(shapeDistanceChecker.classifier(Vector2(0, -1), vSpan), cm, c, b))) ||
|
(y > 0 && ((b = sdf(x, y-1)), hasLinearArtifact(shapeDistanceChecker.classifier(Vector2(0, -1), vSpan), cm, c, b))) ||
|
||||||
(x < sdf.width-1 && ((r = sdf(x+1, row)), hasLinearArtifact(shapeDistanceChecker.classifier(Vector2(+1, 0), hSpan), cm, c, r))) ||
|
(x < sdf.width-1 && ((r = sdf(x+1, y)), hasLinearArtifact(shapeDistanceChecker.classifier(Vector2(+1, 0), hSpan), cm, c, r))) ||
|
||||||
(row < sdf.height-1 && ((t = sdf(x, row+1)), hasLinearArtifact(shapeDistanceChecker.classifier(Vector2(0, +1), vSpan), cm, c, t))) ||
|
(y < sdf.height-1 && ((t = sdf(x, y+1)), hasLinearArtifact(shapeDistanceChecker.classifier(Vector2(0, +1), vSpan), cm, c, t))) ||
|
||||||
(x > 0 && row > 0 && hasDiagonalArtifact(shapeDistanceChecker.classifier(Vector2(-1, -1), dSpan), cm, c, l, b, sdf(x-1, row-1))) ||
|
(x > 0 && y > 0 && hasDiagonalArtifact(shapeDistanceChecker.classifier(Vector2(-1, -1), dSpan), cm, c, l, b, sdf(x-1, y-1))) ||
|
||||||
(x < sdf.width-1 && row > 0 && hasDiagonalArtifact(shapeDistanceChecker.classifier(Vector2(+1, -1), dSpan), cm, c, r, b, sdf(x+1, row-1))) ||
|
(x < sdf.width-1 && y > 0 && hasDiagonalArtifact(shapeDistanceChecker.classifier(Vector2(+1, -1), dSpan), cm, c, r, b, sdf(x+1, y-1))) ||
|
||||||
(x > 0 && row < sdf.height-1 && hasDiagonalArtifact(shapeDistanceChecker.classifier(Vector2(-1, +1), dSpan), cm, c, l, t, sdf(x-1, row+1))) ||
|
(x > 0 && y < sdf.height-1 && hasDiagonalArtifact(shapeDistanceChecker.classifier(Vector2(-1, +1), dSpan), cm, c, l, t, sdf(x-1, y+1))) ||
|
||||||
(x < sdf.width-1 && row < sdf.height-1 && hasDiagonalArtifact(shapeDistanceChecker.classifier(Vector2(+1, +1), dSpan), cm, c, r, t, sdf(x+1, row+1)))
|
(x < sdf.width-1 && y < sdf.height-1 && hasDiagonalArtifact(shapeDistanceChecker.classifier(Vector2(+1, +1), dSpan), cm, c, r, t, sdf(x+1, y+1)))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
xDirection = -xDirection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
void MSDFErrorCorrection::apply(const BitmapRef<float, N> &sdf) const {
|
void MSDFErrorCorrection::apply(BitmapSection<float, N> sdf) const {
|
||||||
int texelCount = sdf.width*sdf.height;
|
sdf.reorient(stencil.yOrientation);
|
||||||
const byte *mask = stencil.pixels;
|
const byte *stencilRow = stencil.pixels;
|
||||||
float *texel = sdf.pixels;
|
float *rowStart = sdf.pixels;
|
||||||
for (int i = 0; i < texelCount; ++i) {
|
for (int y = 0; y < sdf.height; ++y) {
|
||||||
if (*mask&ERROR) {
|
const byte *mask = stencilRow;
|
||||||
// Set all color channels to the median.
|
float *pixel = rowStart;
|
||||||
float m = median(texel[0], texel[1], texel[2]);
|
for (int x = 0; x < sdf.width; ++x) {
|
||||||
texel[0] = m, texel[1] = m, texel[2] = m;
|
if (*mask&ERROR) {
|
||||||
|
// Set all color channels to the median.
|
||||||
|
float m = median(pixel[0], pixel[1], pixel[2]);
|
||||||
|
pixel[0] = m, pixel[1] = m, pixel[2] = m;
|
||||||
|
}
|
||||||
|
++mask;
|
||||||
|
pixel += N;
|
||||||
}
|
}
|
||||||
++mask;
|
stencilRow += stencil.rowStride;
|
||||||
texel += N;
|
rowStart += sdf.rowStride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BitmapConstRef<byte, 1> MSDFErrorCorrection::getStencil() const {
|
BitmapConstSection<byte, 1> MSDFErrorCorrection::getStencil() const {
|
||||||
return stencil;
|
return stencil;
|
||||||
}
|
}
|
||||||
|
|
||||||
template void MSDFErrorCorrection::protectEdges(const BitmapConstRef<float, 3> &sdf);
|
template void MSDFErrorCorrection::protectEdges(const BitmapConstSection<float, 3> &sdf);
|
||||||
template void MSDFErrorCorrection::protectEdges(const BitmapConstRef<float, 4> &sdf);
|
template void MSDFErrorCorrection::protectEdges(const BitmapConstSection<float, 4> &sdf);
|
||||||
template void MSDFErrorCorrection::findErrors(const BitmapConstRef<float, 3> &sdf);
|
template void MSDFErrorCorrection::findErrors(const BitmapConstSection<float, 3> &sdf);
|
||||||
template void MSDFErrorCorrection::findErrors(const BitmapConstRef<float, 4> &sdf);
|
template void MSDFErrorCorrection::findErrors(const BitmapConstSection<float, 4> &sdf);
|
||||||
template void MSDFErrorCorrection::findErrors<SimpleContourCombiner>(const BitmapConstRef<float, 3> &sdf, const Shape &shape);
|
template void MSDFErrorCorrection::findErrors<SimpleContourCombiner>(BitmapConstSection<float, 3> sdf, const Shape &shape);
|
||||||
template void MSDFErrorCorrection::findErrors<SimpleContourCombiner>(const BitmapConstRef<float, 4> &sdf, const Shape &shape);
|
template void MSDFErrorCorrection::findErrors<SimpleContourCombiner>(BitmapConstSection<float, 4> sdf, const Shape &shape);
|
||||||
template void MSDFErrorCorrection::findErrors<OverlappingContourCombiner>(const BitmapConstRef<float, 3> &sdf, const Shape &shape);
|
template void MSDFErrorCorrection::findErrors<OverlappingContourCombiner>(BitmapConstSection<float, 3> sdf, const Shape &shape);
|
||||||
template void MSDFErrorCorrection::findErrors<OverlappingContourCombiner>(const BitmapConstRef<float, 4> &sdf, const Shape &shape);
|
template void MSDFErrorCorrection::findErrors<OverlappingContourCombiner>(BitmapConstSection<float, 4> sdf, const Shape &shape);
|
||||||
template void MSDFErrorCorrection::apply(const BitmapRef<float, 3> &sdf) const;
|
template void MSDFErrorCorrection::apply(BitmapSection<float, 3> sdf) const;
|
||||||
template void MSDFErrorCorrection::apply(const BitmapRef<float, 4> &sdf) const;
|
template void MSDFErrorCorrection::apply(BitmapSection<float, 4> sdf) const;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
14
thirdparty/msdfgen/core/MSDFErrorCorrection.h
vendored
14
thirdparty/msdfgen/core/MSDFErrorCorrection.h
vendored
@@ -20,7 +20,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
MSDFErrorCorrection();
|
MSDFErrorCorrection();
|
||||||
explicit MSDFErrorCorrection(const BitmapRef<byte, 1> &stencil, const SDFTransformation &transformation);
|
explicit MSDFErrorCorrection(const BitmapSection<byte, 1> &stencil, const SDFTransformation &transformation);
|
||||||
/// Sets the minimum ratio between the actual and maximum expected distance delta to be considered an error.
|
/// Sets the minimum ratio between the actual and maximum expected distance delta to be considered an error.
|
||||||
void setMinDeviationRatio(double minDeviationRatio);
|
void setMinDeviationRatio(double minDeviationRatio);
|
||||||
/// Sets the minimum ratio between the pre-correction distance error and the post-correction distance error.
|
/// Sets the minimum ratio between the pre-correction distance error and the post-correction distance error.
|
||||||
@@ -29,23 +29,23 @@ public:
|
|||||||
void protectCorners(const Shape &shape);
|
void protectCorners(const Shape &shape);
|
||||||
/// Flags all texels that contribute to edges as protected.
|
/// Flags all texels that contribute to edges as protected.
|
||||||
template <int N>
|
template <int N>
|
||||||
void protectEdges(const BitmapConstRef<float, N> &sdf);
|
void protectEdges(const BitmapConstSection<float, N> &sdf);
|
||||||
/// Flags all texels as protected.
|
/// Flags all texels as protected.
|
||||||
void protectAll();
|
void protectAll();
|
||||||
/// Flags texels that are expected to cause interpolation artifacts based on analysis of the SDF only.
|
/// Flags texels that are expected to cause interpolation artifacts based on analysis of the SDF only.
|
||||||
template <int N>
|
template <int N>
|
||||||
void findErrors(const BitmapConstRef<float, N> &sdf);
|
void findErrors(const BitmapConstSection<float, N> &sdf);
|
||||||
/// Flags texels that are expected to cause interpolation artifacts based on analysis of the SDF and comparison with the exact shape distance.
|
/// Flags texels that are expected to cause interpolation artifacts based on analysis of the SDF and comparison with the exact shape distance.
|
||||||
template <template <typename> class ContourCombiner, int N>
|
template <template <typename> class ContourCombiner, int N>
|
||||||
void findErrors(const BitmapConstRef<float, N> &sdf, const Shape &shape);
|
void findErrors(BitmapConstSection<float, N> sdf, const Shape &shape);
|
||||||
/// Modifies the MSDF so that all texels with the error flag are converted to single-channel.
|
/// Modifies the MSDF so that all texels with the error flag are converted to single-channel.
|
||||||
template <int N>
|
template <int N>
|
||||||
void apply(const BitmapRef<float, N> &sdf) const;
|
void apply(BitmapSection<float, N> sdf) const;
|
||||||
/// Returns the stencil in its current state (see Flags).
|
/// Returns the stencil in its current state (see Flags).
|
||||||
BitmapConstRef<byte, 1> getStencil() const;
|
BitmapConstSection<byte, 1> getStencil() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BitmapRef<byte, 1> stencil;
|
BitmapSection<byte, 1> stencil;
|
||||||
SDFTransformation transformation;
|
SDFTransformation transformation;
|
||||||
double minDeviationRatio;
|
double minDeviationRatio;
|
||||||
double minImproveRatio;
|
double minImproveRatio;
|
||||||
|
|||||||
22
thirdparty/msdfgen/core/Shape.cpp
vendored
22
thirdparty/msdfgen/core/Shape.cpp
vendored
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include "arithmetics.hpp"
|
#include "arithmetics.hpp"
|
||||||
|
#include "convergent-curve-ordering.h"
|
||||||
|
|
||||||
#define DECONVERGE_OVERSHOOT 1.11111111111111111 // moves control points slightly more than necessary to account for floating-point errors
|
#define DECONVERGE_OVERSHOOT 1.11111111111111111 // moves control points slightly more than necessary to account for floating-point errors
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ void Shape::normalize() {
|
|||||||
contour->edges.push_back(EdgeHolder(parts[0]));
|
contour->edges.push_back(EdgeHolder(parts[0]));
|
||||||
contour->edges.push_back(EdgeHolder(parts[1]));
|
contour->edges.push_back(EdgeHolder(parts[1]));
|
||||||
contour->edges.push_back(EdgeHolder(parts[2]));
|
contour->edges.push_back(EdgeHolder(parts[2]));
|
||||||
} else {
|
} else if (!contour->edges.empty()) {
|
||||||
// Push apart convergent edge segments
|
// Push apart convergent edge segments
|
||||||
EdgeHolder *prevEdge = &contour->edges.back();
|
EdgeHolder *prevEdge = &contour->edges.back();
|
||||||
for (std::vector<EdgeHolder>::iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) {
|
for (std::vector<EdgeHolder>::iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) {
|
||||||
@@ -79,8 +80,7 @@ void Shape::normalize() {
|
|||||||
if (dotProduct(prevDir, curDir) < MSDFGEN_CORNER_DOT_EPSILON-1) {
|
if (dotProduct(prevDir, curDir) < MSDFGEN_CORNER_DOT_EPSILON-1) {
|
||||||
double factor = DECONVERGE_OVERSHOOT*sqrt(1-(MSDFGEN_CORNER_DOT_EPSILON-1)*(MSDFGEN_CORNER_DOT_EPSILON-1))/(MSDFGEN_CORNER_DOT_EPSILON-1);
|
double factor = DECONVERGE_OVERSHOOT*sqrt(1-(MSDFGEN_CORNER_DOT_EPSILON-1)*(MSDFGEN_CORNER_DOT_EPSILON-1))/(MSDFGEN_CORNER_DOT_EPSILON-1);
|
||||||
Vector2 axis = factor*(curDir-prevDir).normalize();
|
Vector2 axis = factor*(curDir-prevDir).normalize();
|
||||||
// Determine curve ordering using third-order derivative (t = 0) of crossProduct((*prevEdge)->point(1-t)-p0, (*edge)->point(t)-p0) where p0 is the corner (*edge)->point(0)
|
if (convergentCurveOrdering(*prevEdge, *edge) < 0)
|
||||||
if (crossProduct((*prevEdge)->directionChange(1), (*edge)->direction(0))+crossProduct((*edge)->directionChange(0), (*prevEdge)->direction(1)) < 0)
|
|
||||||
axis = -axis;
|
axis = -axis;
|
||||||
deconvergeEdge(*prevEdge, 1, axis.getOrthogonal(true));
|
deconvergeEdge(*prevEdge, 1, axis.getOrthogonal(true));
|
||||||
deconvergeEdge(*edge, 0, axis.getOrthogonal(false));
|
deconvergeEdge(*edge, 0, axis.getOrthogonal(false));
|
||||||
@@ -91,14 +91,14 @@ void Shape::normalize() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shape::bound(double &l, double &b, double &r, double &t) const {
|
void Shape::bound(double &xMin, double &yMin, double &xMax, double &yMax) const {
|
||||||
for (std::vector<Contour>::const_iterator contour = contours.begin(); contour != contours.end(); ++contour)
|
for (std::vector<Contour>::const_iterator contour = contours.begin(); contour != contours.end(); ++contour)
|
||||||
contour->bound(l, b, r, t);
|
contour->bound(xMin, yMin, xMax, yMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shape::boundMiters(double &l, double &b, double &r, double &t, double border, double miterLimit, int polarity) const {
|
void Shape::boundMiters(double &xMin, double &yMin, double &xMax, double &yMax, double border, double miterLimit, int polarity) const {
|
||||||
for (std::vector<Contour>::const_iterator contour = contours.begin(); contour != contours.end(); ++contour)
|
for (std::vector<Contour>::const_iterator contour = contours.begin(); contour != contours.end(); ++contour)
|
||||||
contour->boundMiters(l, b, r, t, border, miterLimit, polarity);
|
contour->boundMiters(xMin, yMin, xMax, yMax, border, miterLimit, polarity);
|
||||||
}
|
}
|
||||||
|
|
||||||
Shape::Bounds Shape::getBounds(double border, double miterLimit, int polarity) const {
|
Shape::Bounds Shape::getBounds(double border, double miterLimit, int polarity) const {
|
||||||
@@ -197,4 +197,12 @@ void Shape::orientContours() {
|
|||||||
contours[i].reverse();
|
contours[i].reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
YAxisOrientation Shape::getYAxisOrientation() const {
|
||||||
|
return inverseYAxis ? MSDFGEN_Y_AXIS_NONDEFAULT_ORIENTATION : MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shape::setYAxisOrientation(YAxisOrientation yAxisOrientation) {
|
||||||
|
inverseYAxis = yAxisOrientation != MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
11
thirdparty/msdfgen/core/Shape.h
vendored
11
thirdparty/msdfgen/core/Shape.h
vendored
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Contour.h"
|
#include "Contour.h"
|
||||||
|
#include "YAxisOrientation.h"
|
||||||
#include "Scanline.h"
|
#include "Scanline.h"
|
||||||
|
|
||||||
namespace msdfgen {
|
namespace msdfgen {
|
||||||
@@ -15,12 +16,14 @@ class Shape {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
struct Bounds {
|
struct Bounds {
|
||||||
|
// NOTE: b is actually the lower Y-coordinate and t the higher Y-coordinate. For Y_DOWNWARD orientation, b is actually the top and t the bottom. May be renamed in a future version.
|
||||||
double l, b, r, t;
|
double l, b, r, t;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The list of contours the shape consists of.
|
/// The list of contours the shape consists of.
|
||||||
std::vector<Contour> contours;
|
std::vector<Contour> contours;
|
||||||
/// Specifies whether the shape uses bottom-to-top (false) or top-to-bottom (true) Y coordinates.
|
/// Specifies whether the shape uses bottom-to-top (false) or top-to-bottom (true) Y coordinates.
|
||||||
|
/// DEPRECATED - use getYAxisOrientation / setYAxisOrientation instead.
|
||||||
bool inverseYAxis;
|
bool inverseYAxis;
|
||||||
|
|
||||||
Shape();
|
Shape();
|
||||||
@@ -36,9 +39,9 @@ public:
|
|||||||
/// Performs basic checks to determine if the object represents a valid shape.
|
/// Performs basic checks to determine if the object represents a valid shape.
|
||||||
bool validate() const;
|
bool validate() const;
|
||||||
/// Adjusts the bounding box to fit the shape.
|
/// Adjusts the bounding box to fit the shape.
|
||||||
void bound(double &l, double &b, double &r, double &t) const;
|
void bound(double &xMin, double &yMin, double &xMax, double &yMax) const;
|
||||||
/// Adjusts the bounding box to fit the shape border's mitered corners.
|
/// Adjusts the bounding box to fit the shape border's mitered corners.
|
||||||
void boundMiters(double &l, double &b, double &r, double &t, double border, double miterLimit, int polarity) const;
|
void boundMiters(double &xMin, double &yMin, double &xMax, double &yMax, double border, double miterLimit, int polarity) const;
|
||||||
/// Computes the minimum bounding box that fits the shape, optionally with a (mitered) border.
|
/// Computes the minimum bounding box that fits the shape, optionally with a (mitered) border.
|
||||||
Bounds getBounds(double border = 0, double miterLimit = 0, int polarity = 0) const;
|
Bounds getBounds(double border = 0, double miterLimit = 0, int polarity = 0) const;
|
||||||
/// Outputs the scanline that intersects the shape at y.
|
/// Outputs the scanline that intersects the shape at y.
|
||||||
@@ -47,6 +50,10 @@ public:
|
|||||||
int edgeCount() const;
|
int edgeCount() const;
|
||||||
/// Assumes its contours are unoriented (even-odd fill rule). Attempts to orient them to conform to the non-zero winding rule.
|
/// Assumes its contours are unoriented (even-odd fill rule). Attempts to orient them to conform to the non-zero winding rule.
|
||||||
void orientContours();
|
void orientContours();
|
||||||
|
/// Returns the orientation of the axis of the shape's Y coordinates.
|
||||||
|
YAxisOrientation getYAxisOrientation() const;
|
||||||
|
/// Sets the orientation of the axis of the shape's Y coordinates.
|
||||||
|
void setYAxisOrientation(YAxisOrientation yAxisOrientation);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
17
thirdparty/msdfgen/core/YAxisOrientation.h
vendored
Normal file
17
thirdparty/msdfgen/core/YAxisOrientation.h
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "base.h"
|
||||||
|
|
||||||
|
namespace msdfgen {
|
||||||
|
|
||||||
|
/// Specifies whether the Y component of the coordinate system increases in the upward or downward direction.
|
||||||
|
enum YAxisOrientation {
|
||||||
|
Y_UPWARD,
|
||||||
|
Y_DOWNWARD
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION msdfgen::Y_UPWARD
|
||||||
|
#define MSDFGEN_Y_AXIS_NONDEFAULT_ORIENTATION (MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION == msdfgen::Y_DOWNWARD ? msdfgen::Y_UPWARD : msdfgen::Y_DOWNWARD)
|
||||||
@@ -8,7 +8,9 @@
|
|||||||
namespace msdfgen {
|
namespace msdfgen {
|
||||||
|
|
||||||
template <typename T, int N>
|
template <typename T, int N>
|
||||||
static void interpolate(T *output, const BitmapConstRef<T, N> &bitmap, Point2 pos) {
|
inline void interpolate(T *output, const BitmapConstSection<T, N> &bitmap, Point2 pos) {
|
||||||
|
pos.x = clamp(pos.x, double(bitmap.width));
|
||||||
|
pos.y = clamp(pos.y, double(bitmap.height));
|
||||||
pos -= .5;
|
pos -= .5;
|
||||||
int l = (int) floor(pos.x);
|
int l = (int) floor(pos.x);
|
||||||
int b = (int) floor(pos.y);
|
int b = (int) floor(pos.y);
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ static double resolveDistance(const MultiDistance &distance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class EdgeSelector>
|
template <class EdgeSelector>
|
||||||
SimpleContourCombiner<EdgeSelector>::SimpleContourCombiner(const Shape &shape) { }
|
SimpleContourCombiner<EdgeSelector>::SimpleContourCombiner(const Shape &) { }
|
||||||
|
|
||||||
template <class EdgeSelector>
|
template <class EdgeSelector>
|
||||||
void SimpleContourCombiner<EdgeSelector>::reset(const Point2 &p) {
|
void SimpleContourCombiner<EdgeSelector>::reset(const Point2 &p) {
|
||||||
|
|||||||
140
thirdparty/msdfgen/core/convergent-curve-ordering.cpp
vendored
Normal file
140
thirdparty/msdfgen/core/convergent-curve-ordering.cpp
vendored
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
|
||||||
|
#include "convergent-curve-ordering.h"
|
||||||
|
|
||||||
|
#include "arithmetics.hpp"
|
||||||
|
#include "Vector2.hpp"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For non-degenerate curves A(t), B(t) (ones where all control points are distinct) both originating at P = A(0) = B(0) = *corner,
|
||||||
|
* we are computing the limit of
|
||||||
|
*
|
||||||
|
* sign(crossProduct( A(t / |A'(0)|) - P, B(t / |B'(0)|) - P ))
|
||||||
|
*
|
||||||
|
* for t -> 0 from 1. Of note is that the curves' parameter has to be normed by the first derivative at P,
|
||||||
|
* which ensures that the limit approaches P at the same rate along both curves - omitting this was the main error of earlier versions of deconverge.
|
||||||
|
*
|
||||||
|
* For degenerate cubic curves (ones where the first control point equals the origin point), the denominator |A'(0)| is zero,
|
||||||
|
* so to address that, we approach with the square root of t and use the derivative of A(sqrt(t)), which at t = 0 equals A''(0)/2
|
||||||
|
* Therefore, in these cases, we replace one factor of the cross product with A(sqrt(2*t / |A''(0)|)) - P
|
||||||
|
*
|
||||||
|
* The cross product results in a polynomial (in respect to t or t^2 in the degenerate case),
|
||||||
|
* the limit of sign of which at zero can be determined by the lowest order non-zero derivative,
|
||||||
|
* which equals to the sign of the first non-zero polynomial coefficient in the order of increasing exponents.
|
||||||
|
*
|
||||||
|
* The polynomial's constant and linear terms are zero, so the first derivative is definitely zero as well.
|
||||||
|
* The second derivative is assumed to be zero (or near zero) due to the curves being convergent - this is an input requirement
|
||||||
|
* (otherwise the correct result is the sign of the cross product of their directions at t = 0).
|
||||||
|
* Therefore, we skip the first and second derivatives.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace msdfgen {
|
||||||
|
|
||||||
|
static void simplifyDegenerateCurve(Point2 *controlPoints, int &order) {
|
||||||
|
if (order == 3 && (controlPoints[1] == controlPoints[0] || controlPoints[1] == controlPoints[3]) && (controlPoints[2] == controlPoints[0] || controlPoints[2] == controlPoints[3])) {
|
||||||
|
controlPoints[1] = controlPoints[3];
|
||||||
|
order = 1;
|
||||||
|
}
|
||||||
|
if (order == 2 && (controlPoints[1] == controlPoints[0] || controlPoints[1] == controlPoints[2])) {
|
||||||
|
controlPoints[1] = controlPoints[2];
|
||||||
|
order = 1;
|
||||||
|
}
|
||||||
|
if (order == 1 && controlPoints[0] == controlPoints[1])
|
||||||
|
order = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int convergentCurveOrdering(const Point2 *corner, int controlPointsBefore, int controlPointsAfter) {
|
||||||
|
if (!(controlPointsBefore > 0 && controlPointsAfter > 0))
|
||||||
|
return 0;
|
||||||
|
Vector2 a1, a2, a3, b1, b2, b3;
|
||||||
|
a1 = *(corner-1)-*corner;
|
||||||
|
b1 = *(corner+1)-*corner;
|
||||||
|
if (controlPointsBefore >= 2)
|
||||||
|
a2 = *(corner-2)-*(corner-1)-a1;
|
||||||
|
if (controlPointsAfter >= 2)
|
||||||
|
b2 = *(corner+2)-*(corner+1)-b1;
|
||||||
|
if (controlPointsBefore >= 3) {
|
||||||
|
a3 = *(corner-3)-*(corner-2)-(*(corner-2)-*(corner-1))-a2;
|
||||||
|
a2 *= 3;
|
||||||
|
}
|
||||||
|
if (controlPointsAfter >= 3) {
|
||||||
|
b3 = *(corner+3)-*(corner+2)-(*(corner+2)-*(corner+1))-b2;
|
||||||
|
b2 *= 3;
|
||||||
|
}
|
||||||
|
a1 *= controlPointsBefore;
|
||||||
|
b1 *= controlPointsAfter;
|
||||||
|
// Non-degenerate case
|
||||||
|
if (a1 && b1) {
|
||||||
|
double as = a1.length();
|
||||||
|
double bs = b1.length();
|
||||||
|
// Third derivative
|
||||||
|
if (double d = as*crossProduct(a1, b2) + bs*crossProduct(a2, b1))
|
||||||
|
return sign(d);
|
||||||
|
// Fourth derivative
|
||||||
|
if (double d = as*as*crossProduct(a1, b3) + as*bs*crossProduct(a2, b2) + bs*bs*crossProduct(a3, b1))
|
||||||
|
return sign(d);
|
||||||
|
// Fifth derivative
|
||||||
|
if (double d = as*crossProduct(a2, b3) + bs*crossProduct(a3, b2))
|
||||||
|
return sign(d);
|
||||||
|
// Sixth derivative
|
||||||
|
return sign(crossProduct(a3, b3));
|
||||||
|
}
|
||||||
|
// Degenerate curve after corner (control point after corner equals corner)
|
||||||
|
int s = 1;
|
||||||
|
if (a1) { // !b1
|
||||||
|
// Swap aN <-> bN and handle in if (b1)
|
||||||
|
b1 = a1;
|
||||||
|
a1 = b2, b2 = a2, a2 = a1;
|
||||||
|
a1 = b3, b3 = a3, a3 = a1;
|
||||||
|
s = -1; // make sure to also flip output
|
||||||
|
}
|
||||||
|
// Degenerate curve before corner (control point before corner equals corner)
|
||||||
|
if (b1) { // !a1
|
||||||
|
// Two-and-a-half-th derivative
|
||||||
|
if (double d = crossProduct(a3, b1))
|
||||||
|
return s*sign(d);
|
||||||
|
// Third derivative
|
||||||
|
if (double d = crossProduct(a2, b2))
|
||||||
|
return s*sign(d);
|
||||||
|
// Three-and-a-half-th derivative
|
||||||
|
if (double d = crossProduct(a3, b2))
|
||||||
|
return s*sign(d);
|
||||||
|
// Fourth derivative
|
||||||
|
if (double d = crossProduct(a2, b3))
|
||||||
|
return s*sign(d);
|
||||||
|
// Four-and-a-half-th derivative
|
||||||
|
return s*sign(crossProduct(a3, b3));
|
||||||
|
}
|
||||||
|
// Degenerate curves on both sides of the corner (control point before and after corner equals corner)
|
||||||
|
{ // !a1 && !b1
|
||||||
|
// Two-and-a-half-th derivative
|
||||||
|
if (double d = sqrt(a2.length())*crossProduct(a2, b3) + sqrt(b2.length())*crossProduct(a3, b2))
|
||||||
|
return sign(d);
|
||||||
|
// Third derivative
|
||||||
|
return sign(crossProduct(a3, b3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int convergentCurveOrdering(const EdgeSegment *a, const EdgeSegment *b) {
|
||||||
|
Point2 controlPoints[12];
|
||||||
|
Point2 *corner = controlPoints+4;
|
||||||
|
Point2 *aCpTmp = controlPoints+8;
|
||||||
|
int aOrder = int(a->type());
|
||||||
|
int bOrder = int(b->type());
|
||||||
|
if (!(aOrder >= 1 && aOrder <= 3 && bOrder >= 1 && bOrder <= 3)) {
|
||||||
|
// Not implemented - only linear, quadratic, and cubic curves supported
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i <= aOrder; ++i)
|
||||||
|
aCpTmp[i] = a->controlPoints()[i];
|
||||||
|
for (int i = 0; i <= bOrder; ++i)
|
||||||
|
corner[i] = b->controlPoints()[i];
|
||||||
|
if (aCpTmp[aOrder] != *corner)
|
||||||
|
return 0;
|
||||||
|
simplifyDegenerateCurve(aCpTmp, aOrder);
|
||||||
|
simplifyDegenerateCurve(corner, bOrder);
|
||||||
|
for (int i = 0; i < aOrder; ++i)
|
||||||
|
corner[i-aOrder] = aCpTmp[i];
|
||||||
|
return convergentCurveOrdering(corner, aOrder, bOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
11
thirdparty/msdfgen/core/convergent-curve-ordering.h
vendored
Normal file
11
thirdparty/msdfgen/core/convergent-curve-ordering.h
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "edge-segments.h"
|
||||||
|
|
||||||
|
namespace msdfgen {
|
||||||
|
|
||||||
|
/// For curves a, b converging at P = a->point(1) = b->point(0) with the same (opposite) direction, determines the relative ordering in which they exit P (i.e. whether a is to the left or right of b at the smallest positive radius around P)
|
||||||
|
int convergentCurveOrdering(const EdgeSegment *a, const EdgeSegment *b);
|
||||||
|
|
||||||
|
}
|
||||||
64
thirdparty/msdfgen/core/edge-segments.cpp
vendored
64
thirdparty/msdfgen/core/edge-segments.cpp
vendored
@@ -199,9 +199,9 @@ SignedDistance QuadraticSegment::signedDistance(Point2 origin, double ¶m) co
|
|||||||
double minDistance = nonZeroSign(crossProduct(epDir, qa))*qa.length(); // distance from A
|
double minDistance = nonZeroSign(crossProduct(epDir, qa))*qa.length(); // distance from A
|
||||||
param = -dotProduct(qa, epDir)/dotProduct(epDir, epDir);
|
param = -dotProduct(qa, epDir)/dotProduct(epDir, epDir);
|
||||||
{
|
{
|
||||||
epDir = direction(1);
|
|
||||||
double distance = (p[2]-origin).length(); // distance from B
|
double distance = (p[2]-origin).length(); // distance from B
|
||||||
if (distance < fabs(minDistance)) {
|
if (distance < fabs(minDistance)) {
|
||||||
|
epDir = direction(1);
|
||||||
minDistance = nonZeroSign(crossProduct(epDir, p[2]-origin))*distance;
|
minDistance = nonZeroSign(crossProduct(epDir, p[2]-origin))*distance;
|
||||||
param = dotProduct(origin-p[1], epDir)/dotProduct(epDir, epDir);
|
param = dotProduct(origin-p[1], epDir)/dotProduct(epDir, epDir);
|
||||||
}
|
}
|
||||||
@@ -235,25 +235,31 @@ SignedDistance CubicSegment::signedDistance(Point2 origin, double ¶m) const
|
|||||||
double minDistance = nonZeroSign(crossProduct(epDir, qa))*qa.length(); // distance from A
|
double minDistance = nonZeroSign(crossProduct(epDir, qa))*qa.length(); // distance from A
|
||||||
param = -dotProduct(qa, epDir)/dotProduct(epDir, epDir);
|
param = -dotProduct(qa, epDir)/dotProduct(epDir, epDir);
|
||||||
{
|
{
|
||||||
epDir = direction(1);
|
|
||||||
double distance = (p[3]-origin).length(); // distance from B
|
double distance = (p[3]-origin).length(); // distance from B
|
||||||
if (distance < fabs(minDistance)) {
|
if (distance < fabs(minDistance)) {
|
||||||
|
epDir = direction(1);
|
||||||
minDistance = nonZeroSign(crossProduct(epDir, p[3]-origin))*distance;
|
minDistance = nonZeroSign(crossProduct(epDir, p[3]-origin))*distance;
|
||||||
param = dotProduct(epDir-(p[3]-origin), epDir)/dotProduct(epDir, epDir);
|
param = dotProduct(epDir-(p[3]-origin), epDir)/dotProduct(epDir, epDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Iterative minimum distance search
|
// Iterative minimum distance search
|
||||||
for (int i = 0; i <= MSDFGEN_CUBIC_SEARCH_STARTS; ++i) {
|
for (int i = 0; i <= MSDFGEN_CUBIC_SEARCH_STARTS; ++i) {
|
||||||
double t = (double) i/MSDFGEN_CUBIC_SEARCH_STARTS;
|
double t = 1./MSDFGEN_CUBIC_SEARCH_STARTS*i;
|
||||||
Vector2 qe = qa+3*t*ab+3*t*t*br+t*t*t*as;
|
Vector2 qe = qa+3*t*ab+3*t*t*br+t*t*t*as;
|
||||||
for (int step = 0; step < MSDFGEN_CUBIC_SEARCH_STEPS; ++step) {
|
Vector2 d1 = 3*ab+6*t*br+3*t*t*as;
|
||||||
// Improve t
|
Vector2 d2 = 6*br+6*t*as;
|
||||||
Vector2 d1 = 3*ab+6*t*br+3*t*t*as;
|
double improvedT = t-dotProduct(qe, d1)/(dotProduct(d1, d1)+dotProduct(qe, d2));
|
||||||
Vector2 d2 = 6*br+6*t*as;
|
if (improvedT > 0 && improvedT < 1) {
|
||||||
t -= dotProduct(qe, d1)/(dotProduct(d1, d1)+dotProduct(qe, d2));
|
int remainingSteps = MSDFGEN_CUBIC_SEARCH_STEPS;
|
||||||
if (t <= 0 || t >= 1)
|
do {
|
||||||
break;
|
t = improvedT;
|
||||||
qe = qa+3*t*ab+3*t*t*br+t*t*t*as;
|
qe = qa+3*t*ab+3*t*t*br+t*t*t*as;
|
||||||
|
d1 = 3*ab+6*t*br+3*t*t*as;
|
||||||
|
if (!--remainingSteps)
|
||||||
|
break;
|
||||||
|
d2 = 6*br+6*t*as;
|
||||||
|
improvedT = t-dotProduct(qe, d1)/(dotProduct(d1, d1)+dotProduct(qe, d2));
|
||||||
|
} while (improvedT > 0 && improvedT < 1);
|
||||||
double distance = qe.length();
|
double distance = qe.length();
|
||||||
if (distance < fabs(minDistance)) {
|
if (distance < fabs(minDistance)) {
|
||||||
minDistance = nonZeroSign(crossProduct(d1, qe))*distance;
|
minDistance = nonZeroSign(crossProduct(d1, qe))*distance;
|
||||||
@@ -396,37 +402,37 @@ int CubicSegment::scanlineIntersections(double x[3], int dy[3], double y) const
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pointBounds(Point2 p, double &l, double &b, double &r, double &t) {
|
static void pointBounds(Point2 p, double &xMin, double &yMin, double &xMax, double &yMax) {
|
||||||
if (p.x < l) l = p.x;
|
if (p.x < xMin) xMin = p.x;
|
||||||
if (p.y < b) b = p.y;
|
if (p.y < yMin) yMin = p.y;
|
||||||
if (p.x > r) r = p.x;
|
if (p.x > xMax) xMax = p.x;
|
||||||
if (p.y > t) t = p.y;
|
if (p.y > yMax) yMax = p.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinearSegment::bound(double &l, double &b, double &r, double &t) const {
|
void LinearSegment::bound(double &xMin, double &yMin, double &xMax, double &yMax) const {
|
||||||
pointBounds(p[0], l, b, r, t);
|
pointBounds(p[0], xMin, yMin, xMax, yMax);
|
||||||
pointBounds(p[1], l, b, r, t);
|
pointBounds(p[1], xMin, yMin, xMax, yMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuadraticSegment::bound(double &l, double &b, double &r, double &t) const {
|
void QuadraticSegment::bound(double &xMin, double &yMin, double &xMax, double &yMax) const {
|
||||||
pointBounds(p[0], l, b, r, t);
|
pointBounds(p[0], xMin, yMin, xMax, yMax);
|
||||||
pointBounds(p[2], l, b, r, t);
|
pointBounds(p[2], xMin, yMin, xMax, yMax);
|
||||||
Vector2 bot = (p[1]-p[0])-(p[2]-p[1]);
|
Vector2 bot = (p[1]-p[0])-(p[2]-p[1]);
|
||||||
if (bot.x) {
|
if (bot.x) {
|
||||||
double param = (p[1].x-p[0].x)/bot.x;
|
double param = (p[1].x-p[0].x)/bot.x;
|
||||||
if (param > 0 && param < 1)
|
if (param > 0 && param < 1)
|
||||||
pointBounds(point(param), l, b, r, t);
|
pointBounds(point(param), xMin, yMin, xMax, yMax);
|
||||||
}
|
}
|
||||||
if (bot.y) {
|
if (bot.y) {
|
||||||
double param = (p[1].y-p[0].y)/bot.y;
|
double param = (p[1].y-p[0].y)/bot.y;
|
||||||
if (param > 0 && param < 1)
|
if (param > 0 && param < 1)
|
||||||
pointBounds(point(param), l, b, r, t);
|
pointBounds(point(param), xMin, yMin, xMax, yMax);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubicSegment::bound(double &l, double &b, double &r, double &t) const {
|
void CubicSegment::bound(double &xMin, double &yMin, double &xMax, double &yMax) const {
|
||||||
pointBounds(p[0], l, b, r, t);
|
pointBounds(p[0], xMin, yMin, xMax, yMax);
|
||||||
pointBounds(p[3], l, b, r, t);
|
pointBounds(p[3], xMin, yMin, xMax, yMax);
|
||||||
Vector2 a0 = p[1]-p[0];
|
Vector2 a0 = p[1]-p[0];
|
||||||
Vector2 a1 = 2*(p[2]-p[1]-a0);
|
Vector2 a1 = 2*(p[2]-p[1]-a0);
|
||||||
Vector2 a2 = p[3]-3*p[2]+3*p[1]-p[0];
|
Vector2 a2 = p[3]-3*p[2]+3*p[1]-p[0];
|
||||||
@@ -435,11 +441,11 @@ void CubicSegment::bound(double &l, double &b, double &r, double &t) const {
|
|||||||
solutions = solveQuadratic(params, a2.x, a1.x, a0.x);
|
solutions = solveQuadratic(params, a2.x, a1.x, a0.x);
|
||||||
for (int i = 0; i < solutions; ++i)
|
for (int i = 0; i < solutions; ++i)
|
||||||
if (params[i] > 0 && params[i] < 1)
|
if (params[i] > 0 && params[i] < 1)
|
||||||
pointBounds(point(params[i]), l, b, r, t);
|
pointBounds(point(params[i]), xMin, yMin, xMax, yMax);
|
||||||
solutions = solveQuadratic(params, a2.y, a1.y, a0.y);
|
solutions = solveQuadratic(params, a2.y, a1.y, a0.y);
|
||||||
for (int i = 0; i < solutions; ++i)
|
for (int i = 0; i < solutions; ++i)
|
||||||
if (params[i] > 0 && params[i] < 1)
|
if (params[i] > 0 && params[i] < 1)
|
||||||
pointBounds(point(params[i]), l, b, r, t);
|
pointBounds(point(params[i]), xMin, yMin, xMax, yMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinearSegment::reverse() {
|
void LinearSegment::reverse() {
|
||||||
|
|||||||
8
thirdparty/msdfgen/core/edge-segments.h
vendored
8
thirdparty/msdfgen/core/edge-segments.h
vendored
@@ -42,7 +42,7 @@ public:
|
|||||||
/// Outputs a list of (at most three) intersections (their X coordinates) with an infinite horizontal scanline at y and returns how many there are.
|
/// Outputs a list of (at most three) intersections (their X coordinates) with an infinite horizontal scanline at y and returns how many there are.
|
||||||
virtual int scanlineIntersections(double x[3], int dy[3], double y) const = 0;
|
virtual int scanlineIntersections(double x[3], int dy[3], double y) const = 0;
|
||||||
/// Adjusts the bounding box to fit the edge segment.
|
/// Adjusts the bounding box to fit the edge segment.
|
||||||
virtual void bound(double &l, double &b, double &r, double &t) const = 0;
|
virtual void bound(double &xMin, double &yMin, double &xMax, double &yMax) const = 0;
|
||||||
|
|
||||||
/// Reverses the edge (swaps its start point and end point).
|
/// Reverses the edge (swaps its start point and end point).
|
||||||
virtual void reverse() = 0;
|
virtual void reverse() = 0;
|
||||||
@@ -75,7 +75,7 @@ public:
|
|||||||
double length() const;
|
double length() const;
|
||||||
SignedDistance signedDistance(Point2 origin, double ¶m) const;
|
SignedDistance signedDistance(Point2 origin, double ¶m) const;
|
||||||
int scanlineIntersections(double x[3], int dy[3], double y) const;
|
int scanlineIntersections(double x[3], int dy[3], double y) const;
|
||||||
void bound(double &l, double &b, double &r, double &t) const;
|
void bound(double &xMin, double &yMin, double &xMax, double &yMax) const;
|
||||||
|
|
||||||
void reverse();
|
void reverse();
|
||||||
void moveStartPoint(Point2 to);
|
void moveStartPoint(Point2 to);
|
||||||
@@ -104,7 +104,7 @@ public:
|
|||||||
double length() const;
|
double length() const;
|
||||||
SignedDistance signedDistance(Point2 origin, double ¶m) const;
|
SignedDistance signedDistance(Point2 origin, double ¶m) const;
|
||||||
int scanlineIntersections(double x[3], int dy[3], double y) const;
|
int scanlineIntersections(double x[3], int dy[3], double y) const;
|
||||||
void bound(double &l, double &b, double &r, double &t) const;
|
void bound(double &xMin, double &yMin, double &xMax, double &yMax) const;
|
||||||
|
|
||||||
void reverse();
|
void reverse();
|
||||||
void moveStartPoint(Point2 to);
|
void moveStartPoint(Point2 to);
|
||||||
@@ -134,7 +134,7 @@ public:
|
|||||||
Vector2 directionChange(double param) const;
|
Vector2 directionChange(double param) const;
|
||||||
SignedDistance signedDistance(Point2 origin, double ¶m) const;
|
SignedDistance signedDistance(Point2 origin, double ¶m) const;
|
||||||
int scanlineIntersections(double x[3], int dy[3], double y) const;
|
int scanlineIntersections(double x[3], int dy[3], double y) const;
|
||||||
void bound(double &l, double &b, double &r, double &t) const;
|
void bound(double &xMin, double &yMin, double &xMax, double &yMax) const;
|
||||||
|
|
||||||
void reverse();
|
void reverse();
|
||||||
void moveStartPoint(Point2 to);
|
void moveStartPoint(Point2 to);
|
||||||
|
|||||||
3
thirdparty/msdfgen/core/edge-selectors.cpp
vendored
3
thirdparty/msdfgen/core/edge-selectors.cpp
vendored
@@ -11,6 +11,7 @@ TrueDistanceSelector::EdgeCache::EdgeCache() : absDistance(0) { }
|
|||||||
|
|
||||||
void TrueDistanceSelector::reset(const Point2 &p) {
|
void TrueDistanceSelector::reset(const Point2 &p) {
|
||||||
double delta = DISTANCE_DELTA_FACTOR*(p-this->p).length();
|
double delta = DISTANCE_DELTA_FACTOR*(p-this->p).length();
|
||||||
|
// Since minDistance.distance is initialized to -DBL_MAX, at first glance this seems like it could make it underflow to -infinity, but in practice delta would have to be extremely high for this to happen (above 9e291)
|
||||||
minDistance.distance += nonZeroSign(minDistance.distance)*delta;
|
minDistance.distance += nonZeroSign(minDistance.distance)*delta;
|
||||||
this->p = p;
|
this->p = p;
|
||||||
}
|
}
|
||||||
@@ -60,7 +61,7 @@ void PerpendicularDistanceSelectorBase::reset(double delta) {
|
|||||||
nearEdgeParam = 0;
|
nearEdgeParam = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PerpendicularDistanceSelectorBase::isEdgeRelevant(const EdgeCache &cache, const EdgeSegment *edge, const Point2 &p) const {
|
bool PerpendicularDistanceSelectorBase::isEdgeRelevant(const EdgeCache &cache, const EdgeSegment *, const Point2 &p) const {
|
||||||
double delta = DISTANCE_DELTA_FACTOR*(p-cache.point).length();
|
double delta = DISTANCE_DELTA_FACTOR*(p-cache.point).length();
|
||||||
return (
|
return (
|
||||||
cache.absDistance-delta <= fabs(minTrueDistance.distance) ||
|
cache.absDistance-delta <= fabs(minTrueDistance.distance) ||
|
||||||
|
|||||||
79
thirdparty/msdfgen/core/export-svg.cpp
vendored
79
thirdparty/msdfgen/core/export-svg.cpp
vendored
@@ -1,79 +0,0 @@
|
|||||||
|
|
||||||
#include "export-svg.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include "edge-segments.h"
|
|
||||||
|
|
||||||
namespace msdfgen {
|
|
||||||
|
|
||||||
static void writeSvgCoord(FILE *f, Point2 coord) {
|
|
||||||
fprintf(f, "%.17g %.17g", coord.x, coord.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void writeSvgPathDef(FILE *f, const Shape &shape) {
|
|
||||||
bool beginning = true;
|
|
||||||
for (const Contour &c : shape.contours) {
|
|
||||||
if (c.edges.empty())
|
|
||||||
continue;
|
|
||||||
if (beginning)
|
|
||||||
beginning = false;
|
|
||||||
else
|
|
||||||
fputc(' ', f);
|
|
||||||
fputs("M ", f);
|
|
||||||
writeSvgCoord(f, c.edges[0]->controlPoints()[0]);
|
|
||||||
for (const EdgeHolder &e : c.edges) {
|
|
||||||
const Point2 *cp = e->controlPoints();
|
|
||||||
switch (e->type()) {
|
|
||||||
case (int) LinearSegment::EDGE_TYPE:
|
|
||||||
fputs(" L ", f);
|
|
||||||
writeSvgCoord(f, cp[1]);
|
|
||||||
break;
|
|
||||||
case (int) QuadraticSegment::EDGE_TYPE:
|
|
||||||
fputs(" Q ", f);
|
|
||||||
writeSvgCoord(f, cp[1]);
|
|
||||||
fputc(' ', f);
|
|
||||||
writeSvgCoord(f, cp[2]);
|
|
||||||
break;
|
|
||||||
case (int) CubicSegment::EDGE_TYPE:
|
|
||||||
fputs(" C ", f);
|
|
||||||
writeSvgCoord(f, cp[1]);
|
|
||||||
fputc(' ', f);
|
|
||||||
writeSvgCoord(f, cp[2]);
|
|
||||||
fputc(' ', f);
|
|
||||||
writeSvgCoord(f, cp[3]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fputs(" Z", f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveSvgShape(const Shape &shape, const char *filename) {
|
|
||||||
if (FILE *f = fopen(filename, "w")) {
|
|
||||||
fputs("<svg xmlns=\"http://www.w3.org/2000/svg\"><path", f);
|
|
||||||
if (!shape.inverseYAxis)
|
|
||||||
fputs(" transform=\"scale(1 -1)\"", f);
|
|
||||||
fputs(" d=\"", f);
|
|
||||||
writeSvgPathDef(f, shape);
|
|
||||||
fputs("\"/></svg>\n", f);
|
|
||||||
fclose(f);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveSvgShape(const Shape &shape, const Shape::Bounds &bounds, const char *filename) {
|
|
||||||
if (FILE *f = fopen(filename, "w")) {
|
|
||||||
fprintf(f, "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"%.17g %.17g %.17g %.17g\"><path", bounds.l, bounds.b, bounds.r-bounds.l, bounds.t-bounds.b);
|
|
||||||
if (!shape.inverseYAxis)
|
|
||||||
fprintf(f, " transform=\"translate(0 %.17g) scale(1 -1)\"", bounds.b+bounds.t);
|
|
||||||
fputs(" d=\"", f);
|
|
||||||
writeSvgPathDef(f, shape);
|
|
||||||
fputs("\"/></svg>\n", f);
|
|
||||||
fclose(f);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
11
thirdparty/msdfgen/core/export-svg.h
vendored
11
thirdparty/msdfgen/core/export-svg.h
vendored
@@ -1,11 +0,0 @@
|
|||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Shape.h"
|
|
||||||
|
|
||||||
namespace msdfgen {
|
|
||||||
|
|
||||||
bool saveSvgShape(const Shape &shape, const char *filename);
|
|
||||||
bool saveSvgShape(const Shape &shape, const Shape::Bounds &bounds, const char *filename);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -10,15 +10,14 @@
|
|||||||
namespace msdfgen {
|
namespace msdfgen {
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
static void msdfErrorCorrectionInner(const BitmapRef<float, N> &sdf, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config) {
|
static void msdfErrorCorrectionInner(const BitmapSection<float, N> &sdf, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config) {
|
||||||
if (config.errorCorrection.mode == ErrorCorrectionConfig::DISABLED)
|
if (config.errorCorrection.mode == ErrorCorrectionConfig::DISABLED)
|
||||||
return;
|
return;
|
||||||
Bitmap<byte, 1> stencilBuffer;
|
Bitmap<byte, 1> stencilBuffer;
|
||||||
if (!config.errorCorrection.buffer)
|
if (!config.errorCorrection.buffer)
|
||||||
stencilBuffer = Bitmap<byte, 1>(sdf.width, sdf.height);
|
stencilBuffer = Bitmap<byte, 1>(sdf.width, sdf.height);
|
||||||
BitmapRef<byte, 1> stencil;
|
BitmapSection<byte, 1> stencil(NULL, sdf.width, sdf.height);
|
||||||
stencil.pixels = config.errorCorrection.buffer ? config.errorCorrection.buffer : (byte *) stencilBuffer;
|
stencil.pixels = config.errorCorrection.buffer ? config.errorCorrection.buffer : (byte *) stencilBuffer;
|
||||||
stencil.width = sdf.width, stencil.height = sdf.height;
|
|
||||||
MSDFErrorCorrection ec(stencil, transformation);
|
MSDFErrorCorrection ec(stencil, transformation);
|
||||||
ec.setMinDeviationRatio(config.errorCorrection.minDeviationRatio);
|
ec.setMinDeviationRatio(config.errorCorrection.minDeviationRatio);
|
||||||
ec.setMinImproveRatio(config.errorCorrection.minImproveRatio);
|
ec.setMinImproveRatio(config.errorCorrection.minImproveRatio);
|
||||||
@@ -49,7 +48,7 @@ static void msdfErrorCorrectionInner(const BitmapRef<float, N> &sdf, const Shape
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
static void msdfErrorCorrectionShapeless(const BitmapRef<float, N> &sdf, const SDFTransformation &transformation, double minDeviationRatio, bool protectAll) {
|
static void msdfErrorCorrectionShapeless(const BitmapSection<float, N> &sdf, const SDFTransformation &transformation, double minDeviationRatio, bool protectAll) {
|
||||||
Bitmap<byte, 1> stencilBuffer(sdf.width, sdf.height);
|
Bitmap<byte, 1> stencilBuffer(sdf.width, sdf.height);
|
||||||
MSDFErrorCorrection ec(stencilBuffer, transformation);
|
MSDFErrorCorrection ec(stencilBuffer, transformation);
|
||||||
ec.setMinDeviationRatio(minDeviationRatio);
|
ec.setMinDeviationRatio(minDeviationRatio);
|
||||||
@@ -59,54 +58,54 @@ static void msdfErrorCorrectionShapeless(const BitmapRef<float, N> &sdf, const S
|
|||||||
ec.apply(sdf);
|
ec.apply(sdf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void msdfErrorCorrection(const BitmapRef<float, 3> &sdf, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config) {
|
void msdfErrorCorrection(const BitmapSection<float, 3> &sdf, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config) {
|
||||||
msdfErrorCorrectionInner(sdf, shape, transformation, config);
|
msdfErrorCorrectionInner(sdf, shape, transformation, config);
|
||||||
}
|
}
|
||||||
void msdfErrorCorrection(const BitmapRef<float, 4> &sdf, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config) {
|
void msdfErrorCorrection(const BitmapSection<float, 4> &sdf, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config) {
|
||||||
msdfErrorCorrectionInner(sdf, shape, transformation, config);
|
msdfErrorCorrectionInner(sdf, shape, transformation, config);
|
||||||
}
|
}
|
||||||
void msdfErrorCorrection(const BitmapRef<float, 3> &sdf, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config) {
|
void msdfErrorCorrection(const BitmapSection<float, 3> &sdf, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config) {
|
||||||
msdfErrorCorrectionInner(sdf, shape, SDFTransformation(projection, range), config);
|
msdfErrorCorrectionInner(sdf, shape, SDFTransformation(projection, range), config);
|
||||||
}
|
}
|
||||||
void msdfErrorCorrection(const BitmapRef<float, 4> &sdf, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config) {
|
void msdfErrorCorrection(const BitmapSection<float, 4> &sdf, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config) {
|
||||||
msdfErrorCorrectionInner(sdf, shape, SDFTransformation(projection, range), config);
|
msdfErrorCorrectionInner(sdf, shape, SDFTransformation(projection, range), config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void msdfFastDistanceErrorCorrection(const BitmapRef<float, 3> &sdf, const SDFTransformation &transformation, double minDeviationRatio) {
|
void msdfFastDistanceErrorCorrection(const BitmapSection<float, 3> &sdf, const SDFTransformation &transformation, double minDeviationRatio) {
|
||||||
msdfErrorCorrectionShapeless(sdf, transformation, minDeviationRatio, false);
|
msdfErrorCorrectionShapeless(sdf, transformation, minDeviationRatio, false);
|
||||||
}
|
}
|
||||||
void msdfFastDistanceErrorCorrection(const BitmapRef<float, 4> &sdf, const SDFTransformation &transformation, double minDeviationRatio) {
|
void msdfFastDistanceErrorCorrection(const BitmapSection<float, 4> &sdf, const SDFTransformation &transformation, double minDeviationRatio) {
|
||||||
msdfErrorCorrectionShapeless(sdf, transformation, minDeviationRatio, false);
|
msdfErrorCorrectionShapeless(sdf, transformation, minDeviationRatio, false);
|
||||||
}
|
}
|
||||||
void msdfFastDistanceErrorCorrection(const BitmapRef<float, 3> &sdf, const Projection &projection, Range range, double minDeviationRatio) {
|
void msdfFastDistanceErrorCorrection(const BitmapSection<float, 3> &sdf, const Projection &projection, Range range, double minDeviationRatio) {
|
||||||
msdfErrorCorrectionShapeless(sdf, SDFTransformation(projection, range), minDeviationRatio, false);
|
msdfErrorCorrectionShapeless(sdf, SDFTransformation(projection, range), minDeviationRatio, false);
|
||||||
}
|
}
|
||||||
void msdfFastDistanceErrorCorrection(const BitmapRef<float, 4> &sdf, const Projection &projection, Range range, double minDeviationRatio) {
|
void msdfFastDistanceErrorCorrection(const BitmapSection<float, 4> &sdf, const Projection &projection, Range range, double minDeviationRatio) {
|
||||||
msdfErrorCorrectionShapeless(sdf, SDFTransformation(projection, range), minDeviationRatio, false);
|
msdfErrorCorrectionShapeless(sdf, SDFTransformation(projection, range), minDeviationRatio, false);
|
||||||
}
|
}
|
||||||
void msdfFastDistanceErrorCorrection(const BitmapRef<float, 3> &sdf, Range pxRange, double minDeviationRatio) {
|
void msdfFastDistanceErrorCorrection(const BitmapSection<float, 3> &sdf, Range pxRange, double minDeviationRatio) {
|
||||||
msdfErrorCorrectionShapeless(sdf, SDFTransformation(Projection(), pxRange), minDeviationRatio, false);
|
msdfErrorCorrectionShapeless(sdf, SDFTransformation(Projection(), pxRange), minDeviationRatio, false);
|
||||||
}
|
}
|
||||||
void msdfFastDistanceErrorCorrection(const BitmapRef<float, 4> &sdf, Range pxRange, double minDeviationRatio) {
|
void msdfFastDistanceErrorCorrection(const BitmapSection<float, 4> &sdf, Range pxRange, double minDeviationRatio) {
|
||||||
msdfErrorCorrectionShapeless(sdf, SDFTransformation(Projection(), pxRange), minDeviationRatio, false);
|
msdfErrorCorrectionShapeless(sdf, SDFTransformation(Projection(), pxRange), minDeviationRatio, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void msdfFastEdgeErrorCorrection(const BitmapRef<float, 3> &sdf, const SDFTransformation &transformation, double minDeviationRatio) {
|
void msdfFastEdgeErrorCorrection(const BitmapSection<float, 3> &sdf, const SDFTransformation &transformation, double minDeviationRatio) {
|
||||||
msdfErrorCorrectionShapeless(sdf, transformation, minDeviationRatio, true);
|
msdfErrorCorrectionShapeless(sdf, transformation, minDeviationRatio, true);
|
||||||
}
|
}
|
||||||
void msdfFastEdgeErrorCorrection(const BitmapRef<float, 4> &sdf, const SDFTransformation &transformation, double minDeviationRatio) {
|
void msdfFastEdgeErrorCorrection(const BitmapSection<float, 4> &sdf, const SDFTransformation &transformation, double minDeviationRatio) {
|
||||||
msdfErrorCorrectionShapeless(sdf, transformation, minDeviationRatio, true);
|
msdfErrorCorrectionShapeless(sdf, transformation, minDeviationRatio, true);
|
||||||
}
|
}
|
||||||
void msdfFastEdgeErrorCorrection(const BitmapRef<float, 3> &sdf, const Projection &projection, Range range, double minDeviationRatio) {
|
void msdfFastEdgeErrorCorrection(const BitmapSection<float, 3> &sdf, const Projection &projection, Range range, double minDeviationRatio) {
|
||||||
msdfErrorCorrectionShapeless(sdf, SDFTransformation(projection, range), minDeviationRatio, true);
|
msdfErrorCorrectionShapeless(sdf, SDFTransformation(projection, range), minDeviationRatio, true);
|
||||||
}
|
}
|
||||||
void msdfFastEdgeErrorCorrection(const BitmapRef<float, 4> &sdf, const Projection &projection, Range range, double minDeviationRatio) {
|
void msdfFastEdgeErrorCorrection(const BitmapSection<float, 4> &sdf, const Projection &projection, Range range, double minDeviationRatio) {
|
||||||
msdfErrorCorrectionShapeless(sdf, SDFTransformation(projection, range), minDeviationRatio, true);
|
msdfErrorCorrectionShapeless(sdf, SDFTransformation(projection, range), minDeviationRatio, true);
|
||||||
}
|
}
|
||||||
void msdfFastEdgeErrorCorrection(const BitmapRef<float, 3> &sdf, Range pxRange, double minDeviationRatio) {
|
void msdfFastEdgeErrorCorrection(const BitmapSection<float, 3> &sdf, Range pxRange, double minDeviationRatio) {
|
||||||
msdfErrorCorrectionShapeless(sdf, SDFTransformation(Projection(), pxRange), minDeviationRatio, true);
|
msdfErrorCorrectionShapeless(sdf, SDFTransformation(Projection(), pxRange), minDeviationRatio, true);
|
||||||
}
|
}
|
||||||
void msdfFastEdgeErrorCorrection(const BitmapRef<float, 4> &sdf, Range pxRange, double minDeviationRatio) {
|
void msdfFastEdgeErrorCorrection(const BitmapSection<float, 4> &sdf, Range pxRange, double minDeviationRatio) {
|
||||||
msdfErrorCorrectionShapeless(sdf, SDFTransformation(Projection(), pxRange), minDeviationRatio, true);
|
msdfErrorCorrectionShapeless(sdf, SDFTransformation(Projection(), pxRange), minDeviationRatio, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +135,7 @@ inline static bool detectClash(const float *a, const float *b, double threshold)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
static void msdfErrorCorrectionInner_legacy(const BitmapRef<float, N> &output, const Vector2 &threshold) {
|
static void msdfErrorCorrectionInner_legacy(const BitmapSection<float, N> &output, const Vector2 &threshold) {
|
||||||
std::vector<std::pair<int, int> > clashes;
|
std::vector<std::pair<int, int> > clashes;
|
||||||
int w = output.width, h = output.height;
|
int w = output.width, h = output.height;
|
||||||
for (int y = 0; y < h; ++y)
|
for (int y = 0; y < h; ++y)
|
||||||
@@ -174,10 +173,10 @@ static void msdfErrorCorrectionInner_legacy(const BitmapRef<float, N> &output, c
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void msdfErrorCorrection_legacy(const BitmapRef<float, 3> &output, const Vector2 &threshold) {
|
void msdfErrorCorrection_legacy(const BitmapSection<float, 3> &output, const Vector2 &threshold) {
|
||||||
msdfErrorCorrectionInner_legacy(output, threshold);
|
msdfErrorCorrectionInner_legacy(output, threshold);
|
||||||
}
|
}
|
||||||
void msdfErrorCorrection_legacy(const BitmapRef<float, 4> &output, const Vector2 &threshold) {
|
void msdfErrorCorrection_legacy(const BitmapSection<float, 4> &output, const Vector2 &threshold) {
|
||||||
msdfErrorCorrectionInner_legacy(output, threshold);
|
msdfErrorCorrectionInner_legacy(output, threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
36
thirdparty/msdfgen/core/msdf-error-correction.h
vendored
36
thirdparty/msdfgen/core/msdf-error-correction.h
vendored
@@ -12,29 +12,29 @@
|
|||||||
namespace msdfgen {
|
namespace msdfgen {
|
||||||
|
|
||||||
/// Predicts potential artifacts caused by the interpolation of the MSDF and corrects them by converting nearby texels to single-channel.
|
/// Predicts potential artifacts caused by the interpolation of the MSDF and corrects them by converting nearby texels to single-channel.
|
||||||
void msdfErrorCorrection(const BitmapRef<float, 3> &sdf, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
void msdfErrorCorrection(const BitmapSection<float, 3> &sdf, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
||||||
void msdfErrorCorrection(const BitmapRef<float, 4> &sdf, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
void msdfErrorCorrection(const BitmapSection<float, 4> &sdf, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
||||||
void msdfErrorCorrection(const BitmapRef<float, 3> &sdf, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
void msdfErrorCorrection(const BitmapSection<float, 3> &sdf, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
||||||
void msdfErrorCorrection(const BitmapRef<float, 4> &sdf, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
void msdfErrorCorrection(const BitmapSection<float, 4> &sdf, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
||||||
|
|
||||||
/// Applies the simplified error correction to all discontiunous distances (INDISCRIMINATE mode). Does not need shape or translation.
|
/// Applies the simplified error correction to all discontiunous distances (INDISCRIMINATE mode). Does not need shape or translation.
|
||||||
void msdfFastDistanceErrorCorrection(const BitmapRef<float, 3> &sdf, const SDFTransformation &transformation, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
void msdfFastDistanceErrorCorrection(const BitmapSection<float, 3> &sdf, const SDFTransformation &transformation, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
||||||
void msdfFastDistanceErrorCorrection(const BitmapRef<float, 4> &sdf, const SDFTransformation &transformation, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
void msdfFastDistanceErrorCorrection(const BitmapSection<float, 4> &sdf, const SDFTransformation &transformation, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
||||||
void msdfFastDistanceErrorCorrection(const BitmapRef<float, 3> &sdf, const Projection &projection, Range range, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
void msdfFastDistanceErrorCorrection(const BitmapSection<float, 3> &sdf, const Projection &projection, Range range, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
||||||
void msdfFastDistanceErrorCorrection(const BitmapRef<float, 4> &sdf, const Projection &projection, Range range, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
void msdfFastDistanceErrorCorrection(const BitmapSection<float, 4> &sdf, const Projection &projection, Range range, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
||||||
void msdfFastDistanceErrorCorrection(const BitmapRef<float, 3> &sdf, Range pxRange, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
void msdfFastDistanceErrorCorrection(const BitmapSection<float, 3> &sdf, Range pxRange, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
||||||
void msdfFastDistanceErrorCorrection(const BitmapRef<float, 4> &sdf, Range pxRange, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
void msdfFastDistanceErrorCorrection(const BitmapSection<float, 4> &sdf, Range pxRange, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
||||||
|
|
||||||
/// Applies the simplified error correction to edges only (EDGE_ONLY mode). Does not need shape or translation.
|
/// Applies the simplified error correction to edges only (EDGE_ONLY mode). Does not need shape or translation.
|
||||||
void msdfFastEdgeErrorCorrection(const BitmapRef<float, 3> &sdf, const SDFTransformation &transformation, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
void msdfFastEdgeErrorCorrection(const BitmapSection<float, 3> &sdf, const SDFTransformation &transformation, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
||||||
void msdfFastEdgeErrorCorrection(const BitmapRef<float, 4> &sdf, const SDFTransformation &transformation, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
void msdfFastEdgeErrorCorrection(const BitmapSection<float, 4> &sdf, const SDFTransformation &transformation, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
||||||
void msdfFastEdgeErrorCorrection(const BitmapRef<float, 3> &sdf, const Projection &projection, Range range, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
void msdfFastEdgeErrorCorrection(const BitmapSection<float, 3> &sdf, const Projection &projection, Range range, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
||||||
void msdfFastEdgeErrorCorrection(const BitmapRef<float, 4> &sdf, const Projection &projection, Range range, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
void msdfFastEdgeErrorCorrection(const BitmapSection<float, 4> &sdf, const Projection &projection, Range range, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
||||||
void msdfFastEdgeErrorCorrection(const BitmapRef<float, 3> &sdf, Range pxRange, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
void msdfFastEdgeErrorCorrection(const BitmapSection<float, 3> &sdf, Range pxRange, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
||||||
void msdfFastEdgeErrorCorrection(const BitmapRef<float, 4> &sdf, Range pxRange, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
void msdfFastEdgeErrorCorrection(const BitmapSection<float, 4> &sdf, Range pxRange, double minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio);
|
||||||
|
|
||||||
/// The original version of the error correction algorithm.
|
/// The original version of the error correction algorithm.
|
||||||
void msdfErrorCorrection_legacy(const BitmapRef<float, 3> &output, const Vector2 &threshold);
|
void msdfErrorCorrection_legacy(const BitmapSection<float, 3> &output, const Vector2 &threshold);
|
||||||
void msdfErrorCorrection_legacy(const BitmapRef<float, 4> &output, const Vector2 &threshold);
|
void msdfErrorCorrection_legacy(const BitmapSection<float, 4> &output, const Vector2 &threshold);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
83
thirdparty/msdfgen/core/msdfgen.cpp
vendored
83
thirdparty/msdfgen/core/msdfgen.cpp
vendored
@@ -15,7 +15,7 @@ template <>
|
|||||||
class DistancePixelConversion<double> {
|
class DistancePixelConversion<double> {
|
||||||
DistanceMapping mapping;
|
DistanceMapping mapping;
|
||||||
public:
|
public:
|
||||||
typedef BitmapRef<float, 1> BitmapRefType;
|
typedef BitmapSection<float, 1> BitmapSectionType;
|
||||||
inline explicit DistancePixelConversion(DistanceMapping mapping) : mapping(mapping) { }
|
inline explicit DistancePixelConversion(DistanceMapping mapping) : mapping(mapping) { }
|
||||||
inline void operator()(float *pixels, double distance) const {
|
inline void operator()(float *pixels, double distance) const {
|
||||||
*pixels = float(mapping(distance));
|
*pixels = float(mapping(distance));
|
||||||
@@ -26,7 +26,7 @@ template <>
|
|||||||
class DistancePixelConversion<MultiDistance> {
|
class DistancePixelConversion<MultiDistance> {
|
||||||
DistanceMapping mapping;
|
DistanceMapping mapping;
|
||||||
public:
|
public:
|
||||||
typedef BitmapRef<float, 3> BitmapRefType;
|
typedef BitmapSection<float, 3> BitmapSectionType;
|
||||||
inline explicit DistancePixelConversion(DistanceMapping mapping) : mapping(mapping) { }
|
inline explicit DistancePixelConversion(DistanceMapping mapping) : mapping(mapping) { }
|
||||||
inline void operator()(float *pixels, const MultiDistance &distance) const {
|
inline void operator()(float *pixels, const MultiDistance &distance) const {
|
||||||
pixels[0] = float(mapping(distance.r));
|
pixels[0] = float(mapping(distance.r));
|
||||||
@@ -39,7 +39,7 @@ template <>
|
|||||||
class DistancePixelConversion<MultiAndTrueDistance> {
|
class DistancePixelConversion<MultiAndTrueDistance> {
|
||||||
DistanceMapping mapping;
|
DistanceMapping mapping;
|
||||||
public:
|
public:
|
||||||
typedef BitmapRef<float, 4> BitmapRefType;
|
typedef BitmapSection<float, 4> BitmapSectionType;
|
||||||
inline explicit DistancePixelConversion(DistanceMapping mapping) : mapping(mapping) { }
|
inline explicit DistancePixelConversion(DistanceMapping mapping) : mapping(mapping) { }
|
||||||
inline void operator()(float *pixels, const MultiAndTrueDistance &distance) const {
|
inline void operator()(float *pixels, const MultiAndTrueDistance &distance) const {
|
||||||
pixels[0] = float(mapping(distance.r));
|
pixels[0] = float(mapping(distance.r));
|
||||||
@@ -50,45 +50,46 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class ContourCombiner>
|
template <class ContourCombiner>
|
||||||
void generateDistanceField(const typename DistancePixelConversion<typename ContourCombiner::DistanceType>::BitmapRefType &output, const Shape &shape, const SDFTransformation &transformation) {
|
void generateDistanceField(typename DistancePixelConversion<typename ContourCombiner::DistanceType>::BitmapSectionType output, const Shape &shape, const SDFTransformation &transformation) {
|
||||||
DistancePixelConversion<typename ContourCombiner::DistanceType> distancePixelConversion(transformation.distanceMapping);
|
DistancePixelConversion<typename ContourCombiner::DistanceType> distancePixelConversion(transformation.distanceMapping);
|
||||||
|
output.reorient(shape.getYAxisOrientation());
|
||||||
#ifdef MSDFGEN_USE_OPENMP
|
#ifdef MSDFGEN_USE_OPENMP
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ShapeDistanceFinder<ContourCombiner> distanceFinder(shape);
|
ShapeDistanceFinder<ContourCombiner> distanceFinder(shape);
|
||||||
bool rightToLeft = false;
|
int xDirection = 1;
|
||||||
#ifdef MSDFGEN_USE_OPENMP
|
#ifdef MSDFGEN_USE_OPENMP
|
||||||
#pragma omp for
|
#pragma omp for
|
||||||
#endif
|
#endif
|
||||||
for (int y = 0; y < output.height; ++y) {
|
for (int y = 0; y < output.height; ++y) {
|
||||||
int row = shape.inverseYAxis ? output.height-y-1 : y;
|
int x = xDirection < 0 ? output.width-1 : 0;
|
||||||
for (int col = 0; col < output.width; ++col) {
|
for (int col = 0; col < output.width; ++col) {
|
||||||
int x = rightToLeft ? output.width-col-1 : col;
|
|
||||||
Point2 p = transformation.unproject(Point2(x+.5, y+.5));
|
Point2 p = transformation.unproject(Point2(x+.5, y+.5));
|
||||||
typename ContourCombiner::DistanceType distance = distanceFinder.distance(p);
|
typename ContourCombiner::DistanceType distance = distanceFinder.distance(p);
|
||||||
distancePixelConversion(output(x, row), distance);
|
distancePixelConversion(output(x, y), distance);
|
||||||
|
x += xDirection;
|
||||||
}
|
}
|
||||||
rightToLeft = !rightToLeft;
|
xDirection = -xDirection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateSDF(const BitmapRef<float, 1> &output, const Shape &shape, const SDFTransformation &transformation, const GeneratorConfig &config) {
|
void generateSDF(const BitmapSection<float, 1> &output, const Shape &shape, const SDFTransformation &transformation, const GeneratorConfig &config) {
|
||||||
if (config.overlapSupport)
|
if (config.overlapSupport)
|
||||||
generateDistanceField<OverlappingContourCombiner<TrueDistanceSelector> >(output, shape, transformation);
|
generateDistanceField<OverlappingContourCombiner<TrueDistanceSelector> >(output, shape, transformation);
|
||||||
else
|
else
|
||||||
generateDistanceField<SimpleContourCombiner<TrueDistanceSelector> >(output, shape, transformation);
|
generateDistanceField<SimpleContourCombiner<TrueDistanceSelector> >(output, shape, transformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generatePSDF(const BitmapRef<float, 1> &output, const Shape &shape, const SDFTransformation &transformation, const GeneratorConfig &config) {
|
void generatePSDF(const BitmapSection<float, 1> &output, const Shape &shape, const SDFTransformation &transformation, const GeneratorConfig &config) {
|
||||||
if (config.overlapSupport)
|
if (config.overlapSupport)
|
||||||
generateDistanceField<OverlappingContourCombiner<PerpendicularDistanceSelector> >(output, shape, transformation);
|
generateDistanceField<OverlappingContourCombiner<PerpendicularDistanceSelector> >(output, shape, transformation);
|
||||||
else
|
else
|
||||||
generateDistanceField<SimpleContourCombiner<PerpendicularDistanceSelector> >(output, shape, transformation);
|
generateDistanceField<SimpleContourCombiner<PerpendicularDistanceSelector> >(output, shape, transformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateMSDF(const BitmapRef<float, 3> &output, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config) {
|
void generateMSDF(const BitmapSection<float, 3> &output, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config) {
|
||||||
if (config.overlapSupport)
|
if (config.overlapSupport)
|
||||||
generateDistanceField<OverlappingContourCombiner<MultiDistanceSelector> >(output, shape, transformation);
|
generateDistanceField<OverlappingContourCombiner<MultiDistanceSelector> >(output, shape, transformation);
|
||||||
else
|
else
|
||||||
@@ -96,7 +97,7 @@ void generateMSDF(const BitmapRef<float, 3> &output, const Shape &shape, const S
|
|||||||
msdfErrorCorrection(output, shape, transformation, config);
|
msdfErrorCorrection(output, shape, transformation, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateMTSDF(const BitmapRef<float, 4> &output, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config) {
|
void generateMTSDF(const BitmapSection<float, 4> &output, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config) {
|
||||||
if (config.overlapSupport)
|
if (config.overlapSupport)
|
||||||
generateDistanceField<OverlappingContourCombiner<MultiAndTrueDistanceSelector> >(output, shape, transformation);
|
generateDistanceField<OverlappingContourCombiner<MultiAndTrueDistanceSelector> >(output, shape, transformation);
|
||||||
else
|
else
|
||||||
@@ -104,21 +105,21 @@ void generateMTSDF(const BitmapRef<float, 4> &output, const Shape &shape, const
|
|||||||
msdfErrorCorrection(output, shape, transformation, config);
|
msdfErrorCorrection(output, shape, transformation, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateSDF(const BitmapRef<float, 1> &output, const Shape &shape, const Projection &projection, Range range, const GeneratorConfig &config) {
|
void generateSDF(const BitmapSection<float, 1> &output, const Shape &shape, const Projection &projection, Range range, const GeneratorConfig &config) {
|
||||||
if (config.overlapSupport)
|
if (config.overlapSupport)
|
||||||
generateDistanceField<OverlappingContourCombiner<TrueDistanceSelector> >(output, shape, SDFTransformation(projection, range));
|
generateDistanceField<OverlappingContourCombiner<TrueDistanceSelector> >(output, shape, SDFTransformation(projection, range));
|
||||||
else
|
else
|
||||||
generateDistanceField<SimpleContourCombiner<TrueDistanceSelector> >(output, shape, SDFTransformation(projection, range));
|
generateDistanceField<SimpleContourCombiner<TrueDistanceSelector> >(output, shape, SDFTransformation(projection, range));
|
||||||
}
|
}
|
||||||
|
|
||||||
void generatePSDF(const BitmapRef<float, 1> &output, const Shape &shape, const Projection &projection, Range range, const GeneratorConfig &config) {
|
void generatePSDF(const BitmapSection<float, 1> &output, const Shape &shape, const Projection &projection, Range range, const GeneratorConfig &config) {
|
||||||
if (config.overlapSupport)
|
if (config.overlapSupport)
|
||||||
generateDistanceField<OverlappingContourCombiner<PerpendicularDistanceSelector> >(output, shape, SDFTransformation(projection, range));
|
generateDistanceField<OverlappingContourCombiner<PerpendicularDistanceSelector> >(output, shape, SDFTransformation(projection, range));
|
||||||
else
|
else
|
||||||
generateDistanceField<SimpleContourCombiner<PerpendicularDistanceSelector> >(output, shape, SDFTransformation(projection, range));
|
generateDistanceField<SimpleContourCombiner<PerpendicularDistanceSelector> >(output, shape, SDFTransformation(projection, range));
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateMSDF(const BitmapRef<float, 3> &output, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config) {
|
void generateMSDF(const BitmapSection<float, 3> &output, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config) {
|
||||||
if (config.overlapSupport)
|
if (config.overlapSupport)
|
||||||
generateDistanceField<OverlappingContourCombiner<MultiDistanceSelector> >(output, shape, SDFTransformation(projection, range));
|
generateDistanceField<OverlappingContourCombiner<MultiDistanceSelector> >(output, shape, SDFTransformation(projection, range));
|
||||||
else
|
else
|
||||||
@@ -126,7 +127,7 @@ void generateMSDF(const BitmapRef<float, 3> &output, const Shape &shape, const P
|
|||||||
msdfErrorCorrection(output, shape, SDFTransformation(projection, range), config);
|
msdfErrorCorrection(output, shape, SDFTransformation(projection, range), config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateMTSDF(const BitmapRef<float, 4> &output, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config) {
|
void generateMTSDF(const BitmapSection<float, 4> &output, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config) {
|
||||||
if (config.overlapSupport)
|
if (config.overlapSupport)
|
||||||
generateDistanceField<OverlappingContourCombiner<MultiAndTrueDistanceSelector> >(output, shape, SDFTransformation(projection, range));
|
generateDistanceField<OverlappingContourCombiner<MultiAndTrueDistanceSelector> >(output, shape, SDFTransformation(projection, range));
|
||||||
else
|
else
|
||||||
@@ -136,39 +137,39 @@ void generateMTSDF(const BitmapRef<float, 4> &output, const Shape &shape, const
|
|||||||
|
|
||||||
// Legacy API
|
// Legacy API
|
||||||
|
|
||||||
void generatePseudoSDF(const BitmapRef<float, 1> &output, const Shape &shape, const Projection &projection, Range range, const GeneratorConfig &config) {
|
void generatePseudoSDF(const BitmapSection<float, 1> &output, const Shape &shape, const Projection &projection, Range range, const GeneratorConfig &config) {
|
||||||
generatePSDF(output, shape, SDFTransformation(projection, range), config);
|
generatePSDF(output, shape, SDFTransformation(projection, range), config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateSDF(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport) {
|
void generateSDF(const BitmapSection<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport) {
|
||||||
generateSDF(output, shape, Projection(scale, translate), range, GeneratorConfig(overlapSupport));
|
generateSDF(output, shape, Projection(scale, translate), range, GeneratorConfig(overlapSupport));
|
||||||
}
|
}
|
||||||
|
|
||||||
void generatePSDF(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport) {
|
void generatePSDF(const BitmapSection<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport) {
|
||||||
generatePSDF(output, shape, Projection(scale, translate), range, GeneratorConfig(overlapSupport));
|
generatePSDF(output, shape, Projection(scale, translate), range, GeneratorConfig(overlapSupport));
|
||||||
}
|
}
|
||||||
|
|
||||||
void generatePseudoSDF(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport) {
|
void generatePseudoSDF(const BitmapSection<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport) {
|
||||||
generatePSDF(output, shape, Projection(scale, translate), range, GeneratorConfig(overlapSupport));
|
generatePSDF(output, shape, Projection(scale, translate), range, GeneratorConfig(overlapSupport));
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateMSDF(const BitmapRef<float, 3> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, const ErrorCorrectionConfig &errorCorrectionConfig, bool overlapSupport) {
|
void generateMSDF(const BitmapSection<float, 3> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, const ErrorCorrectionConfig &errorCorrectionConfig, bool overlapSupport) {
|
||||||
generateMSDF(output, shape, Projection(scale, translate), range, MSDFGeneratorConfig(overlapSupport, errorCorrectionConfig));
|
generateMSDF(output, shape, Projection(scale, translate), range, MSDFGeneratorConfig(overlapSupport, errorCorrectionConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateMTSDF(const BitmapRef<float, 4> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, const ErrorCorrectionConfig &errorCorrectionConfig, bool overlapSupport) {
|
void generateMTSDF(const BitmapSection<float, 4> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, const ErrorCorrectionConfig &errorCorrectionConfig, bool overlapSupport) {
|
||||||
generateMTSDF(output, shape, Projection(scale, translate), range, MSDFGeneratorConfig(overlapSupport, errorCorrectionConfig));
|
generateMTSDF(output, shape, Projection(scale, translate), range, MSDFGeneratorConfig(overlapSupport, errorCorrectionConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Legacy version
|
// Legacy version
|
||||||
|
|
||||||
void generateSDF_legacy(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate) {
|
void generateSDF_legacy(BitmapSection<float, 1> output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate) {
|
||||||
DistanceMapping distanceMapping(range);
|
DistanceMapping distanceMapping(range);
|
||||||
|
output.reorient(shape.getYAxisOrientation());
|
||||||
#ifdef MSDFGEN_USE_OPENMP
|
#ifdef MSDFGEN_USE_OPENMP
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
#endif
|
#endif
|
||||||
for (int y = 0; y < output.height; ++y) {
|
for (int y = 0; y < output.height; ++y) {
|
||||||
int row = shape.inverseYAxis ? output.height-y-1 : y;
|
|
||||||
for (int x = 0; x < output.width; ++x) {
|
for (int x = 0; x < output.width; ++x) {
|
||||||
double dummy;
|
double dummy;
|
||||||
Point2 p = Vector2(x+.5, y+.5)/scale-translate;
|
Point2 p = Vector2(x+.5, y+.5)/scale-translate;
|
||||||
@@ -179,18 +180,18 @@ void generateSDF_legacy(const BitmapRef<float, 1> &output, const Shape &shape, R
|
|||||||
if (distance < minDistance)
|
if (distance < minDistance)
|
||||||
minDistance = distance;
|
minDistance = distance;
|
||||||
}
|
}
|
||||||
*output(x, row) = float(distanceMapping(minDistance.distance));
|
*output(x, y) = float(distanceMapping(minDistance.distance));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generatePSDF_legacy(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate) {
|
void generatePSDF_legacy(BitmapSection<float, 1> output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate) {
|
||||||
DistanceMapping distanceMapping(range);
|
DistanceMapping distanceMapping(range);
|
||||||
|
output.reorient(shape.getYAxisOrientation());
|
||||||
#ifdef MSDFGEN_USE_OPENMP
|
#ifdef MSDFGEN_USE_OPENMP
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
#endif
|
#endif
|
||||||
for (int y = 0; y < output.height; ++y) {
|
for (int y = 0; y < output.height; ++y) {
|
||||||
int row = shape.inverseYAxis ? output.height-y-1 : y;
|
|
||||||
for (int x = 0; x < output.width; ++x) {
|
for (int x = 0; x < output.width; ++x) {
|
||||||
Point2 p = Vector2(x+.5, y+.5)/scale-translate;
|
Point2 p = Vector2(x+.5, y+.5)/scale-translate;
|
||||||
SignedDistance minDistance;
|
SignedDistance minDistance;
|
||||||
@@ -208,22 +209,22 @@ void generatePSDF_legacy(const BitmapRef<float, 1> &output, const Shape &shape,
|
|||||||
}
|
}
|
||||||
if (nearEdge)
|
if (nearEdge)
|
||||||
(*nearEdge)->distanceToPerpendicularDistance(minDistance, p, nearParam);
|
(*nearEdge)->distanceToPerpendicularDistance(minDistance, p, nearParam);
|
||||||
*output(x, row) = float(distanceMapping(minDistance.distance));
|
*output(x, y) = float(distanceMapping(minDistance.distance));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generatePseudoSDF_legacy(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate) {
|
void generatePseudoSDF_legacy(BitmapSection<float, 1> output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate) {
|
||||||
generatePSDF_legacy(output, shape, range, scale, translate);
|
generatePSDF_legacy(output, shape, range, scale, translate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateMSDF_legacy(const BitmapRef<float, 3> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, ErrorCorrectionConfig errorCorrectionConfig) {
|
void generateMSDF_legacy(BitmapSection<float, 3> output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, ErrorCorrectionConfig errorCorrectionConfig) {
|
||||||
DistanceMapping distanceMapping(range);
|
DistanceMapping distanceMapping(range);
|
||||||
|
output.reorient(shape.getYAxisOrientation());
|
||||||
#ifdef MSDFGEN_USE_OPENMP
|
#ifdef MSDFGEN_USE_OPENMP
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
#endif
|
#endif
|
||||||
for (int y = 0; y < output.height; ++y) {
|
for (int y = 0; y < output.height; ++y) {
|
||||||
int row = shape.inverseYAxis ? output.height-y-1 : y;
|
|
||||||
for (int x = 0; x < output.width; ++x) {
|
for (int x = 0; x < output.width; ++x) {
|
||||||
Point2 p = Vector2(x+.5, y+.5)/scale-translate;
|
Point2 p = Vector2(x+.5, y+.5)/scale-translate;
|
||||||
|
|
||||||
@@ -262,9 +263,9 @@ void generateMSDF_legacy(const BitmapRef<float, 3> &output, const Shape &shape,
|
|||||||
(*g.nearEdge)->distanceToPerpendicularDistance(g.minDistance, p, g.nearParam);
|
(*g.nearEdge)->distanceToPerpendicularDistance(g.minDistance, p, g.nearParam);
|
||||||
if (b.nearEdge)
|
if (b.nearEdge)
|
||||||
(*b.nearEdge)->distanceToPerpendicularDistance(b.minDistance, p, b.nearParam);
|
(*b.nearEdge)->distanceToPerpendicularDistance(b.minDistance, p, b.nearParam);
|
||||||
output(x, row)[0] = float(distanceMapping(r.minDistance.distance));
|
output(x, y)[0] = float(distanceMapping(r.minDistance.distance));
|
||||||
output(x, row)[1] = float(distanceMapping(g.minDistance.distance));
|
output(x, y)[1] = float(distanceMapping(g.minDistance.distance));
|
||||||
output(x, row)[2] = float(distanceMapping(b.minDistance.distance));
|
output(x, y)[2] = float(distanceMapping(b.minDistance.distance));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,13 +273,13 @@ void generateMSDF_legacy(const BitmapRef<float, 3> &output, const Shape &shape,
|
|||||||
msdfErrorCorrection(output, shape, Projection(scale, translate), range, MSDFGeneratorConfig(false, errorCorrectionConfig));
|
msdfErrorCorrection(output, shape, Projection(scale, translate), range, MSDFGeneratorConfig(false, errorCorrectionConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateMTSDF_legacy(const BitmapRef<float, 4> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, ErrorCorrectionConfig errorCorrectionConfig) {
|
void generateMTSDF_legacy(BitmapSection<float, 4> output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, ErrorCorrectionConfig errorCorrectionConfig) {
|
||||||
DistanceMapping distanceMapping(range);
|
DistanceMapping distanceMapping(range);
|
||||||
|
output.reorient(shape.getYAxisOrientation());
|
||||||
#ifdef MSDFGEN_USE_OPENMP
|
#ifdef MSDFGEN_USE_OPENMP
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
#endif
|
#endif
|
||||||
for (int y = 0; y < output.height; ++y) {
|
for (int y = 0; y < output.height; ++y) {
|
||||||
int row = shape.inverseYAxis ? output.height-y-1 : y;
|
|
||||||
for (int x = 0; x < output.width; ++x) {
|
for (int x = 0; x < output.width; ++x) {
|
||||||
Point2 p = Vector2(x+.5, y+.5)/scale-translate;
|
Point2 p = Vector2(x+.5, y+.5)/scale-translate;
|
||||||
|
|
||||||
@@ -320,10 +321,10 @@ void generateMTSDF_legacy(const BitmapRef<float, 4> &output, const Shape &shape,
|
|||||||
(*g.nearEdge)->distanceToPerpendicularDistance(g.minDistance, p, g.nearParam);
|
(*g.nearEdge)->distanceToPerpendicularDistance(g.minDistance, p, g.nearParam);
|
||||||
if (b.nearEdge)
|
if (b.nearEdge)
|
||||||
(*b.nearEdge)->distanceToPerpendicularDistance(b.minDistance, p, b.nearParam);
|
(*b.nearEdge)->distanceToPerpendicularDistance(b.minDistance, p, b.nearParam);
|
||||||
output(x, row)[0] = float(distanceMapping(r.minDistance.distance));
|
output(x, y)[0] = float(distanceMapping(r.minDistance.distance));
|
||||||
output(x, row)[1] = float(distanceMapping(g.minDistance.distance));
|
output(x, y)[1] = float(distanceMapping(g.minDistance.distance));
|
||||||
output(x, row)[2] = float(distanceMapping(b.minDistance.distance));
|
output(x, y)[2] = float(distanceMapping(b.minDistance.distance));
|
||||||
output(x, row)[3] = float(distanceMapping(minDistance.distance));
|
output(x, y)[3] = float(distanceMapping(minDistance.distance));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
75
thirdparty/msdfgen/core/rasterization.cpp
vendored
75
thirdparty/msdfgen/core/rasterization.cpp
vendored
@@ -6,58 +6,60 @@
|
|||||||
|
|
||||||
namespace msdfgen {
|
namespace msdfgen {
|
||||||
|
|
||||||
void rasterize(const BitmapRef<float, 1> &output, const Shape &shape, const Projection &projection, FillRule fillRule) {
|
void rasterize(BitmapSection<float, 1> output, const Shape &shape, const Projection &projection, FillRule fillRule) {
|
||||||
|
output.reorient(shape.getYAxisOrientation());
|
||||||
Scanline scanline;
|
Scanline scanline;
|
||||||
for (int y = 0; y < output.height; ++y) {
|
for (int y = 0; y < output.height; ++y) {
|
||||||
int row = shape.inverseYAxis ? output.height-y-1 : y;
|
|
||||||
shape.scanline(scanline, projection.unprojectY(y+.5));
|
shape.scanline(scanline, projection.unprojectY(y+.5));
|
||||||
for (int x = 0; x < output.width; ++x)
|
for (int x = 0; x < output.width; ++x)
|
||||||
*output(x, row) = (float) scanline.filled(projection.unprojectX(x+.5), fillRule);
|
*output(x, y) = (float) scanline.filled(projection.unprojectX(x+.5), fillRule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void distanceSignCorrection(const BitmapRef<float, 1> &sdf, const Shape &shape, const Projection &projection, FillRule fillRule) {
|
void distanceSignCorrection(BitmapSection<float, 1> sdf, const Shape &shape, const Projection &projection, float sdfZeroValue, FillRule fillRule) {
|
||||||
|
sdf.reorient(shape.getYAxisOrientation());
|
||||||
|
float doubleSdfZeroValue = sdfZeroValue+sdfZeroValue;
|
||||||
Scanline scanline;
|
Scanline scanline;
|
||||||
for (int y = 0; y < sdf.height; ++y) {
|
for (int y = 0; y < sdf.height; ++y) {
|
||||||
int row = shape.inverseYAxis ? sdf.height-y-1 : y;
|
|
||||||
shape.scanline(scanline, projection.unprojectY(y+.5));
|
shape.scanline(scanline, projection.unprojectY(y+.5));
|
||||||
for (int x = 0; x < sdf.width; ++x) {
|
for (int x = 0; x < sdf.width; ++x) {
|
||||||
bool fill = scanline.filled(projection.unprojectX(x+.5), fillRule);
|
bool fill = scanline.filled(projection.unprojectX(x+.5), fillRule);
|
||||||
float &sd = *sdf(x, row);
|
float &sd = *sdf(x, y);
|
||||||
if ((sd > .5f) != fill)
|
if ((sd > sdfZeroValue) != fill)
|
||||||
sd = 1.f-sd;
|
sd = doubleSdfZeroValue-sd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
static void multiDistanceSignCorrection(const BitmapRef<float, N> &sdf, const Shape &shape, const Projection &projection, FillRule fillRule) {
|
static void multiDistanceSignCorrection(BitmapSection<float, N> sdf, const Shape &shape, const Projection &projection, float sdfZeroValue, FillRule fillRule) {
|
||||||
int w = sdf.width, h = sdf.height;
|
int w = sdf.width, h = sdf.height;
|
||||||
if (!(w && h))
|
if (!(w && h))
|
||||||
return;
|
return;
|
||||||
|
sdf.reorient(shape.getYAxisOrientation());
|
||||||
|
float doubleSdfZeroValue = sdfZeroValue+sdfZeroValue;
|
||||||
Scanline scanline;
|
Scanline scanline;
|
||||||
bool ambiguous = false;
|
bool ambiguous = false;
|
||||||
std::vector<char> matchMap;
|
std::vector<char> matchMap;
|
||||||
matchMap.resize(w*h);
|
matchMap.resize(w*h);
|
||||||
char *match = &matchMap[0];
|
char *match = &matchMap[0];
|
||||||
for (int y = 0; y < h; ++y) {
|
for (int y = 0; y < h; ++y) {
|
||||||
int row = shape.inverseYAxis ? h-y-1 : y;
|
|
||||||
shape.scanline(scanline, projection.unprojectY(y+.5));
|
shape.scanline(scanline, projection.unprojectY(y+.5));
|
||||||
for (int x = 0; x < w; ++x) {
|
for (int x = 0; x < w; ++x) {
|
||||||
bool fill = scanline.filled(projection.unprojectX(x+.5), fillRule);
|
bool fill = scanline.filled(projection.unprojectX(x+.5), fillRule);
|
||||||
float *msd = sdf(x, row);
|
float *msd = sdf(x, y);
|
||||||
float sd = median(msd[0], msd[1], msd[2]);
|
float sd = median(msd[0], msd[1], msd[2]);
|
||||||
if (sd == .5f)
|
if (sd == sdfZeroValue)
|
||||||
ambiguous = true;
|
ambiguous = true;
|
||||||
else if ((sd > .5f) != fill) {
|
else if ((sd > sdfZeroValue) != fill) {
|
||||||
msd[0] = 1.f-msd[0];
|
msd[0] = doubleSdfZeroValue-msd[0];
|
||||||
msd[1] = 1.f-msd[1];
|
msd[1] = doubleSdfZeroValue-msd[1];
|
||||||
msd[2] = 1.f-msd[2];
|
msd[2] = doubleSdfZeroValue-msd[2];
|
||||||
*match = -1;
|
*match = -1;
|
||||||
} else
|
} else
|
||||||
*match = 1;
|
*match = 1;
|
||||||
if (N >= 4 && (msd[3] > .5f) != fill)
|
if (N >= 4 && (msd[3] > sdfZeroValue) != fill)
|
||||||
msd[3] = 1.f-msd[3];
|
msd[3] = doubleSdfZeroValue-msd[3];
|
||||||
++match;
|
++match;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,7 +67,6 @@ static void multiDistanceSignCorrection(const BitmapRef<float, N> &sdf, const Sh
|
|||||||
if (ambiguous) {
|
if (ambiguous) {
|
||||||
match = &matchMap[0];
|
match = &matchMap[0];
|
||||||
for (int y = 0; y < h; ++y) {
|
for (int y = 0; y < h; ++y) {
|
||||||
int row = shape.inverseYAxis ? h-y-1 : y;
|
|
||||||
for (int x = 0; x < w; ++x) {
|
for (int x = 0; x < w; ++x) {
|
||||||
if (!*match) {
|
if (!*match) {
|
||||||
int neighborMatch = 0;
|
int neighborMatch = 0;
|
||||||
@@ -74,10 +75,10 @@ static void multiDistanceSignCorrection(const BitmapRef<float, N> &sdf, const Sh
|
|||||||
if (y > 0) neighborMatch += *(match-w);
|
if (y > 0) neighborMatch += *(match-w);
|
||||||
if (y < h-1) neighborMatch += *(match+w);
|
if (y < h-1) neighborMatch += *(match+w);
|
||||||
if (neighborMatch < 0) {
|
if (neighborMatch < 0) {
|
||||||
float *msd = sdf(x, row);
|
float *msd = sdf(x, y);
|
||||||
msd[0] = 1.f-msd[0];
|
msd[0] = doubleSdfZeroValue-msd[0];
|
||||||
msd[1] = 1.f-msd[1];
|
msd[1] = doubleSdfZeroValue-msd[1];
|
||||||
msd[2] = 1.f-msd[2];
|
msd[2] = doubleSdfZeroValue-msd[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++match;
|
++match;
|
||||||
@@ -86,29 +87,41 @@ static void multiDistanceSignCorrection(const BitmapRef<float, N> &sdf, const Sh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void distanceSignCorrection(const BitmapRef<float, 3> &sdf, const Shape &shape, const Projection &projection, FillRule fillRule) {
|
void distanceSignCorrection(BitmapSection<float, 3> sdf, const Shape &shape, const Projection &projection, float sdfZeroValue, FillRule fillRule) {
|
||||||
multiDistanceSignCorrection(sdf, shape, projection, fillRule);
|
multiDistanceSignCorrection(sdf, shape, projection, sdfZeroValue, fillRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
void distanceSignCorrection(const BitmapRef<float, 4> &sdf, const Shape &shape, const Projection &projection, FillRule fillRule) {
|
void distanceSignCorrection(BitmapSection<float, 4> sdf, const Shape &shape, const Projection &projection, float sdfZeroValue, FillRule fillRule) {
|
||||||
multiDistanceSignCorrection(sdf, shape, projection, fillRule);
|
multiDistanceSignCorrection(sdf, shape, projection, sdfZeroValue, fillRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Legacy API
|
// Legacy API
|
||||||
|
|
||||||
void rasterize(const BitmapRef<float, 1> &output, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
|
void rasterize(const BitmapSection<float, 1> &output, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
|
||||||
rasterize(output, shape, Projection(scale, translate), fillRule);
|
rasterize(output, shape, Projection(scale, translate), fillRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
void distanceSignCorrection(const BitmapRef<float, 1> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
|
void distanceSignCorrection(BitmapSection<float, 1> sdf, const Shape &shape, const Projection &projection, FillRule fillRule) {
|
||||||
|
distanceSignCorrection(sdf, shape, projection, .5f, fillRule);
|
||||||
|
}
|
||||||
|
|
||||||
|
void distanceSignCorrection(BitmapSection<float, 3> sdf, const Shape &shape, const Projection &projection, FillRule fillRule) {
|
||||||
|
distanceSignCorrection(sdf, shape, projection, .5f, fillRule);
|
||||||
|
}
|
||||||
|
|
||||||
|
void distanceSignCorrection(BitmapSection<float, 4> sdf, const Shape &shape, const Projection &projection, FillRule fillRule) {
|
||||||
|
distanceSignCorrection(sdf, shape, projection, .5f, fillRule);
|
||||||
|
}
|
||||||
|
|
||||||
|
void distanceSignCorrection(const BitmapSection<float, 1> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
|
||||||
distanceSignCorrection(sdf, shape, Projection(scale, translate), fillRule);
|
distanceSignCorrection(sdf, shape, Projection(scale, translate), fillRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
void distanceSignCorrection(const BitmapRef<float, 3> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
|
void distanceSignCorrection(const BitmapSection<float, 3> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
|
||||||
distanceSignCorrection(sdf, shape, Projection(scale, translate), fillRule);
|
distanceSignCorrection(sdf, shape, Projection(scale, translate), fillRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
void distanceSignCorrection(const BitmapRef<float, 4> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
|
void distanceSignCorrection(const BitmapSection<float, 4> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
|
||||||
distanceSignCorrection(sdf, shape, Projection(scale, translate), fillRule);
|
distanceSignCorrection(sdf, shape, Projection(scale, translate), fillRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
thirdparty/msdfgen/core/rasterization.h
vendored
21
thirdparty/msdfgen/core/rasterization.h
vendored
@@ -10,16 +10,19 @@
|
|||||||
namespace msdfgen {
|
namespace msdfgen {
|
||||||
|
|
||||||
/// Rasterizes the shape into a monochrome bitmap.
|
/// Rasterizes the shape into a monochrome bitmap.
|
||||||
void rasterize(const BitmapRef<float, 1> &output, const Shape &shape, const Projection &projection, FillRule fillRule = FILL_NONZERO);
|
void rasterize(BitmapSection<float, 1> output, const Shape &shape, const Projection &projection, FillRule fillRule = FILL_NONZERO);
|
||||||
/// Fixes the sign of the input signed distance field, so that it matches the shape's rasterized fill.
|
/// Fixes the sign of the input signed distance field, so that it matches the shape's rasterized fill.
|
||||||
void distanceSignCorrection(const BitmapRef<float, 1> &sdf, const Shape &shape, const Projection &projection, FillRule fillRule = FILL_NONZERO);
|
void distanceSignCorrection(BitmapSection<float, 1> sdf, const Shape &shape, const Projection &projection, float sdfZeroValue = .5f, FillRule fillRule = FILL_NONZERO);
|
||||||
void distanceSignCorrection(const BitmapRef<float, 3> &sdf, const Shape &shape, const Projection &projection, FillRule fillRule = FILL_NONZERO);
|
void distanceSignCorrection(BitmapSection<float, 3> sdf, const Shape &shape, const Projection &projection, float sdfZeroValue = .5f, FillRule fillRule = FILL_NONZERO);
|
||||||
void distanceSignCorrection(const BitmapRef<float, 4> &sdf, const Shape &shape, const Projection &projection, FillRule fillRule = FILL_NONZERO);
|
void distanceSignCorrection(BitmapSection<float, 4> sdf, const Shape &shape, const Projection &projection, float sdfZeroValue = .5f, FillRule fillRule = FILL_NONZERO);
|
||||||
|
|
||||||
// Old version of the function API's kept for backwards compatibility
|
// Old versions of the function API's kept for backwards compatibility
|
||||||
void rasterize(const BitmapRef<float, 1> &output, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule = FILL_NONZERO);
|
void rasterize(const BitmapSection<float, 1> &output, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule = FILL_NONZERO);
|
||||||
void distanceSignCorrection(const BitmapRef<float, 1> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule = FILL_NONZERO);
|
void distanceSignCorrection(BitmapSection<float, 1> sdf, const Shape &shape, const Projection &projection, FillRule fillRule);
|
||||||
void distanceSignCorrection(const BitmapRef<float, 3> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule = FILL_NONZERO);
|
void distanceSignCorrection(BitmapSection<float, 3> sdf, const Shape &shape, const Projection &projection, FillRule fillRule);
|
||||||
void distanceSignCorrection(const BitmapRef<float, 4> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule = FILL_NONZERO);
|
void distanceSignCorrection(BitmapSection<float, 4> sdf, const Shape &shape, const Projection &projection, FillRule fillRule);
|
||||||
|
void distanceSignCorrection(const BitmapSection<float, 1> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule = FILL_NONZERO);
|
||||||
|
void distanceSignCorrection(const BitmapSection<float, 3> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule = FILL_NONZERO);
|
||||||
|
void distanceSignCorrection(const BitmapSection<float, 4> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule = FILL_NONZERO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
18
thirdparty/msdfgen/core/render-sdf.cpp
vendored
18
thirdparty/msdfgen/core/render-sdf.cpp
vendored
@@ -12,7 +12,7 @@ static float distVal(float dist, DistanceMapping mapping) {
|
|||||||
return (float) clamp(mapping(dist)+.5);
|
return (float) clamp(mapping(dist)+.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderSDF(const BitmapRef<float, 1> &output, const BitmapConstRef<float, 1> &sdf, Range sdfPxRange, float sdThreshold) {
|
void renderSDF(const BitmapSection<float, 1> &output, const BitmapConstSection<float, 1> &sdf, Range sdfPxRange, float sdThreshold) {
|
||||||
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
|
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
|
||||||
if (sdfPxRange.lower == sdfPxRange.upper) {
|
if (sdfPxRange.lower == sdfPxRange.upper) {
|
||||||
for (int y = 0; y < output.height; ++y) {
|
for (int y = 0; y < output.height; ++y) {
|
||||||
@@ -37,7 +37,7 @@ void renderSDF(const BitmapRef<float, 1> &output, const BitmapConstRef<float, 1>
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderSDF(const BitmapRef<float, 3> &output, const BitmapConstRef<float, 1> &sdf, Range sdfPxRange, float sdThreshold) {
|
void renderSDF(const BitmapSection<float, 3> &output, const BitmapConstSection<float, 1> &sdf, Range sdfPxRange, float sdThreshold) {
|
||||||
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
|
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
|
||||||
if (sdfPxRange.lower == sdfPxRange.upper) {
|
if (sdfPxRange.lower == sdfPxRange.upper) {
|
||||||
for (int y = 0; y < output.height; ++y) {
|
for (int y = 0; y < output.height; ++y) {
|
||||||
@@ -67,7 +67,7 @@ void renderSDF(const BitmapRef<float, 3> &output, const BitmapConstRef<float, 1>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderSDF(const BitmapRef<float, 1> &output, const BitmapConstRef<float, 3> &sdf, Range sdfPxRange, float sdThreshold) {
|
void renderSDF(const BitmapSection<float, 1> &output, const BitmapConstSection<float, 3> &sdf, Range sdfPxRange, float sdThreshold) {
|
||||||
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
|
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
|
||||||
if (sdfPxRange.lower == sdfPxRange.upper) {
|
if (sdfPxRange.lower == sdfPxRange.upper) {
|
||||||
for (int y = 0; y < output.height; ++y) {
|
for (int y = 0; y < output.height; ++y) {
|
||||||
@@ -91,7 +91,7 @@ void renderSDF(const BitmapRef<float, 1> &output, const BitmapConstRef<float, 3>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderSDF(const BitmapRef<float, 3> &output, const BitmapConstRef<float, 3> &sdf, Range sdfPxRange, float sdThreshold) {
|
void renderSDF(const BitmapSection<float, 3> &output, const BitmapConstSection<float, 3> &sdf, Range sdfPxRange, float sdThreshold) {
|
||||||
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
|
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
|
||||||
if (sdfPxRange.lower == sdfPxRange.upper) {
|
if (sdfPxRange.lower == sdfPxRange.upper) {
|
||||||
for (int y = 0; y < output.height; ++y) {
|
for (int y = 0; y < output.height; ++y) {
|
||||||
@@ -119,7 +119,7 @@ void renderSDF(const BitmapRef<float, 3> &output, const BitmapConstRef<float, 3>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderSDF(const BitmapRef<float, 1> &output, const BitmapConstRef<float, 4> &sdf, Range sdfPxRange, float sdThreshold) {
|
void renderSDF(const BitmapSection<float, 1> &output, const BitmapConstSection<float, 4> &sdf, Range sdfPxRange, float sdThreshold) {
|
||||||
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
|
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
|
||||||
if (sdfPxRange.lower == sdfPxRange.upper) {
|
if (sdfPxRange.lower == sdfPxRange.upper) {
|
||||||
for (int y = 0; y < output.height; ++y) {
|
for (int y = 0; y < output.height; ++y) {
|
||||||
@@ -143,7 +143,7 @@ void renderSDF(const BitmapRef<float, 1> &output, const BitmapConstRef<float, 4>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderSDF(const BitmapRef<float, 4> &output, const BitmapConstRef<float, 4> &sdf, Range sdfPxRange, float sdThreshold) {
|
void renderSDF(const BitmapSection<float, 4> &output, const BitmapConstSection<float, 4> &sdf, Range sdfPxRange, float sdThreshold) {
|
||||||
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
|
Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height);
|
||||||
if (sdfPxRange.lower == sdfPxRange.upper) {
|
if (sdfPxRange.lower == sdfPxRange.upper) {
|
||||||
for (int y = 0; y < output.height; ++y) {
|
for (int y = 0; y < output.height; ++y) {
|
||||||
@@ -173,19 +173,19 @@ void renderSDF(const BitmapRef<float, 4> &output, const BitmapConstRef<float, 4>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void simulate8bit(const BitmapRef<float, 1> &bitmap) {
|
void simulate8bit(const BitmapSection<float, 1> &bitmap) {
|
||||||
const float *end = bitmap.pixels+1*bitmap.width*bitmap.height;
|
const float *end = bitmap.pixels+1*bitmap.width*bitmap.height;
|
||||||
for (float *p = bitmap.pixels; p < end; ++p)
|
for (float *p = bitmap.pixels; p < end; ++p)
|
||||||
*p = pixelByteToFloat(pixelFloatToByte(*p));
|
*p = pixelByteToFloat(pixelFloatToByte(*p));
|
||||||
}
|
}
|
||||||
|
|
||||||
void simulate8bit(const BitmapRef<float, 3> &bitmap) {
|
void simulate8bit(const BitmapSection<float, 3> &bitmap) {
|
||||||
const float *end = bitmap.pixels+3*bitmap.width*bitmap.height;
|
const float *end = bitmap.pixels+3*bitmap.width*bitmap.height;
|
||||||
for (float *p = bitmap.pixels; p < end; ++p)
|
for (float *p = bitmap.pixels; p < end; ++p)
|
||||||
*p = pixelByteToFloat(pixelFloatToByte(*p));
|
*p = pixelByteToFloat(pixelFloatToByte(*p));
|
||||||
}
|
}
|
||||||
|
|
||||||
void simulate8bit(const BitmapRef<float, 4> &bitmap) {
|
void simulate8bit(const BitmapSection<float, 4> &bitmap) {
|
||||||
const float *end = bitmap.pixels+4*bitmap.width*bitmap.height;
|
const float *end = bitmap.pixels+4*bitmap.width*bitmap.height;
|
||||||
for (float *p = bitmap.pixels; p < end; ++p)
|
for (float *p = bitmap.pixels; p < end; ++p)
|
||||||
*p = pixelByteToFloat(pixelFloatToByte(*p));
|
*p = pixelByteToFloat(pixelFloatToByte(*p));
|
||||||
|
|||||||
18
thirdparty/msdfgen/core/render-sdf.h
vendored
18
thirdparty/msdfgen/core/render-sdf.h
vendored
@@ -8,16 +8,16 @@
|
|||||||
namespace msdfgen {
|
namespace msdfgen {
|
||||||
|
|
||||||
/// Reconstructs the shape's appearance into output from the distance field sdf.
|
/// Reconstructs the shape's appearance into output from the distance field sdf.
|
||||||
void renderSDF(const BitmapRef<float, 1> &output, const BitmapConstRef<float, 1> &sdf, Range sdfPxRange = 0, float sdThreshold = .5f);
|
void renderSDF(const BitmapSection<float, 1> &output, const BitmapConstSection<float, 1> &sdf, Range sdfPxRange = 0, float sdThreshold = .5f);
|
||||||
void renderSDF(const BitmapRef<float, 3> &output, const BitmapConstRef<float, 1> &sdf, Range sdfPxRange = 0, float sdThreshold = .5f);
|
void renderSDF(const BitmapSection<float, 3> &output, const BitmapConstSection<float, 1> &sdf, Range sdfPxRange = 0, float sdThreshold = .5f);
|
||||||
void renderSDF(const BitmapRef<float, 1> &output, const BitmapConstRef<float, 3> &sdf, Range sdfPxRange = 0, float sdThreshold = .5f);
|
void renderSDF(const BitmapSection<float, 1> &output, const BitmapConstSection<float, 3> &sdf, Range sdfPxRange = 0, float sdThreshold = .5f);
|
||||||
void renderSDF(const BitmapRef<float, 3> &output, const BitmapConstRef<float, 3> &sdf, Range sdfPxRange = 0, float sdThreshold = .5f);
|
void renderSDF(const BitmapSection<float, 3> &output, const BitmapConstSection<float, 3> &sdf, Range sdfPxRange = 0, float sdThreshold = .5f);
|
||||||
void renderSDF(const BitmapRef<float, 1> &output, const BitmapConstRef<float, 4> &sdf, Range sdfPxRange = 0, float sdThreshold = .5f);
|
void renderSDF(const BitmapSection<float, 1> &output, const BitmapConstSection<float, 4> &sdf, Range sdfPxRange = 0, float sdThreshold = .5f);
|
||||||
void renderSDF(const BitmapRef<float, 4> &output, const BitmapConstRef<float, 4> &sdf, Range sdfPxRange = 0, float sdThreshold = .5f);
|
void renderSDF(const BitmapSection<float, 4> &output, const BitmapConstSection<float, 4> &sdf, Range sdfPxRange = 0, float sdThreshold = .5f);
|
||||||
|
|
||||||
/// Snaps the values of the floating-point bitmaps into one of the 256 values representable in a standard 8-bit bitmap.
|
/// Snaps the values of the floating-point bitmaps into one of the 256 values representable in a standard 8-bit bitmap.
|
||||||
void simulate8bit(const BitmapRef<float, 1> &bitmap);
|
void simulate8bit(const BitmapSection<float, 1> &bitmap);
|
||||||
void simulate8bit(const BitmapRef<float, 3> &bitmap);
|
void simulate8bit(const BitmapSection<float, 3> &bitmap);
|
||||||
void simulate8bit(const BitmapRef<float, 4> &bitmap);
|
void simulate8bit(const BitmapSection<float, 4> &bitmap);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
173
thirdparty/msdfgen/core/save-bmp.cpp
vendored
173
thirdparty/msdfgen/core/save-bmp.cpp
vendored
@@ -1,173 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "save-bmp.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
#ifdef MSDFGEN_USE_CPP11
|
|
||||||
#include <cstdint>
|
|
||||||
#else
|
|
||||||
namespace msdfgen {
|
|
||||||
typedef int int32_t;
|
|
||||||
typedef unsigned uint32_t;
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pixel-conversion.hpp"
|
|
||||||
|
|
||||||
namespace msdfgen {
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static bool writeValue(FILE *file, T value) {
|
|
||||||
#ifdef __BIG_ENDIAN__
|
|
||||||
T reverse = 0;
|
|
||||||
for (int i = 0; i < sizeof(T); ++i) {
|
|
||||||
reverse <<= 8;
|
|
||||||
reverse |= value&T(0xff);
|
|
||||||
value >>= 8;
|
|
||||||
}
|
|
||||||
return fwrite(&reverse, sizeof(T), 1, file) == 1;
|
|
||||||
#else
|
|
||||||
return fwrite(&value, sizeof(T), 1, file) == 1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool writeBmpHeader(FILE *file, int width, int height, int &paddedWidth) {
|
|
||||||
paddedWidth = (3*width+3)&~3;
|
|
||||||
const uint32_t bitmapStart = 54;
|
|
||||||
const uint32_t bitmapSize = paddedWidth*height;
|
|
||||||
const uint32_t fileSize = bitmapStart+bitmapSize;
|
|
||||||
|
|
||||||
writeValue<uint16_t>(file, 0x4d42u);
|
|
||||||
writeValue<uint32_t>(file, fileSize);
|
|
||||||
writeValue<uint16_t>(file, 0);
|
|
||||||
writeValue<uint16_t>(file, 0);
|
|
||||||
writeValue<uint32_t>(file, bitmapStart);
|
|
||||||
|
|
||||||
writeValue<uint32_t>(file, 40);
|
|
||||||
writeValue<int32_t>(file, width);
|
|
||||||
writeValue<int32_t>(file, height);
|
|
||||||
writeValue<uint16_t>(file, 1);
|
|
||||||
writeValue<uint16_t>(file, 24);
|
|
||||||
writeValue<uint32_t>(file, 0);
|
|
||||||
writeValue<uint32_t>(file, bitmapSize);
|
|
||||||
writeValue<uint32_t>(file, 2835);
|
|
||||||
writeValue<uint32_t>(file, 2835);
|
|
||||||
writeValue<uint32_t>(file, 0);
|
|
||||||
writeValue<uint32_t>(file, 0);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveBmp(const BitmapConstRef<byte, 1> &bitmap, const char *filename) {
|
|
||||||
FILE *file = fopen(filename, "wb");
|
|
||||||
if (!file)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int paddedWidth;
|
|
||||||
writeBmpHeader(file, bitmap.width, bitmap.height, paddedWidth);
|
|
||||||
|
|
||||||
const uint8_t padding[4] = { };
|
|
||||||
int padLength = paddedWidth-3*bitmap.width;
|
|
||||||
for (int y = 0; y < bitmap.height; ++y) {
|
|
||||||
for (int x = 0; x < bitmap.width; ++x) {
|
|
||||||
uint8_t px = (uint8_t) *bitmap(x, y);
|
|
||||||
fwrite(&px, sizeof(uint8_t), 1, file);
|
|
||||||
fwrite(&px, sizeof(uint8_t), 1, file);
|
|
||||||
fwrite(&px, sizeof(uint8_t), 1, file);
|
|
||||||
}
|
|
||||||
fwrite(padding, 1, padLength, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !fclose(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveBmp(const BitmapConstRef<byte, 3> &bitmap, const char *filename) {
|
|
||||||
FILE *file = fopen(filename, "wb");
|
|
||||||
if (!file)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int paddedWidth;
|
|
||||||
writeBmpHeader(file, bitmap.width, bitmap.height, paddedWidth);
|
|
||||||
|
|
||||||
const uint8_t padding[4] = { };
|
|
||||||
int padLength = paddedWidth-3*bitmap.width;
|
|
||||||
for (int y = 0; y < bitmap.height; ++y) {
|
|
||||||
for (int x = 0; x < bitmap.width; ++x) {
|
|
||||||
uint8_t bgr[3] = {
|
|
||||||
(uint8_t) bitmap(x, y)[2],
|
|
||||||
(uint8_t) bitmap(x, y)[1],
|
|
||||||
(uint8_t) bitmap(x, y)[0]
|
|
||||||
};
|
|
||||||
fwrite(bgr, sizeof(uint8_t), 3, file);
|
|
||||||
}
|
|
||||||
fwrite(padding, 1, padLength, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !fclose(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveBmp(const BitmapConstRef<byte, 4> &bitmap, const char *filename) {
|
|
||||||
// RGBA not supported by the BMP format
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveBmp(const BitmapConstRef<float, 1> &bitmap, const char *filename) {
|
|
||||||
FILE *file = fopen(filename, "wb");
|
|
||||||
if (!file)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int paddedWidth;
|
|
||||||
writeBmpHeader(file, bitmap.width, bitmap.height, paddedWidth);
|
|
||||||
|
|
||||||
const uint8_t padding[4] = { };
|
|
||||||
int padLength = paddedWidth-3*bitmap.width;
|
|
||||||
for (int y = 0; y < bitmap.height; ++y) {
|
|
||||||
for (int x = 0; x < bitmap.width; ++x) {
|
|
||||||
uint8_t px = (uint8_t) pixelFloatToByte(*bitmap(x, y));
|
|
||||||
fwrite(&px, sizeof(uint8_t), 1, file);
|
|
||||||
fwrite(&px, sizeof(uint8_t), 1, file);
|
|
||||||
fwrite(&px, sizeof(uint8_t), 1, file);
|
|
||||||
}
|
|
||||||
fwrite(padding, 1, padLength, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !fclose(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveBmp(const BitmapConstRef<float, 3> &bitmap, const char *filename) {
|
|
||||||
FILE *file = fopen(filename, "wb");
|
|
||||||
if (!file)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int paddedWidth;
|
|
||||||
writeBmpHeader(file, bitmap.width, bitmap.height, paddedWidth);
|
|
||||||
|
|
||||||
const uint8_t padding[4] = { };
|
|
||||||
int padLength = paddedWidth-3*bitmap.width;
|
|
||||||
for (int y = 0; y < bitmap.height; ++y) {
|
|
||||||
for (int x = 0; x < bitmap.width; ++x) {
|
|
||||||
uint8_t bgr[3] = {
|
|
||||||
(uint8_t) pixelFloatToByte(bitmap(x, y)[2]),
|
|
||||||
(uint8_t) pixelFloatToByte(bitmap(x, y)[1]),
|
|
||||||
(uint8_t) pixelFloatToByte(bitmap(x, y)[0])
|
|
||||||
};
|
|
||||||
fwrite(bgr, sizeof(uint8_t), 3, file);
|
|
||||||
}
|
|
||||||
fwrite(padding, 1, padLength, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !fclose(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveBmp(const BitmapConstRef<float, 4> &bitmap, const char *filename) {
|
|
||||||
// RGBA not supported by the BMP format
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
16
thirdparty/msdfgen/core/save-bmp.h
vendored
16
thirdparty/msdfgen/core/save-bmp.h
vendored
@@ -1,16 +0,0 @@
|
|||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "BitmapRef.hpp"
|
|
||||||
|
|
||||||
namespace msdfgen {
|
|
||||||
|
|
||||||
/// Saves the bitmap as a BMP file.
|
|
||||||
bool saveBmp(const BitmapConstRef<byte, 1> &bitmap, const char *filename);
|
|
||||||
bool saveBmp(const BitmapConstRef<byte, 3> &bitmap, const char *filename);
|
|
||||||
bool saveBmp(const BitmapConstRef<byte, 4> &bitmap, const char *filename);
|
|
||||||
bool saveBmp(const BitmapConstRef<float, 1> &bitmap, const char *filename);
|
|
||||||
bool saveBmp(const BitmapConstRef<float, 3> &bitmap, const char *filename);
|
|
||||||
bool saveBmp(const BitmapConstRef<float, 4> &bitmap, const char *filename);
|
|
||||||
|
|
||||||
}
|
|
||||||
39
thirdparty/msdfgen/core/save-fl32.cpp
vendored
39
thirdparty/msdfgen/core/save-fl32.cpp
vendored
@@ -1,39 +0,0 @@
|
|||||||
|
|
||||||
#include "save-fl32.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
namespace msdfgen {
|
|
||||||
|
|
||||||
// Requires byte reversal for floats on big-endian platform
|
|
||||||
#ifndef __BIG_ENDIAN__
|
|
||||||
|
|
||||||
template <int N>
|
|
||||||
bool saveFl32(const BitmapConstRef<float, N> &bitmap, const char *filename) {
|
|
||||||
if (FILE *f = fopen(filename, "wb")) {
|
|
||||||
byte header[16] = { byte('F'), byte('L'), byte('3'), byte('2') };
|
|
||||||
header[4] = byte(bitmap.height);
|
|
||||||
header[5] = byte(bitmap.height>>8);
|
|
||||||
header[6] = byte(bitmap.height>>16);
|
|
||||||
header[7] = byte(bitmap.height>>24);
|
|
||||||
header[8] = byte(bitmap.width);
|
|
||||||
header[9] = byte(bitmap.width>>8);
|
|
||||||
header[10] = byte(bitmap.width>>16);
|
|
||||||
header[11] = byte(bitmap.width>>24);
|
|
||||||
header[12] = byte(N);
|
|
||||||
fwrite(header, 1, 16, f);
|
|
||||||
fwrite(bitmap.pixels, sizeof(float), N*bitmap.width*bitmap.height, f);
|
|
||||||
fclose(f);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template bool saveFl32(const BitmapConstRef<float, 1> &bitmap, const char *filename);
|
|
||||||
template bool saveFl32(const BitmapConstRef<float, 2> &bitmap, const char *filename);
|
|
||||||
template bool saveFl32(const BitmapConstRef<float, 3> &bitmap, const char *filename);
|
|
||||||
template bool saveFl32(const BitmapConstRef<float, 4> &bitmap, const char *filename);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
12
thirdparty/msdfgen/core/save-fl32.h
vendored
12
thirdparty/msdfgen/core/save-fl32.h
vendored
@@ -1,12 +0,0 @@
|
|||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "BitmapRef.hpp"
|
|
||||||
|
|
||||||
namespace msdfgen {
|
|
||||||
|
|
||||||
/// Saves the bitmap as an uncompressed floating-point FL32 file, which can be decoded trivially.
|
|
||||||
template <int N>
|
|
||||||
bool saveFl32(const BitmapConstRef<float, N> &bitmap, const char *filename);
|
|
||||||
|
|
||||||
}
|
|
||||||
133
thirdparty/msdfgen/core/save-rgba.cpp
vendored
133
thirdparty/msdfgen/core/save-rgba.cpp
vendored
@@ -1,133 +0,0 @@
|
|||||||
|
|
||||||
#include "save-rgba.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include "pixel-conversion.hpp"
|
|
||||||
|
|
||||||
namespace msdfgen {
|
|
||||||
|
|
||||||
class RgbaFileOutput {
|
|
||||||
FILE *file;
|
|
||||||
|
|
||||||
public:
|
|
||||||
RgbaFileOutput(const char *filename, unsigned width, unsigned height) {
|
|
||||||
if ((file = fopen(filename, "wb"))) {
|
|
||||||
byte header[12] = { byte('R'), byte('G'), byte('B'), byte('A') };
|
|
||||||
header[4] = byte(width>>24);
|
|
||||||
header[5] = byte(width>>16);
|
|
||||||
header[6] = byte(width>>8);
|
|
||||||
header[7] = byte(width);
|
|
||||||
header[8] = byte(height>>24);
|
|
||||||
header[9] = byte(height>>16);
|
|
||||||
header[10] = byte(height>>8);
|
|
||||||
header[11] = byte(height);
|
|
||||||
fwrite(header, 1, 12, file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~RgbaFileOutput() {
|
|
||||||
if (file)
|
|
||||||
fclose(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
void writePixel(const byte rgba[4]) {
|
|
||||||
fwrite(rgba, 1, 4, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator FILE *() {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
bool saveRgba(const BitmapConstRef<byte, 1> &bitmap, const char *filename) {
|
|
||||||
RgbaFileOutput output(filename, bitmap.width, bitmap.height);
|
|
||||||
if (output) {
|
|
||||||
byte rgba[4] = { byte(0), byte(0), byte(0), byte(0xff) };
|
|
||||||
for (int y = bitmap.height; y--;) {
|
|
||||||
for (const byte *p = bitmap(0, y), *end = p+bitmap.width; p < end; ++p) {
|
|
||||||
rgba[0] = rgba[1] = rgba[2] = *p;
|
|
||||||
output.writePixel(rgba);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveRgba(const BitmapConstRef<byte, 3> &bitmap, const char *filename) {
|
|
||||||
RgbaFileOutput output(filename, bitmap.width, bitmap.height);
|
|
||||||
if (output) {
|
|
||||||
byte rgba[4] = { byte(0), byte(0), byte(0), byte(0xff) };
|
|
||||||
for (int y = bitmap.height; y--;) {
|
|
||||||
for (const byte *p = bitmap(0, y), *end = p+3*bitmap.width; p < end; p += 3) {
|
|
||||||
rgba[0] = p[0], rgba[1] = p[1], rgba[2] = p[2];
|
|
||||||
output.writePixel(rgba);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveRgba(const BitmapConstRef<byte, 4> &bitmap, const char *filename) {
|
|
||||||
RgbaFileOutput output(filename, bitmap.width, bitmap.height);
|
|
||||||
if (output) {
|
|
||||||
for (int y = bitmap.height; y--;)
|
|
||||||
fwrite(bitmap(0, y), 1, 4*bitmap.width, output);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveRgba(const BitmapConstRef<float, 1> &bitmap, const char *filename) {
|
|
||||||
RgbaFileOutput output(filename, bitmap.width, bitmap.height);
|
|
||||||
if (output) {
|
|
||||||
byte rgba[4] = { byte(0), byte(0), byte(0), byte(0xff) };
|
|
||||||
for (int y = bitmap.height; y--;) {
|
|
||||||
for (const float *p = bitmap(0, y), *end = p+bitmap.width; p < end; ++p) {
|
|
||||||
rgba[0] = rgba[1] = rgba[2] = pixelFloatToByte(*p);
|
|
||||||
output.writePixel(rgba);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveRgba(const BitmapConstRef<float, 3> &bitmap, const char *filename) {
|
|
||||||
RgbaFileOutput output(filename, bitmap.width, bitmap.height);
|
|
||||||
if (output) {
|
|
||||||
byte rgba[4] = { byte(0), byte(0), byte(0), byte(0xff) };
|
|
||||||
for (int y = bitmap.height; y--;) {
|
|
||||||
for (const float *p = bitmap(0, y), *end = p+3*bitmap.width; p < end; p += 3) {
|
|
||||||
rgba[0] = pixelFloatToByte(p[0]);
|
|
||||||
rgba[1] = pixelFloatToByte(p[1]);
|
|
||||||
rgba[2] = pixelFloatToByte(p[2]);
|
|
||||||
output.writePixel(rgba);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveRgba(const BitmapConstRef<float, 4> &bitmap, const char *filename) {
|
|
||||||
RgbaFileOutput output(filename, bitmap.width, bitmap.height);
|
|
||||||
if (output) {
|
|
||||||
byte rgba[4];
|
|
||||||
for (int y = bitmap.height; y--;) {
|
|
||||||
for (const float *p = bitmap(0, y), *end = p+4*bitmap.width; p < end; p += 4) {
|
|
||||||
rgba[0] = pixelFloatToByte(p[0]);
|
|
||||||
rgba[1] = pixelFloatToByte(p[1]);
|
|
||||||
rgba[2] = pixelFloatToByte(p[2]);
|
|
||||||
rgba[3] = pixelFloatToByte(p[3]);
|
|
||||||
output.writePixel(rgba);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
16
thirdparty/msdfgen/core/save-rgba.h
vendored
16
thirdparty/msdfgen/core/save-rgba.h
vendored
@@ -1,16 +0,0 @@
|
|||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "BitmapRef.hpp"
|
|
||||||
|
|
||||||
namespace msdfgen {
|
|
||||||
|
|
||||||
/// Saves the bitmap as a simple RGBA file, which can be decoded trivially.
|
|
||||||
bool saveRgba(const BitmapConstRef<byte, 1> &bitmap, const char *filename);
|
|
||||||
bool saveRgba(const BitmapConstRef<byte, 3> &bitmap, const char *filename);
|
|
||||||
bool saveRgba(const BitmapConstRef<byte, 4> &bitmap, const char *filename);
|
|
||||||
bool saveRgba(const BitmapConstRef<float, 1> &bitmap, const char *filename);
|
|
||||||
bool saveRgba(const BitmapConstRef<float, 3> &bitmap, const char *filename);
|
|
||||||
bool saveRgba(const BitmapConstRef<float, 4> &bitmap, const char *filename);
|
|
||||||
|
|
||||||
}
|
|
||||||
194
thirdparty/msdfgen/core/save-tiff.cpp
vendored
194
thirdparty/msdfgen/core/save-tiff.cpp
vendored
@@ -1,194 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "save-tiff.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
#ifdef MSDFGEN_USE_CPP11
|
|
||||||
#include <cstdint>
|
|
||||||
#else
|
|
||||||
namespace msdfgen {
|
|
||||||
typedef int int32_t;
|
|
||||||
typedef unsigned uint32_t;
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace msdfgen {
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static bool writeValue(FILE *file, T value) {
|
|
||||||
return fwrite(&value, sizeof(T), 1, file) == 1;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
static void writeValueRepeated(FILE *file, T value, int times) {
|
|
||||||
for (int i = 0; i < times; ++i)
|
|
||||||
writeValue(file, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool writeTiffHeader(FILE *file, int width, int height, int channels) {
|
|
||||||
#ifdef __BIG_ENDIAN__
|
|
||||||
writeValue<uint16_t>(file, 0x4d4du);
|
|
||||||
#else
|
|
||||||
writeValue<uint16_t>(file, 0x4949u);
|
|
||||||
#endif
|
|
||||||
writeValue<uint16_t>(file, 42);
|
|
||||||
writeValue<uint32_t>(file, 0x0008u); // Offset of first IFD
|
|
||||||
// Offset = 0x0008
|
|
||||||
|
|
||||||
writeValue<uint16_t>(file, 15); // Number of IFD entries
|
|
||||||
|
|
||||||
// ImageWidth
|
|
||||||
writeValue<uint16_t>(file, 0x0100u);
|
|
||||||
writeValue<uint16_t>(file, 0x0004u);
|
|
||||||
writeValue<uint32_t>(file, 1);
|
|
||||||
writeValue<int32_t>(file, width);
|
|
||||||
// ImageLength
|
|
||||||
writeValue<uint16_t>(file, 0x0101u);
|
|
||||||
writeValue<uint16_t>(file, 0x0004u);
|
|
||||||
writeValue<uint32_t>(file, 1);
|
|
||||||
writeValue<int32_t>(file, height);
|
|
||||||
// BitsPerSample
|
|
||||||
writeValue<uint16_t>(file, 0x0102u);
|
|
||||||
writeValue<uint16_t>(file, 0x0003u);
|
|
||||||
writeValue<uint32_t>(file, channels);
|
|
||||||
if (channels > 1)
|
|
||||||
writeValue<uint32_t>(file, 0x00c2u); // Offset of 32, 32, ...
|
|
||||||
else {
|
|
||||||
writeValue<uint16_t>(file, 32);
|
|
||||||
writeValue<uint16_t>(file, 0);
|
|
||||||
}
|
|
||||||
// Compression
|
|
||||||
writeValue<uint16_t>(file, 0x0103u);
|
|
||||||
writeValue<uint16_t>(file, 0x0003u);
|
|
||||||
writeValue<uint32_t>(file, 1);
|
|
||||||
writeValue<uint16_t>(file, 1);
|
|
||||||
writeValue<uint16_t>(file, 0);
|
|
||||||
// PhotometricInterpretation
|
|
||||||
writeValue<uint16_t>(file, 0x0106u);
|
|
||||||
writeValue<uint16_t>(file, 0x0003u);
|
|
||||||
writeValue<uint32_t>(file, 1);
|
|
||||||
writeValue<uint16_t>(file, channels >= 3 ? 2 : 1);
|
|
||||||
writeValue<uint16_t>(file, 0);
|
|
||||||
// StripOffsets
|
|
||||||
writeValue<uint16_t>(file, 0x0111u);
|
|
||||||
writeValue<uint16_t>(file, 0x0004u);
|
|
||||||
writeValue<uint32_t>(file, 1);
|
|
||||||
writeValue<uint32_t>(file, 0x00d2u+(channels > 1)*channels*12); // Offset of pixel data
|
|
||||||
// SamplesPerPixel
|
|
||||||
writeValue<uint16_t>(file, 0x0115u);
|
|
||||||
writeValue<uint16_t>(file, 0x0003u);
|
|
||||||
writeValue<uint32_t>(file, 1);
|
|
||||||
writeValue<uint16_t>(file, channels);
|
|
||||||
writeValue<uint16_t>(file, 0);
|
|
||||||
// RowsPerStrip
|
|
||||||
writeValue<uint16_t>(file, 0x0116u);
|
|
||||||
writeValue<uint16_t>(file, 0x0004u);
|
|
||||||
writeValue<uint32_t>(file, 1);
|
|
||||||
writeValue<int32_t>(file, height);
|
|
||||||
// StripByteCounts
|
|
||||||
writeValue<uint16_t>(file, 0x0117u);
|
|
||||||
writeValue<uint16_t>(file, 0x0004u);
|
|
||||||
writeValue<uint32_t>(file, 1);
|
|
||||||
writeValue<int32_t>(file, sizeof(float)*channels*width*height);
|
|
||||||
// XResolution
|
|
||||||
writeValue<uint16_t>(file, 0x011au);
|
|
||||||
writeValue<uint16_t>(file, 0x0005u);
|
|
||||||
writeValue<uint32_t>(file, 1);
|
|
||||||
writeValue<uint32_t>(file, 0x00c2u+(channels > 1)*channels*2); // Offset of 300, 1
|
|
||||||
// YResolution
|
|
||||||
writeValue<uint16_t>(file, 0x011bu);
|
|
||||||
writeValue<uint16_t>(file, 0x0005u);
|
|
||||||
writeValue<uint32_t>(file, 1);
|
|
||||||
writeValue<uint32_t>(file, 0x00cau+(channels > 1)*channels*2); // Offset of 300, 1
|
|
||||||
// ResolutionUnit
|
|
||||||
writeValue<uint16_t>(file, 0x0128u);
|
|
||||||
writeValue<uint16_t>(file, 0x0003u);
|
|
||||||
writeValue<uint32_t>(file, 1);
|
|
||||||
writeValue<uint16_t>(file, 2);
|
|
||||||
writeValue<uint16_t>(file, 0);
|
|
||||||
// SampleFormat
|
|
||||||
writeValue<uint16_t>(file, 0x0153u);
|
|
||||||
writeValue<uint16_t>(file, 0x0003u);
|
|
||||||
writeValue<uint32_t>(file, channels);
|
|
||||||
if (channels > 1)
|
|
||||||
writeValue<uint32_t>(file, 0x00d2u+channels*2); // Offset of 3, 3, ...
|
|
||||||
else {
|
|
||||||
writeValue<uint16_t>(file, 3);
|
|
||||||
writeValue<uint16_t>(file, 0);
|
|
||||||
}
|
|
||||||
// SMinSampleValue
|
|
||||||
writeValue<uint16_t>(file, 0x0154u);
|
|
||||||
writeValue<uint16_t>(file, 0x000bu);
|
|
||||||
writeValue<uint32_t>(file, channels);
|
|
||||||
if (channels > 1)
|
|
||||||
writeValue<uint32_t>(file, 0x00d2u+channels*4); // Offset of 0.f, 0.f, ...
|
|
||||||
else
|
|
||||||
writeValue<float>(file, 0.f);
|
|
||||||
// SMaxSampleValue
|
|
||||||
writeValue<uint16_t>(file, 0x0155u);
|
|
||||||
writeValue<uint16_t>(file, 0x000bu);
|
|
||||||
writeValue<uint32_t>(file, channels);
|
|
||||||
if (channels > 1)
|
|
||||||
writeValue<uint32_t>(file, 0x00d2u+channels*8); // Offset of 1.f, 1.f, ...
|
|
||||||
else
|
|
||||||
writeValue<float>(file, 1.f);
|
|
||||||
// Offset = 0x00be
|
|
||||||
|
|
||||||
writeValue<uint32_t>(file, 0);
|
|
||||||
|
|
||||||
if (channels > 1) {
|
|
||||||
// 0x00c2 BitsPerSample data
|
|
||||||
writeValueRepeated<uint16_t>(file, 32, channels);
|
|
||||||
// 0x00c2 + 2*N XResolution data
|
|
||||||
writeValue<uint32_t>(file, 300);
|
|
||||||
writeValue<uint32_t>(file, 1);
|
|
||||||
// 0x00ca + 2*N YResolution data
|
|
||||||
writeValue<uint32_t>(file, 300);
|
|
||||||
writeValue<uint32_t>(file, 1);
|
|
||||||
// 0x00d2 + 2*N SampleFormat data
|
|
||||||
writeValueRepeated<uint16_t>(file, 3, channels);
|
|
||||||
// 0x00d2 + 4*N SMinSampleValue data
|
|
||||||
writeValueRepeated<float>(file, 0.f, channels);
|
|
||||||
// 0x00d2 + 8*N SMaxSampleValue data
|
|
||||||
writeValueRepeated<float>(file, 1.f, channels);
|
|
||||||
// Offset = 0x00d2 + 12*N
|
|
||||||
} else {
|
|
||||||
// 0x00c2 XResolution data
|
|
||||||
writeValue<uint32_t>(file, 300);
|
|
||||||
writeValue<uint32_t>(file, 1);
|
|
||||||
// 0x00ca YResolution data
|
|
||||||
writeValue<uint32_t>(file, 300);
|
|
||||||
writeValue<uint32_t>(file, 1);
|
|
||||||
// Offset = 0x00d2
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int N>
|
|
||||||
bool saveTiffFloat(const BitmapConstRef<float, N> &bitmap, const char *filename) {
|
|
||||||
FILE *file = fopen(filename, "wb");
|
|
||||||
if (!file)
|
|
||||||
return false;
|
|
||||||
writeTiffHeader(file, bitmap.width, bitmap.height, N);
|
|
||||||
for (int y = bitmap.height-1; y >= 0; --y)
|
|
||||||
fwrite(bitmap(0, y), sizeof(float), N*bitmap.width, file);
|
|
||||||
return !fclose(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveTiff(const BitmapConstRef<float, 1> &bitmap, const char *filename) {
|
|
||||||
return saveTiffFloat(bitmap, filename);
|
|
||||||
}
|
|
||||||
bool saveTiff(const BitmapConstRef<float, 3> &bitmap, const char *filename) {
|
|
||||||
return saveTiffFloat(bitmap, filename);
|
|
||||||
}
|
|
||||||
bool saveTiff(const BitmapConstRef<float, 4> &bitmap, const char *filename) {
|
|
||||||
return saveTiffFloat(bitmap, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
13
thirdparty/msdfgen/core/save-tiff.h
vendored
13
thirdparty/msdfgen/core/save-tiff.h
vendored
@@ -1,13 +0,0 @@
|
|||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "BitmapRef.hpp"
|
|
||||||
|
|
||||||
namespace msdfgen {
|
|
||||||
|
|
||||||
/// Saves the bitmap as an uncompressed floating-point TIFF file.
|
|
||||||
bool saveTiff(const BitmapConstRef<float, 1> &bitmap, const char *filename);
|
|
||||||
bool saveTiff(const BitmapConstRef<float, 3> &bitmap, const char *filename);
|
|
||||||
bool saveTiff(const BitmapConstRef<float, 4> &bitmap, const char *filename);
|
|
||||||
|
|
||||||
}
|
|
||||||
50
thirdparty/msdfgen/core/sdf-error-estimation.cpp
vendored
50
thirdparty/msdfgen/core/sdf-error-estimation.cpp
vendored
@@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
namespace msdfgen {
|
namespace msdfgen {
|
||||||
|
|
||||||
void scanlineSDF(Scanline &line, const BitmapConstRef<float, 1> &sdf, const Projection &projection, double y, bool inverseYAxis) {
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 1> &sdf, const Projection &projection, double y, YAxisOrientation yAxisOrientation) {
|
||||||
if (!(sdf.width > 0 && sdf.height > 0))
|
if (!(sdf.width > 0 && sdf.height > 0))
|
||||||
return line.setIntersections(std::vector<Scanline::Intersection>());
|
return line.setIntersections(std::vector<Scanline::Intersection>());
|
||||||
double pixelY = clamp(projection.projectY(y)-.5, double(sdf.height-1));
|
double pixelY = clamp(projection.projectY(y)-.5, double(sdf.height-1));
|
||||||
if (inverseYAxis)
|
if (yAxisOrientation == Y_DOWNWARD)
|
||||||
pixelY = sdf.height-1-pixelY;
|
pixelY = sdf.height-1-pixelY;
|
||||||
int b = (int) floor(pixelY);
|
int b = (int) floor(pixelY);
|
||||||
int t = b+1;
|
int t = b+1;
|
||||||
@@ -46,11 +46,11 @@ void scanlineSDF(Scanline &line, const BitmapConstRef<float, 1> &sdf, const Proj
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
void scanlineMSDF(Scanline &line, const BitmapConstRef<float, N> &sdf, const Projection &projection, double y, bool inverseYAxis) {
|
void scanlineMSDF(Scanline &line, const BitmapConstSection<float, N> &sdf, const Projection &projection, double y, YAxisOrientation yAxisOrientation) {
|
||||||
if (!(sdf.width > 0 && sdf.height > 0))
|
if (!(sdf.width > 0 && sdf.height > 0))
|
||||||
return line.setIntersections(std::vector<Scanline::Intersection>());
|
return line.setIntersections(std::vector<Scanline::Intersection>());
|
||||||
double pixelY = clamp(projection.projectY(y)-.5, double(sdf.height-1));
|
double pixelY = clamp(projection.projectY(y)-.5, double(sdf.height-1));
|
||||||
if (inverseYAxis)
|
if (yAxisOrientation == Y_DOWNWARD)
|
||||||
pixelY = sdf.height-1-pixelY;
|
pixelY = sdf.height-1-pixelY;
|
||||||
int b = (int) floor(pixelY);
|
int b = (int) floor(pixelY);
|
||||||
int t = b+1;
|
int t = b+1;
|
||||||
@@ -124,15 +124,15 @@ void scanlineMSDF(Scanline &line, const BitmapConstRef<float, N> &sdf, const Pro
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void scanlineSDF(Scanline &line, const BitmapConstRef<float, 3> &sdf, const Projection &projection, double y, bool inverseYAxis) {
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 3> &sdf, const Projection &projection, double y, YAxisOrientation yAxisOrientation) {
|
||||||
scanlineMSDF(line, sdf, projection, y, inverseYAxis);
|
scanlineMSDF(line, sdf, projection, y, yAxisOrientation);
|
||||||
}
|
}
|
||||||
void scanlineSDF(Scanline &line, const BitmapConstRef<float, 4> &sdf, const Projection &projection, double y, bool inverseYAxis) {
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 4> &sdf, const Projection &projection, double y, YAxisOrientation yAxisOrientation) {
|
||||||
scanlineMSDF(line, sdf, projection, y, inverseYAxis);
|
scanlineMSDF(line, sdf, projection, y, yAxisOrientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
double estimateSDFErrorInner(const BitmapConstRef<float, N> &sdf, const Shape &shape, const Projection &projection, int scanlinesPerRow, FillRule fillRule) {
|
double estimateSDFErrorInner(const BitmapConstSection<float, N> &sdf, const Shape &shape, const Projection &projection, int scanlinesPerRow, FillRule fillRule) {
|
||||||
if (sdf.width <= 1 || sdf.height <= 1 || scanlinesPerRow < 1)
|
if (sdf.width <= 1 || sdf.height <= 1 || scanlinesPerRow < 1)
|
||||||
return 0;
|
return 0;
|
||||||
double subRowSize = 1./scanlinesPerRow;
|
double subRowSize = 1./scanlinesPerRow;
|
||||||
@@ -146,46 +146,58 @@ double estimateSDFErrorInner(const BitmapConstRef<float, N> &sdf, const Shape &s
|
|||||||
double bt = (subRow+.5)*subRowSize;
|
double bt = (subRow+.5)*subRowSize;
|
||||||
double y = projection.unprojectY(row+bt+.5);
|
double y = projection.unprojectY(row+bt+.5);
|
||||||
shape.scanline(refScanline, y);
|
shape.scanline(refScanline, y);
|
||||||
scanlineSDF(sdfScanline, sdf, projection, y, shape.inverseYAxis);
|
scanlineSDF(sdfScanline, sdf, projection, y, shape.getYAxisOrientation());
|
||||||
error += 1-overlapFactor*Scanline::overlap(refScanline, sdfScanline, xFrom, xTo, fillRule);
|
error += 1-overlapFactor*Scanline::overlap(refScanline, sdfScanline, xFrom, xTo, fillRule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return error/((sdf.height-1)*scanlinesPerRow);
|
return error/((sdf.height-1)*scanlinesPerRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
double estimateSDFError(const BitmapConstRef<float, 1> &sdf, const Shape &shape, const Projection &projection, int scanlinesPerRow, FillRule fillRule) {
|
double estimateSDFError(const BitmapConstSection<float, 1> &sdf, const Shape &shape, const Projection &projection, int scanlinesPerRow, FillRule fillRule) {
|
||||||
return estimateSDFErrorInner(sdf, shape, projection, scanlinesPerRow, fillRule);
|
return estimateSDFErrorInner(sdf, shape, projection, scanlinesPerRow, fillRule);
|
||||||
}
|
}
|
||||||
double estimateSDFError(const BitmapConstRef<float, 3> &sdf, const Shape &shape, const Projection &projection, int scanlinesPerRow, FillRule fillRule) {
|
double estimateSDFError(const BitmapConstSection<float, 3> &sdf, const Shape &shape, const Projection &projection, int scanlinesPerRow, FillRule fillRule) {
|
||||||
return estimateSDFErrorInner(sdf, shape, projection, scanlinesPerRow, fillRule);
|
return estimateSDFErrorInner(sdf, shape, projection, scanlinesPerRow, fillRule);
|
||||||
}
|
}
|
||||||
double estimateSDFError(const BitmapConstRef<float, 4> &sdf, const Shape &shape, const Projection &projection, int scanlinesPerRow, FillRule fillRule) {
|
double estimateSDFError(const BitmapConstSection<float, 4> &sdf, const Shape &shape, const Projection &projection, int scanlinesPerRow, FillRule fillRule) {
|
||||||
return estimateSDFErrorInner(sdf, shape, projection, scanlinesPerRow, fillRule);
|
return estimateSDFErrorInner(sdf, shape, projection, scanlinesPerRow, fillRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Legacy API
|
// Legacy API
|
||||||
|
|
||||||
void scanlineSDF(Scanline &line, const BitmapConstRef<float, 1> &sdf, const Vector2 &scale, const Vector2 &translate, bool inverseYAxis, double y) {
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 1> &sdf, const Projection &projection, double y, bool inverseYAxis) {
|
||||||
|
scanlineSDF(line, sdf, projection, y, inverseYAxis ? MSDFGEN_Y_AXIS_NONDEFAULT_ORIENTATION : MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 3> &sdf, const Projection &projection, double y, bool inverseYAxis) {
|
||||||
|
scanlineSDF(line, sdf, projection, y, inverseYAxis ? MSDFGEN_Y_AXIS_NONDEFAULT_ORIENTATION : MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 4> &sdf, const Projection &projection, double y, bool inverseYAxis) {
|
||||||
|
scanlineSDF(line, sdf, projection, y, inverseYAxis ? MSDFGEN_Y_AXIS_NONDEFAULT_ORIENTATION : MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 1> &sdf, const Vector2 &scale, const Vector2 &translate, bool inverseYAxis, double y) {
|
||||||
scanlineSDF(line, sdf, Projection(scale, translate), y, inverseYAxis);
|
scanlineSDF(line, sdf, Projection(scale, translate), y, inverseYAxis);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scanlineSDF(Scanline &line, const BitmapConstRef<float, 3> &sdf, const Vector2 &scale, const Vector2 &translate, bool inverseYAxis, double y) {
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 3> &sdf, const Vector2 &scale, const Vector2 &translate, bool inverseYAxis, double y) {
|
||||||
scanlineSDF(line, sdf, Projection(scale, translate), y, inverseYAxis);
|
scanlineSDF(line, sdf, Projection(scale, translate), y, inverseYAxis);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scanlineSDF(Scanline &line, const BitmapConstRef<float, 4> &sdf, const Vector2 &scale, const Vector2 &translate, bool inverseYAxis, double y) {
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 4> &sdf, const Vector2 &scale, const Vector2 &translate, bool inverseYAxis, double y) {
|
||||||
scanlineSDF(line, sdf, Projection(scale, translate), y, inverseYAxis);
|
scanlineSDF(line, sdf, Projection(scale, translate), y, inverseYAxis);
|
||||||
}
|
}
|
||||||
|
|
||||||
double estimateSDFError(const BitmapConstRef<float, 1> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, int scanlinesPerRow, FillRule fillRule) {
|
double estimateSDFError(const BitmapConstSection<float, 1> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, int scanlinesPerRow, FillRule fillRule) {
|
||||||
return estimateSDFError(sdf, shape, Projection(scale, translate), scanlinesPerRow, fillRule);
|
return estimateSDFError(sdf, shape, Projection(scale, translate), scanlinesPerRow, fillRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
double estimateSDFError(const BitmapConstRef<float, 3> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, int scanlinesPerRow, FillRule fillRule) {
|
double estimateSDFError(const BitmapConstSection<float, 3> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, int scanlinesPerRow, FillRule fillRule) {
|
||||||
return estimateSDFError(sdf, shape, Projection(scale, translate), scanlinesPerRow, fillRule);
|
return estimateSDFError(sdf, shape, Projection(scale, translate), scanlinesPerRow, fillRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
double estimateSDFError(const BitmapConstRef<float, 4> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, int scanlinesPerRow, FillRule fillRule) {
|
double estimateSDFError(const BitmapConstSection<float, 4> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, int scanlinesPerRow, FillRule fillRule) {
|
||||||
return estimateSDFError(sdf, shape, Projection(scale, translate), scanlinesPerRow, fillRule);
|
return estimateSDFError(sdf, shape, Projection(scale, translate), scanlinesPerRow, fillRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
27
thirdparty/msdfgen/core/sdf-error-estimation.h
vendored
27
thirdparty/msdfgen/core/sdf-error-estimation.h
vendored
@@ -10,21 +10,24 @@
|
|||||||
namespace msdfgen {
|
namespace msdfgen {
|
||||||
|
|
||||||
/// Analytically constructs a scanline at y evaluating fill by linear interpolation of the SDF.
|
/// Analytically constructs a scanline at y evaluating fill by linear interpolation of the SDF.
|
||||||
void scanlineSDF(Scanline &line, const BitmapConstRef<float, 1> &sdf, const Projection &projection, double y, bool inverseYAxis = false);
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 1> &sdf, const Projection &projection, double y, YAxisOrientation yAxisOrientation = MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION);
|
||||||
void scanlineSDF(Scanline &line, const BitmapConstRef<float, 3> &sdf, const Projection &projection, double y, bool inverseYAxis = false);
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 3> &sdf, const Projection &projection, double y, YAxisOrientation yAxisOrientation = MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION);
|
||||||
void scanlineSDF(Scanline &line, const BitmapConstRef<float, 4> &sdf, const Projection &projection, double y, bool inverseYAxis = false);
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 4> &sdf, const Projection &projection, double y, YAxisOrientation yAxisOrientation = MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION);
|
||||||
|
|
||||||
/// Estimates the portion of the area that will be filled incorrectly when rendering using the SDF.
|
/// Estimates the portion of the area that will be filled incorrectly when rendering using the SDF.
|
||||||
double estimateSDFError(const BitmapConstRef<float, 1> &sdf, const Shape &shape, const Projection &projection, int scanlinesPerRow, FillRule fillRule = FILL_NONZERO);
|
double estimateSDFError(const BitmapConstSection<float, 1> &sdf, const Shape &shape, const Projection &projection, int scanlinesPerRow, FillRule fillRule = FILL_NONZERO);
|
||||||
double estimateSDFError(const BitmapConstRef<float, 3> &sdf, const Shape &shape, const Projection &projection, int scanlinesPerRow, FillRule fillRule = FILL_NONZERO);
|
double estimateSDFError(const BitmapConstSection<float, 3> &sdf, const Shape &shape, const Projection &projection, int scanlinesPerRow, FillRule fillRule = FILL_NONZERO);
|
||||||
double estimateSDFError(const BitmapConstRef<float, 4> &sdf, const Shape &shape, const Projection &projection, int scanlinesPerRow, FillRule fillRule = FILL_NONZERO);
|
double estimateSDFError(const BitmapConstSection<float, 4> &sdf, const Shape &shape, const Projection &projection, int scanlinesPerRow, FillRule fillRule = FILL_NONZERO);
|
||||||
|
|
||||||
// Old version of the function API's kept for backwards compatibility
|
// Old version of the function API's kept for backwards compatibility
|
||||||
void scanlineSDF(Scanline &line, const BitmapConstRef<float, 1> &sdf, const Vector2 &scale, const Vector2 &translate, bool inverseYAxis, double y);
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 1> &sdf, const Projection &projection, double y, bool inverseYAxis);
|
||||||
void scanlineSDF(Scanline &line, const BitmapConstRef<float, 3> &sdf, const Vector2 &scale, const Vector2 &translate, bool inverseYAxis, double y);
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 3> &sdf, const Projection &projection, double y, bool inverseYAxis);
|
||||||
void scanlineSDF(Scanline &line, const BitmapConstRef<float, 4> &sdf, const Vector2 &scale, const Vector2 &translate, bool inverseYAxis, double y);
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 4> &sdf, const Projection &projection, double y, bool inverseYAxis);
|
||||||
double estimateSDFError(const BitmapConstRef<float, 1> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, int scanlinesPerRow, FillRule fillRule = FILL_NONZERO);
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 1> &sdf, const Vector2 &scale, const Vector2 &translate, bool inverseYAxis, double y);
|
||||||
double estimateSDFError(const BitmapConstRef<float, 3> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, int scanlinesPerRow, FillRule fillRule = FILL_NONZERO);
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 3> &sdf, const Vector2 &scale, const Vector2 &translate, bool inverseYAxis, double y);
|
||||||
double estimateSDFError(const BitmapConstRef<float, 4> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, int scanlinesPerRow, FillRule fillRule = FILL_NONZERO);
|
void scanlineSDF(Scanline &line, const BitmapConstSection<float, 4> &sdf, const Vector2 &scale, const Vector2 &translate, bool inverseYAxis, double y);
|
||||||
|
double estimateSDFError(const BitmapConstSection<float, 1> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, int scanlinesPerRow, FillRule fillRule = FILL_NONZERO);
|
||||||
|
double estimateSDFError(const BitmapConstSection<float, 3> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, int scanlinesPerRow, FillRule fillRule = FILL_NONZERO);
|
||||||
|
double estimateSDFError(const BitmapConstSection<float, 4> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, int scanlinesPerRow, FillRule fillRule = FILL_NONZERO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
54
thirdparty/msdfgen/core/shape-description.cpp
vendored
54
thirdparty/msdfgen/core/shape-description.cpp
vendored
@@ -51,6 +51,17 @@ int readCoordS(const char **input, Point2 &coord) {
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool matchStringS(const char **input, const char *str) {
|
||||||
|
const char *cur = *input;
|
||||||
|
while (*cur && *str && *cur == *str)
|
||||||
|
++cur, ++str;
|
||||||
|
if (!*str) {
|
||||||
|
*input = cur;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool writeCoord(FILE *output, Point2 coord) {
|
static bool writeCoord(FILE *output, Point2 coord) {
|
||||||
fprintf(output, "%.12g, %.12g", coord.x, coord.y);
|
fprintf(output, "%.12g, %.12g", coord.x, coord.y);
|
||||||
return true;
|
return true;
|
||||||
@@ -176,7 +187,7 @@ static bool readContour(T *input, Contour &output, const Point2 *first, int term
|
|||||||
bool readShapeDescription(FILE *input, Shape &output, bool *colorsSpecified) {
|
bool readShapeDescription(FILE *input, Shape &output, bool *colorsSpecified) {
|
||||||
bool locColorsSpec = false;
|
bool locColorsSpec = false;
|
||||||
output.contours.clear();
|
output.contours.clear();
|
||||||
output.inverseYAxis = false;
|
output.setYAxisOrientation(MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION);
|
||||||
Point2 p;
|
Point2 p;
|
||||||
int result = readCoordF(input, p);
|
int result = readCoordF(input, p);
|
||||||
if (result == 2) {
|
if (result == 2) {
|
||||||
@@ -187,9 +198,21 @@ bool readShapeDescription(FILE *input, Shape &output, bool *colorsSpecified) {
|
|||||||
int c = readCharF(input);
|
int c = readCharF(input);
|
||||||
if (c == '@') {
|
if (c == '@') {
|
||||||
char after = '\0';
|
char after = '\0';
|
||||||
if (fscanf(input, "invert-y%c", &after) != 1)
|
if (fscanf(input, "y-%c", &after) == 1 && (after == 'u' || after == 'd')) {
|
||||||
|
switch (after) {
|
||||||
|
case 'u':
|
||||||
|
output.setYAxisOrientation(Y_UPWARD);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
output.setYAxisOrientation(Y_DOWNWARD);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (fscanf(input, after == 'u' ? "p%c" : "own%c", &after) != 1)
|
||||||
|
return feof(input) != 0;
|
||||||
|
} else if (fscanf(input, "invert-y%c", &after) == 1)
|
||||||
|
output.inverseYAxis = true;
|
||||||
|
else
|
||||||
return feof(input) != 0;
|
return feof(input) != 0;
|
||||||
output.inverseYAxis = true;
|
|
||||||
c = after;
|
c = after;
|
||||||
if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
|
if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
|
||||||
c = readCharF(input);
|
c = readCharF(input);
|
||||||
@@ -206,7 +229,7 @@ bool readShapeDescription(FILE *input, Shape &output, bool *colorsSpecified) {
|
|||||||
bool readShapeDescription(const char *input, Shape &output, bool *colorsSpecified) {
|
bool readShapeDescription(const char *input, Shape &output, bool *colorsSpecified) {
|
||||||
bool locColorsSpec = false;
|
bool locColorsSpec = false;
|
||||||
output.contours.clear();
|
output.contours.clear();
|
||||||
output.inverseYAxis = false;
|
output.setYAxisOrientation(MSDFGEN_Y_AXIS_DEFAULT_ORIENTATION);
|
||||||
Point2 p;
|
Point2 p;
|
||||||
int result = readCoordS(&input, p);
|
int result = readCoordS(&input, p);
|
||||||
if (result == 2) {
|
if (result == 2) {
|
||||||
@@ -216,11 +239,14 @@ bool readShapeDescription(const char *input, Shape &output, bool *colorsSpecifie
|
|||||||
else {
|
else {
|
||||||
int c = readCharS(&input);
|
int c = readCharS(&input);
|
||||||
if (c == '@') {
|
if (c == '@') {
|
||||||
for (int i = 0; i < (int) sizeof("invert-y")-1; ++i)
|
if (matchStringS(&input, "y-down"))
|
||||||
if (input[i] != "invert-y"[i])
|
output.setYAxisOrientation(Y_DOWNWARD);
|
||||||
return false;
|
else if (matchStringS(&input, "y-up"))
|
||||||
output.inverseYAxis = true;
|
output.setYAxisOrientation(Y_UPWARD);
|
||||||
input += sizeof("invert-y")-1;
|
else if (matchStringS(&input, "invert-y"))
|
||||||
|
output.inverseYAxis = true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
c = readCharS(&input);
|
c = readCharS(&input);
|
||||||
}
|
}
|
||||||
for (; c == '{'; c = readCharS(&input))
|
for (; c == '{'; c = readCharS(&input))
|
||||||
@@ -244,8 +270,14 @@ bool writeShapeDescription(FILE *output, const Shape &shape) {
|
|||||||
if (!shape.validate())
|
if (!shape.validate())
|
||||||
return false;
|
return false;
|
||||||
bool writeColors = isColored(shape);
|
bool writeColors = isColored(shape);
|
||||||
if (shape.inverseYAxis)
|
switch (shape.getYAxisOrientation()) {
|
||||||
fprintf(output, "@invert-y\n");
|
case Y_UPWARD:
|
||||||
|
fprintf(output, "@y-up\n");
|
||||||
|
break;
|
||||||
|
case Y_DOWNWARD:
|
||||||
|
fprintf(output, "@y-down\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
for (std::vector<Contour>::const_iterator contour = shape.contours.begin(); contour != shape.contours.end(); ++contour) {
|
for (std::vector<Contour>::const_iterator contour = shape.contours.begin(); contour != shape.contours.end(); ++contour) {
|
||||||
fprintf(output, "{\n");
|
fprintf(output, "{\n");
|
||||||
if (!contour->edges.empty()) {
|
if (!contour->edges.empty()) {
|
||||||
|
|||||||
43
thirdparty/msdfgen/msdfgen.h
vendored
43
thirdparty/msdfgen/msdfgen.h
vendored
@@ -34,45 +34,40 @@
|
|||||||
#include "core/render-sdf.h"
|
#include "core/render-sdf.h"
|
||||||
#include "core/rasterization.h"
|
#include "core/rasterization.h"
|
||||||
#include "core/sdf-error-estimation.h"
|
#include "core/sdf-error-estimation.h"
|
||||||
#include "core/save-bmp.h"
|
|
||||||
#include "core/save-tiff.h"
|
|
||||||
#include "core/save-rgba.h"
|
|
||||||
#include "core/save-fl32.h"
|
|
||||||
#include "core/shape-description.h"
|
#include "core/shape-description.h"
|
||||||
#include "core/export-svg.h"
|
|
||||||
|
|
||||||
namespace msdfgen {
|
namespace msdfgen {
|
||||||
|
|
||||||
/// Generates a conventional single-channel signed distance field.
|
/// Generates a conventional single-channel signed distance field.
|
||||||
void generateSDF(const BitmapRef<float, 1> &output, const Shape &shape, const SDFTransformation &transformation, const GeneratorConfig &config = GeneratorConfig());
|
void generateSDF(const BitmapSection<float, 1> &output, const Shape &shape, const SDFTransformation &transformation, const GeneratorConfig &config = GeneratorConfig());
|
||||||
|
|
||||||
/// Generates a single-channel signed perpendicular distance field.
|
/// Generates a single-channel signed perpendicular distance field.
|
||||||
void generatePSDF(const BitmapRef<float, 1> &output, const Shape &shape, const SDFTransformation &transformation, const GeneratorConfig &config = GeneratorConfig());
|
void generatePSDF(const BitmapSection<float, 1> &output, const Shape &shape, const SDFTransformation &transformation, const GeneratorConfig &config = GeneratorConfig());
|
||||||
|
|
||||||
/// Generates a multi-channel signed distance field. Edge colors must be assigned first! (See edgeColoringSimple)
|
/// Generates a multi-channel signed distance field. Edge colors must be assigned first! (See edgeColoringSimple)
|
||||||
void generateMSDF(const BitmapRef<float, 3> &output, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
void generateMSDF(const BitmapSection<float, 3> &output, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
||||||
|
|
||||||
/// Generates a multi-channel signed distance field with true distance in the alpha channel. Edge colors must be assigned first.
|
/// Generates a multi-channel signed distance field with true distance in the alpha channel. Edge colors must be assigned first.
|
||||||
void generateMTSDF(const BitmapRef<float, 4> &output, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
void generateMTSDF(const BitmapSection<float, 4> &output, const Shape &shape, const SDFTransformation &transformation, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
||||||
|
|
||||||
// Old version of the function API's kept for backwards compatibility
|
// Old version of the function API's kept for backwards compatibility
|
||||||
void generateSDF(const BitmapRef<float, 1> &output, const Shape &shape, const Projection &projection, Range range, const GeneratorConfig &config = GeneratorConfig());
|
void generateSDF(const BitmapSection<float, 1> &output, const Shape &shape, const Projection &projection, Range range, const GeneratorConfig &config = GeneratorConfig());
|
||||||
void generatePSDF(const BitmapRef<float, 1> &output, const Shape &shape, const Projection &projection, Range range, const GeneratorConfig &config = GeneratorConfig());
|
void generatePSDF(const BitmapSection<float, 1> &output, const Shape &shape, const Projection &projection, Range range, const GeneratorConfig &config = GeneratorConfig());
|
||||||
void generatePseudoSDF(const BitmapRef<float, 1> &output, const Shape &shape, const Projection &projection, Range range, const GeneratorConfig &config = GeneratorConfig());
|
void generatePseudoSDF(const BitmapSection<float, 1> &output, const Shape &shape, const Projection &projection, Range range, const GeneratorConfig &config = GeneratorConfig());
|
||||||
void generateMSDF(const BitmapRef<float, 3> &output, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
void generateMSDF(const BitmapSection<float, 3> &output, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
||||||
void generateMTSDF(const BitmapRef<float, 4> &output, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
void generateMTSDF(const BitmapSection<float, 4> &output, const Shape &shape, const Projection &projection, Range range, const MSDFGeneratorConfig &config = MSDFGeneratorConfig());
|
||||||
|
|
||||||
void generateSDF(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport = true);
|
void generateSDF(const BitmapSection<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport = true);
|
||||||
void generatePSDF(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport = true);
|
void generatePSDF(const BitmapSection<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport = true);
|
||||||
void generatePseudoSDF(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport = true);
|
void generatePseudoSDF(const BitmapSection<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, bool overlapSupport = true);
|
||||||
void generateMSDF(const BitmapRef<float, 3> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, const ErrorCorrectionConfig &errorCorrectionConfig = ErrorCorrectionConfig(), bool overlapSupport = true);
|
void generateMSDF(const BitmapSection<float, 3> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, const ErrorCorrectionConfig &errorCorrectionConfig = ErrorCorrectionConfig(), bool overlapSupport = true);
|
||||||
void generateMTSDF(const BitmapRef<float, 4> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, const ErrorCorrectionConfig &errorCorrectionConfig = ErrorCorrectionConfig(), bool overlapSupport = true);
|
void generateMTSDF(const BitmapSection<float, 4> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, const ErrorCorrectionConfig &errorCorrectionConfig = ErrorCorrectionConfig(), bool overlapSupport = true);
|
||||||
|
|
||||||
// Original simpler versions of the previous functions, which work well under normal circumstances, but cannot deal with overlapping contours.
|
// Original simpler versions of the previous functions, which work well under normal circumstances, but cannot deal with overlapping contours.
|
||||||
void generateSDF_legacy(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate);
|
void generateSDF_legacy(BitmapSection<float, 1> output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate);
|
||||||
void generatePSDF_legacy(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate);
|
void generatePSDF_legacy(BitmapSection<float, 1> output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate);
|
||||||
void generatePseudoSDF_legacy(const BitmapRef<float, 1> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate);
|
void generatePseudoSDF_legacy(BitmapSection<float, 1> output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate);
|
||||||
void generateMSDF_legacy(const BitmapRef<float, 3> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, ErrorCorrectionConfig errorCorrectionConfig = ErrorCorrectionConfig());
|
void generateMSDF_legacy(BitmapSection<float, 3> output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, ErrorCorrectionConfig errorCorrectionConfig = ErrorCorrectionConfig());
|
||||||
void generateMTSDF_legacy(const BitmapRef<float, 4> &output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, ErrorCorrectionConfig errorCorrectionConfig = ErrorCorrectionConfig());
|
void generateMTSDF_legacy(BitmapSection<float, 4> output, const Shape &shape, Range range, const Vector2 &scale, const Vector2 &translate, ErrorCorrectionConfig errorCorrectionConfig = ErrorCorrectionConfig());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
17
thirdparty/msdfgen/patches/0001-remove-unused-save-features.patch
vendored
Normal file
17
thirdparty/msdfgen/patches/0001-remove-unused-save-features.patch
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
diff --git a/thirdparty/msdfgen/msdfgen.h b/thirdparty/msdfgen/msdfgen.h
|
||||||
|
index bf0ae2badc..d2c9a2fc8f 100644
|
||||||
|
--- a/thirdparty/msdfgen/msdfgen.h
|
||||||
|
+++ b/thirdparty/msdfgen/msdfgen.h
|
||||||
|
@@ -34,12 +34,7 @@
|
||||||
|
#include "core/render-sdf.h"
|
||||||
|
#include "core/rasterization.h"
|
||||||
|
#include "core/sdf-error-estimation.h"
|
||||||
|
-#include "core/save-bmp.h"
|
||||||
|
-#include "core/save-tiff.h"
|
||||||
|
-#include "core/save-rgba.h"
|
||||||
|
-#include "core/save-fl32.h"
|
||||||
|
#include "core/shape-description.h"
|
||||||
|
-#include "core/export-svg.h"
|
||||||
|
|
||||||
|
namespace msdfgen {
|
||||||
|
|
||||||
Reference in New Issue
Block a user