Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

msdfgen: Update to 1.12 #101367

Merged
merged 1 commit into from
Jan 10, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion COPYRIGHT.txt
Original file line number Diff line number Diff line change
@@ -469,7 +469,7 @@ License: BSD-2-clause

Files: ./thirdparty/msdfgen/
Comment: Multi-channel signed distance field generator
Copyright: 2016-2022, Viktor Chlumsky
Copyright: 2014-2024, Viktor Chlumsky
License: Expat

Files: ./thirdparty/nvapi/nvapi_minimal.h
6 changes: 6 additions & 0 deletions modules/msdfgen/SCsub
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ if env["builtin_msdfgen"]:
thirdparty_dir = "#thirdparty/msdfgen/"
thirdparty_sources = [
"core/Contour.cpp",
"core/DistanceMapping.cpp",
"core/EdgeHolder.cpp",
"core/MSDFErrorCorrection.cpp",
"core/Projection.cpp",
@@ -26,10 +27,15 @@ if env["builtin_msdfgen"]:
"core/edge-segments.cpp",
"core/edge-selectors.cpp",
"core/equation-solver.cpp",
# "core/export-svg.cpp",
"core/msdf-error-correction.cpp",
"core/msdfgen.cpp",
"core/rasterization.cpp",
"core/render-sdf.cpp",
# "core/save-bmp.cpp",
# "core/save-fl32.cpp",
# "core/save-rgba.cpp",
# "core/save-tiff.cpp",
"core/sdf-error-estimation.cpp",
"core/shape-description.cpp",
]
6 changes: 6 additions & 0 deletions modules/text_server_adv/gdextension_build/SConstruct
Original file line number Diff line number Diff line change
@@ -123,6 +123,7 @@ if env["msdfgen_enabled"] and env["freetype_enabled"]:
thirdparty_msdfgen_dir = "../../../thirdparty/msdfgen/"
thirdparty_msdfgen_sources = [
"core/Contour.cpp",
"core/DistanceMapping.cpp",
"core/EdgeHolder.cpp",
"core/MSDFErrorCorrection.cpp",
"core/Projection.cpp",
@@ -133,10 +134,15 @@ if env["msdfgen_enabled"] and env["freetype_enabled"]:
"core/edge-segments.cpp",
"core/edge-selectors.cpp",
"core/equation-solver.cpp",
# "core/export-svg.cpp",
"core/msdf-error-correction.cpp",
"core/msdfgen.cpp",
"core/rasterization.cpp",
"core/render-sdf.cpp",
# "core/save-bmp.cpp",
# "core/save-fl32.cpp",
# "core/save-rgba.cpp",
# "core/save-tiff.cpp",
"core/sdf-error-estimation.cpp",
"core/shape-description.cpp",
]
1 change: 1 addition & 0 deletions modules/text_server_adv/text_server_adv.cpp
Original file line number Diff line number Diff line change
@@ -69,6 +69,7 @@ using namespace godot;
#ifdef _MSC_VER
#pragma warning(disable : 4458)
#endif
#include <core/EdgeHolder.h>
#include <core/ShapeDistanceFinder.h>
#include <core/contour-combiners.h>
#include <core/edge-selectors.h>
6 changes: 6 additions & 0 deletions modules/text_server_fb/gdextension_build/SConstruct
Original file line number Diff line number Diff line change
@@ -118,6 +118,7 @@ if env["msdfgen_enabled"] and env["freetype_enabled"]:
thirdparty_msdfgen_dir = "../../../thirdparty/msdfgen/"
thirdparty_msdfgen_sources = [
"core/Contour.cpp",
"core/DistanceMapping.cpp",
"core/EdgeHolder.cpp",
"core/MSDFErrorCorrection.cpp",
"core/Projection.cpp",
@@ -128,10 +129,15 @@ if env["msdfgen_enabled"] and env["freetype_enabled"]:
"core/edge-segments.cpp",
"core/edge-selectors.cpp",
"core/equation-solver.cpp",
# "core/export-svg.cpp",
"core/msdf-error-correction.cpp",
"core/msdfgen.cpp",
"core/rasterization.cpp",
"core/render-sdf.cpp",
# "core/save-bmp.cpp",
# "core/save-fl32.cpp",
# "core/save-rgba.cpp",
# "core/save-tiff.cpp",
"core/sdf-error-estimation.cpp",
"core/shape-description.cpp",
]
1 change: 1 addition & 0 deletions modules/text_server_fb/text_server_fb.cpp
Original file line number Diff line number Diff line change
@@ -64,6 +64,7 @@ using namespace godot;
#ifdef _MSC_VER
#pragma warning(disable : 4458)
#endif
#include <core/EdgeHolder.h>
#include <core/ShapeDistanceFinder.h>
#include <core/contour-combiners.h>
#include <core/edge-selectors.h>
2 changes: 1 addition & 1 deletion thirdparty/README.md
Original file line number Diff line number Diff line change
@@ -763,7 +763,7 @@ Collection of single-file libraries used in Godot components.
## msdfgen

