From c97c7b73e65d67106229d2ea83b90dcb078efd14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Thu, 9 Jan 2025 21:16:08 +0100 Subject: [PATCH] msdfgen: Update to 1.12 --- COPYRIGHT.txt | 2 +- modules/msdfgen/SCsub | 6 + .../gdextension_build/SConstruct | 6 + modules/text_server_adv/text_server_adv.cpp | 1 + .../gdextension_build/SConstruct | 6 + modules/text_server_fb/text_server_fb.cpp | 1 + thirdparty/README.md | 2 +- thirdparty/msdfgen/LICENSE.txt | 2 +- thirdparty/msdfgen/core/DistanceMapping.cpp | 27 +++ thirdparty/msdfgen/core/DistanceMapping.h | 36 ++++ thirdparty/msdfgen/core/EdgeHolder.cpp | 10 - thirdparty/msdfgen/core/EdgeHolder.h | 10 +- .../msdfgen/core/MSDFErrorCorrection.cpp | 35 ++-- thirdparty/msdfgen/core/MSDFErrorCorrection.h | 7 +- thirdparty/msdfgen/core/Range.hpp | 46 +++++ thirdparty/msdfgen/core/SDFTransformation.h | 24 +++ thirdparty/msdfgen/core/Shape.cpp | 26 ++- thirdparty/msdfgen/core/Shape.h | 2 - thirdparty/msdfgen/core/Vector2.hpp | 4 +- thirdparty/msdfgen/core/contour-combiners.cpp | 11 +- thirdparty/msdfgen/core/edge-coloring.cpp | 116 +++++++---- thirdparty/msdfgen/core/edge-segments.cpp | 77 ++++--- thirdparty/msdfgen/core/edge-segments.h | 18 +- thirdparty/msdfgen/core/edge-selectors.cpp | 102 ++++----- thirdparty/msdfgen/core/edge-selectors.h | 28 +-- thirdparty/msdfgen/core/export-svg.cpp | 79 +++++++ thirdparty/msdfgen/core/export-svg.h | 11 + .../msdfgen/core/msdf-error-correction.cpp | 50 +++-- .../msdfgen/core/msdf-error-correction.h | 20 +- thirdparty/msdfgen/core/msdfgen.cpp | 158 +++++++++----- thirdparty/msdfgen/core/pixel-conversion.hpp | 2 +- thirdparty/msdfgen/core/render-sdf.cpp | 194 +++++++++++++----- thirdparty/msdfgen/core/render-sdf.h | 13 +- thirdparty/msdfgen/core/save-bmp.cpp | 2 + thirdparty/msdfgen/core/save-fl32.cpp | 39 ++++ thirdparty/msdfgen/core/save-fl32.h | 12 ++ thirdparty/msdfgen/core/save-rgba.cpp | 133 ++++++++++++ thirdparty/msdfgen/core/save-rgba.h | 16 ++ thirdparty/msdfgen/core/save-tiff.cpp | 2 + thirdparty/msdfgen/core/shape-description.cpp | 23 ++- thirdparty/msdfgen/msdfgen.h | 42 ++-- 41 files changed, 1038 insertions(+), 363 deletions(-) create mode 100644 thirdparty/msdfgen/core/DistanceMapping.cpp create mode 100644 thirdparty/msdfgen/core/DistanceMapping.h create mode 100644 thirdparty/msdfgen/core/Range.hpp create mode 100644 thirdparty/msdfgen/core/SDFTransformation.h create mode 100644 thirdparty/msdfgen/core/export-svg.cpp create mode 100644 thirdparty/msdfgen/core/export-svg.h create mode 100644 thirdparty/msdfgen/core/save-fl32.cpp create mode 100644 thirdparty/msdfgen/core/save-fl32.h create mode 100644 thirdparty/msdfgen/core/save-rgba.cpp create mode 100644 thirdparty/msdfgen/core/save-rgba.h diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 7561168405f..89246805544 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -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 diff --git a/modules/msdfgen/SCsub b/modules/msdfgen/SCsub index 844b0980ac5..55c1394e302 100644 --- a/modules/msdfgen/SCsub +++ b/modules/msdfgen/SCsub @@ -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", ] diff --git a/modules/text_server_adv/gdextension_build/SConstruct b/modules/text_server_adv/gdextension_build/SConstruct index 39573aebde5..5d73d4ae22e 100644 --- a/modules/text_server_adv/gdextension_build/SConstruct +++ b/modules/text_server_adv/gdextension_build/SConstruct @@ -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", ] diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index d163b9f2326..aa97a4073d2 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -69,6 +69,7 @@ using namespace godot; #ifdef _MSC_VER #pragma warning(disable : 4458) #endif +#include #include #include #include diff --git a/modules/text_server_fb/gdextension_build/SConstruct b/modules/text_server_fb/gdextension_build/SConstruct index ac1dc6d4e4a..6f97ccf9dd6 100644 --- a/modules/text_server_fb/gdextension_build/SConstruct +++ b/modules/text_server_fb/gdextension_build/SConstruct @@ -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", ] diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index f367567feed..561575a34bb 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -64,6 +64,7 @@ using namespace godot; #ifdef _MSC_VER #pragma warning(disable : 4458) #endif +#include #include #include #include diff --git a/thirdparty/README.md b/thirdparty/README.md index 30bb192472d..9987d675096 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -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: diff --git a/thirdparty/msdfgen/LICENSE.txt b/thirdparty/msdfgen/LICENSE.txt index 69054bd2e18..d5b31742500 100644 --- a/thirdparty/msdfgen/LICENSE.txt +++ b/thirdparty/msdfgen/LICENSE.txt @@ -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 diff --git a/thirdparty/msdfgen/core/DistanceMapping.cpp b/thirdparty/msdfgen/core/DistanceMapping.cpp new file mode 100644 index 00000000000..526e12905e1 --- /dev/null +++ b/thirdparty/msdfgen/core/DistanceMapping.cpp @@ -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); +} + +} diff --git a/thirdparty/msdfgen/core/DistanceMapping.h b/thirdparty/msdfgen/core/DistanceMapping.h new file mode 100644 index 00000000000..fadbefa54bc --- /dev/null +++ b/thirdparty/msdfgen/core/DistanceMapping.h @@ -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) { } + +}; + +} diff --git a/thirdparty/msdfgen/core/EdgeHolder.cpp b/thirdparty/msdfgen/core/EdgeHolder.cpp index cffcff46d32..f552e98fa7d 100644 --- a/thirdparty/msdfgen/core/EdgeHolder.cpp +++ b/thirdparty/msdfgen/core/EdgeHolder.cpp @@ -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 diff --git a/thirdparty/msdfgen/core/EdgeHolder.h b/thirdparty/msdfgen/core/EdgeHolder.h index 50a59b21891..5ae2dc231af 100644 --- a/thirdparty/msdfgen/core/EdgeHolder.h +++ b/thirdparty/msdfgen/core/EdgeHolder.h @@ -12,11 +12,11 @@ public: /// 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); diff --git a/thirdparty/msdfgen/core/MSDFErrorCorrection.cpp b/thirdparty/msdfgen/core/MSDFErrorCorrection.cpp index 9a5cefe1287..7639dc68773 100644 --- a/thirdparty/msdfgen/core/MSDFErrorCorrection.cpp +++ b/thirdparty/msdfgen/core/MSDFErrorCorrection.cpp @@ -74,7 +74,7 @@ public: // 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 @@ public: Point2 shapeCoord, sdfCoord; const float *msd; bool protectedFlag; - inline ShapeDistanceChecker(const BitmapConstRef &sdf, const Shape &shape, const Projection &projection, double invRange, double minImproveRatio) : distanceFinder(shape), sdf(sdf), invRange(invRange), minImproveRatio(minImproveRatio) { + inline ShapeDistanceChecker(const BitmapConstRef &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 > distanceFinder; + ShapeDistanceFinder > distanceFinder; BitmapConstRef sdf; - double invRange; + DistanceMapping distanceMapping; Vector2 texelSize; double minImproveRatio; }; MSDFErrorCorrection::MSDFErrorCorrection() { } -MSDFErrorCorrection::MSDFErrorCorrection(const BitmapRef &stencil, const Projection &projection, double range) : stencil(stencil), projection(projection) { - invRange = 1/range; +MSDFErrorCorrection::MSDFErrorCorrection(const BitmapRef &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 void MSDFErrorCorrection::protectEdges(const BitmapConstRef &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 &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 &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 void MSDFErrorCorrection::findErrors(const BitmapConstRef &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 &sdf) { template