- Upstream: https://github.com/Chlumsky/msdfgen
- Version: 1.11 (f12d7ca00091a632a289865b85c3f2e0bfc6542d, 2023)
- Version: 1.12 (85e8b3d47b3d1a42e4a5ebda0a24fb1cc2e669e0, 2024)
- License: MIT

Files extracted from the upstream source:
2 changes: 1 addition & 1 deletion thirdparty/msdfgen/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2016 - 2023 Viktor Chlumsky
Copyright (c) 2014 - 2024 Viktor Chlumsky

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
27 changes: 27 additions & 0 deletions thirdparty/msdfgen/core/DistanceMapping.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

#include "DistanceMapping.h"

namespace msdfgen {

DistanceMapping DistanceMapping::inverse(Range range) {
double rangeWidth = range.upper-range.lower;
return DistanceMapping(rangeWidth, range.lower/(rangeWidth ? rangeWidth : 1));
}

DistanceMapping::DistanceMapping() : scale(1), translate(0) { }

DistanceMapping::DistanceMapping(Range range) : scale(1/(range.upper-range.lower)), translate(-range.lower) { }

double DistanceMapping::operator()(double d) const {
return scale*(d+translate);
}

double DistanceMapping::operator()(Delta d) const {
return scale*d.value;
}

DistanceMapping DistanceMapping::inverse() const {
return DistanceMapping(1/scale, -scale*translate);
}

}
36 changes: 36 additions & 0 deletions thirdparty/msdfgen/core/DistanceMapping.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

#pragma once

#include "Range.hpp"

namespace msdfgen {

/// Linear transformation of signed distance values.
class DistanceMapping {

public:
/// Explicitly designates value as distance delta rather than an absolute distance.
class Delta {
public:
double value;
inline explicit Delta(double distanceDelta) : value(distanceDelta) { }
inline operator double() const { return value; }
};

static DistanceMapping inverse(Range range);

DistanceMapping();
DistanceMapping(Range range);
double operator()(double d) const;
double operator()(Delta d) const;
DistanceMapping inverse() const;

private:
double scale;
double translate;

inline DistanceMapping(double scale, double translate) : scale(scale), translate(translate) { }

};

}
10 changes: 0 additions & 10 deletions thirdparty/msdfgen/core/EdgeHolder.cpp
Original file line number Diff line number Diff line change
@@ -9,16 +9,6 @@ void EdgeHolder::swap(EdgeHolder &a, EdgeHolder &b) {
b.edgeSegment = tmp;
}

EdgeHolder::EdgeHolder() : edgeSegment(NULL) { }

EdgeHolder::EdgeHolder(EdgeSegment *segment) : edgeSegment(segment) { }

EdgeHolder::EdgeHolder(Point2 p0, Point2 p1, EdgeColor edgeColor) : edgeSegment(new LinearSegment(p0, p1, edgeColor)) { }

EdgeHolder::EdgeHolder(Point2 p0, Point2 p1, Point2 p2, EdgeColor edgeColor) : edgeSegment(new QuadraticSegment(p0, p1, p2, edgeColor)) { }

EdgeHolder::EdgeHolder(Point2 p0, Point2 p1, Point2 p2, Point2 p3, EdgeColor edgeColor) : edgeSegment(new CubicSegment(p0, p1, p2, p3, edgeColor)) { }

EdgeHolder::EdgeHolder(const EdgeHolder &orig) : edgeSegment(orig.edgeSegment ? orig.edgeSegment->clone() : NULL) { }

#ifdef MSDFGEN_USE_CPP11
10 changes: 5 additions & 5 deletions thirdparty/msdfgen/core/EdgeHolder.h
Original file line number Diff line number Diff line change
@@ -12,11 +12,11 @@ class EdgeHolder {
/// Swaps the edges held by a and b.
static void swap(EdgeHolder &a, EdgeHolder &b);

EdgeHolder();
EdgeHolder(EdgeSegment *segment);
EdgeHolder(Point2 p0, Point2 p1, EdgeColor edgeColor = WHITE);
EdgeHolder(Point2 p0, Point2 p1, Point2 p2, EdgeColor edgeColor = WHITE);
EdgeHolder(Point2 p0, Point2 p1, Point2 p2, Point2 p3, EdgeColor edgeColor = WHITE);
inline EdgeHolder() : edgeSegment() { }
inline EdgeHolder(EdgeSegment *segment) : edgeSegment(segment) { }
inline EdgeHolder(Point2 p0, Point2 p1, EdgeColor edgeColor = WHITE) : edgeSegment(EdgeSegment::create(p0, p1, edgeColor)) { }
inline EdgeHolder(Point2 p0, Point2 p1, Point2 p2, EdgeColor edgeColor = WHITE) : edgeSegment(EdgeSegment::create(p0, p1, p2, edgeColor)) { }
inline EdgeHolder(Point2 p0, Point2 p1, Point2 p2, Point2 p3, EdgeColor edgeColor = WHITE) : edgeSegment(EdgeSegment::create(p0, p1, p2, p3, edgeColor)) { }
EdgeHolder(const EdgeHolder &orig);
#ifdef MSDFGEN_USE_CPP11
EdgeHolder(EdgeHolder &&orig);
35 changes: 17 additions & 18 deletions thirdparty/msdfgen/core/MSDFErrorCorrection.cpp
Original file line number Diff line number Diff line change
@@ -74,7 +74,7 @@ class ShapeDistanceChecker {
// Compute the evaluated distance (interpolated median) before and after error correction, as well as the exact shape distance.
float oldPSD = median(oldMSD[0], oldMSD[1], oldMSD[2]);
float newPSD = median(newMSD[0], newMSD[1], newMSD[2]);
float refPSD = float(parent->invRange*parent->distanceFinder.distance(parent->shapeCoord+tVector*parent->texelSize)+.5);
float refPSD = float(parent->distanceMapping(parent->distanceFinder.distance(parent->shapeCoord+tVector*parent->texelSize)));
// Compare the differences of the exact distance and the before and after distances.
return parent->minImproveRatio*fabsf(newPSD-refPSD) < double(fabsf(oldPSD-refPSD));
}
@@ -87,24 +87,23 @@ class ShapeDistanceChecker {
Point2 shapeCoord, sdfCoord;
const float *msd;
bool protectedFlag;
inline ShapeDistanceChecker(const BitmapConstRef<float, N> &sdf, const Shape &shape, const Projection &projection, double invRange, double minImproveRatio) : distanceFinder(shape), sdf(sdf), invRange(invRange), minImproveRatio(minImproveRatio) {
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) {
texelSize = projection.unprojectVector(Vector2(1));
}
inline ArtifactClassifier classifier(const Vector2 &direction, double span) {
return ArtifactClassifier(this, direction, span);
}
private:
ShapeDistanceFinder<ContourCombiner<PseudoDistanceSelector> > distanceFinder;
ShapeDistanceFinder<ContourCombiner<PerpendicularDistanceSelector> > distanceFinder;
BitmapConstRef<float, N> sdf;
double invRange;
DistanceMapping distanceMapping;
Vector2 texelSize;
double minImproveRatio;
};

MSDFErrorCorrection::MSDFErrorCorrection() { }

MSDFErrorCorrection::MSDFErrorCorrection(const BitmapRef<byte, 1> &stencil, const Projection &projection, double range) : stencil(stencil), projection(projection) {
invRange = 1/range;
MSDFErrorCorrection::MSDFErrorCorrection(const BitmapRef<byte, 1> &stencil, const SDFTransformation &transformation) : stencil(stencil), transformation(transformation) {
minDeviationRatio = ErrorCorrectionConfig::defaultMinDeviationRatio;
minImproveRatio = ErrorCorrectionConfig::defaultMinImproveRatio;
memset(stencil.pixels, 0, sizeof(byte)*stencil.width*stencil.height);
@@ -127,7 +126,7 @@ void MSDFErrorCorrection::protectCorners(const Shape &shape) {
// If the color changes from prevEdge to edge, this is a corner.
if (!(commonColor&(commonColor-1))) {
// Find the four texels that envelop the corner and mark them as protected.
Point2 p = projection.project((*edge)->point(0));
Point2 p = transformation.project((*edge)->point(0));
if (shape.inverseYAxis)
p.y = stencil.height-p.y;
int l = (int) floor(p.x-.5);
@@ -191,7 +190,7 @@ template <int N>
void MSDFErrorCorrection::protectEdges(const BitmapConstRef<float, N> &sdf) {
float radius;
// Horizontal texel pairs
radius = float(PROTECTION_RADIUS_TOLERANCE*projection.unprojectVector(Vector2(invRange, 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) {
const float *left = sdf(0, y);
const float *right = sdf(1, y);
@@ -207,7 +206,7 @@ void MSDFErrorCorrection::protectEdges(const BitmapConstRef<float, N> &sdf) {
}
}
// Vertical texel pairs
radius = float(PROTECTION_RADIUS_TOLERANCE*projection.unprojectVector(Vector2(0, invRange)).length());
radius = float(PROTECTION_RADIUS_TOLERANCE*transformation.unprojectVector(Vector2(0, transformation.distanceMapping(DistanceMapping::Delta(1)))).length());
for (int y = 0; y < sdf.height-1; ++y) {
const float *bottom = sdf(0, y);
const float *top = sdf(0, y+1);
@@ -223,7 +222,7 @@ void MSDFErrorCorrection::protectEdges(const BitmapConstRef<float, N> &sdf) {
}
}
// Diagonal texel pairs
radius = float(PROTECTION_RADIUS_TOLERANCE*projection.unprojectVector(Vector2(invRange)).length());
radius = float(PROTECTION_RADIUS_TOLERANCE*transformation.unprojectVector(Vector2(transformation.distanceMapping(DistanceMapping::Delta(1)))).length());
for (int y = 0; y < sdf.height-1; ++y) {
const float *lb = sdf(0, y);
const float *rb = sdf(1, y);
@@ -391,9 +390,9 @@ static bool hasDiagonalArtifact(const ArtifactClassifier &artifactClassifier, fl
template <int N>
void MSDFErrorCorrection::findErrors(const BitmapConstRef<float, N> &sdf) {
// Compute the expected deltas between values of horizontally, vertically, and diagonally adjacent texels.
double hSpan = minDeviationRatio*projection.unprojectVector(Vector2(invRange, 0)).length();
double vSpan = minDeviationRatio*projection.unprojectVector(Vector2(0, invRange)).length();
double dSpan = minDeviationRatio*projection.unprojectVector(Vector2(invRange)).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 dSpan = minDeviationRatio*transformation.unprojectVector(Vector2(transformation.distanceMapping(DistanceMapping::Delta(1)))).length();
// Inspect all texels.
for (int y = 0; y < sdf.height; ++y) {
for (int x = 0; x < sdf.width; ++x) {
@@ -419,14 +418,14 @@ void MSDFErrorCorrection::findErrors(const BitmapConstRef<float, N> &sdf) {
template <template <typename> class ContourCombiner, int N>
void MSDFErrorCorrection::findErrors(const BitmapConstRef<float, N> &sdf, const Shape &shape) {
// Compute the expected deltas between values of horizontally, vertically, and diagonally adjacent texels.
double hSpan = minDeviationRatio*projection.unprojectVector(Vector2(invRange, 0)).length();
double vSpan = minDeviationRatio*projection.unprojectVector(Vector2(0, invRange)).length();
double dSpan = minDeviationRatio*projection.unprojectVector(Vector2(invRange)).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 dSpan = minDeviationRatio*transformation.unprojectVector(Vector2(transformation.distanceMapping(DistanceMapping::Delta(1)))).length();
#ifdef MSDFGEN_USE_OPENMP
#pragma omp parallel
#endif
{
ShapeDistanceChecker<ContourCombiner, N> shapeDistanceChecker(sdf, shape, projection, invRange, minImproveRatio);
ShapeDistanceChecker<ContourCombiner, N> shapeDistanceChecker(sdf, shape, transformation, transformation.distanceMapping, minImproveRatio);
bool rightToLeft = false;
// Inspect all texels.
#ifdef MSDFGEN_USE_OPENMP
@@ -439,7 +438,7 @@ void MSDFErrorCorrection::findErrors(const BitmapConstRef<float, N> &sdf, const
if ((*stencil(x, row)&ERROR))
continue;
const float *c = sdf(x, row);
shapeDistanceChecker.shapeCoord = projection.unproject(Point2(x+.5, y+.5));
shapeDistanceChecker.shapeCoord = transformation.unproject(Point2(x+.5, y+.5));
shapeDistanceChecker.sdfCoord = Point2(x+.5, row+.5);
shapeDistanceChecker.msd = c;
shapeDistanceChecker.protectedFlag = (*stencil(x, row)&PROTECTED) != 0;
7 changes: 3 additions & 4 deletions thirdparty/msdfgen/core/MSDFErrorCorrection.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

#pragma once

#include "Projection.h"
#include "SDFTransformation.h"
#include "Shape.h"
#include "BitmapRef.hpp"

@@ -20,7 +20,7 @@ class MSDFErrorCorrection {
};

MSDFErrorCorrection();
explicit MSDFErrorCorrection(const BitmapRef<byte, 1> &stencil, const Projection &projection, double range);
explicit MSDFErrorCorrection(const BitmapRef<byte, 1> &stencil, const SDFTransformation &transformation);
/// Sets the minimum ratio between the actual and maximum expected distance delta to be considered an error.
void setMinDeviationRatio(double minDeviationRatio);
/// Sets the minimum ratio between the pre-correction distance error and the post-correction distance error.
@@ -46,8 +46,7 @@ class MSDFErrorCorrection {

private:
BitmapRef<byte, 1> stencil;
Projection projection;
double invRange;
SDFTransformation transformation;
double minDeviationRatio;
double minImproveRatio;

Loading