From 2901e3898c2878bc0e0df10c8d02f5a8b002c7cd Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Fri, 29 Aug 2025 16:03:44 -0500 Subject: [PATCH 01/70] Add `IncludeInheritedTypes` to `RequireActor` --- .../Editor/CustomEditors/Dedicated/ScriptsEditor.cs | 13 +++++++------ .../Attributes/Editor/RequireActorAttribute.cs | 9 ++++++++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs b/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs index 123c7252a..685bf9dfc 100644 --- a/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs +++ b/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs @@ -102,11 +102,12 @@ namespace FlaxEditor.CustomEditors.Dedicated var actors = ScriptsEditor.ParentEditor.Values; foreach (var a in actors) { - if (a.GetType() != requireActor.RequiredType) - { - item.Enabled = false; - break; - } + if (a.GetType() == requireActor.RequiredType) + continue; + if (requireActor.IncludeInheritedTypes && a.GetType().IsSubclassOf(requireActor.RequiredType)) + continue; + item.Enabled = false; + break; } } cm.AddItem(item); @@ -827,7 +828,7 @@ namespace FlaxEditor.CustomEditors.Dedicated if (attribute != null) { var actor = script.Actor; - if (actor.GetType() != attribute.RequiredType && !actor.GetType().IsSubclassOf(attribute.RequiredType)) + if (actor.GetType() != attribute.RequiredType && (attribute.IncludeInheritedTypes && !actor.GetType().IsSubclassOf(attribute.RequiredType))) { Editor.LogWarning($"`{Utilities.Utils.GetPropertyNameUI(scriptType.Name)}` on `{script.Actor}` is missing a required Actor of type `{attribute.RequiredType}`."); hasAllRequirements = false; diff --git a/Source/Engine/Scripting/Attributes/Editor/RequireActorAttribute.cs b/Source/Engine/Scripting/Attributes/Editor/RequireActorAttribute.cs index 6e08217bf..3e5ad7f73 100644 --- a/Source/Engine/Scripting/Attributes/Editor/RequireActorAttribute.cs +++ b/Source/Engine/Scripting/Attributes/Editor/RequireActorAttribute.cs @@ -13,13 +13,20 @@ public class RequireActorAttribute : Attribute /// The required type. /// public Type RequiredType; + + /// + /// Whether to include inherited types. + /// + public bool IncludeInheritedTypes; /// /// Initializes a new instance of the class. /// /// The required type. - public RequireActorAttribute(Type type) + /// Whether to include inherited types. + public RequireActorAttribute(Type type, bool includeInheritedTypes = false) { RequiredType = type; + IncludeInheritedTypes = includeInheritedTypes; } } From f588d6da51c218a70e2f3c8d9b11cca6b74242f6 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 2 Sep 2025 20:33:41 -0500 Subject: [PATCH 02/70] Add ability to loop root node in behavior trees. --- Source/Engine/AI/Behavior.cpp | 14 +++++++++++++- Source/Engine/AI/BehaviorTreeNodes.h | 4 ++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Source/Engine/AI/Behavior.cpp b/Source/Engine/AI/Behavior.cpp index e70ca50a4..f0c4acee3 100644 --- a/Source/Engine/AI/Behavior.cpp +++ b/Source/Engine/AI/Behavior.cpp @@ -106,7 +106,19 @@ void Behavior::UpdateAsync() const BehaviorUpdateResult result = tree->Graph.Root->InvokeUpdate(context); if (result != BehaviorUpdateResult::Running) _result = result; - if (_result != BehaviorUpdateResult::Running) + if (_result != BehaviorUpdateResult::Running && tree->Graph.Root->Loop) + { + // Ensure to have tree loaded on play + CHECK(Tree && !Tree->WaitForLoaded()); + BehaviorTree* tree = Tree.Get(); + CHECK(tree->Graph.Root); + + // Setup state + _result = BehaviorUpdateResult::Running; + _accumulatedTime = 0.0f; + _totalTime = 0; + } + else if (_result != BehaviorUpdateResult::Running) { Finished(); } diff --git a/Source/Engine/AI/BehaviorTreeNodes.h b/Source/Engine/AI/BehaviorTreeNodes.h index 7aaab5f3c..05a472da7 100644 --- a/Source/Engine/AI/BehaviorTreeNodes.h +++ b/Source/Engine/AI/BehaviorTreeNodes.h @@ -96,6 +96,10 @@ API_CLASS(Sealed) class FLAXENGINE_API BehaviorTreeRootNode : public BehaviorTre // The target amount of the behavior logic updates per second. API_FIELD(Attributes="EditorOrder(100)") float UpdateFPS = 10.0f; + + // Whether to loop the root node. + API_FIELD(Attributes="EditorOrder(200)") + bool Loop = true; }; /// From cd0878f81064791f4f94c9faee8c47c6e1af4ead Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 2 Sep 2025 20:47:04 -0500 Subject: [PATCH 03/70] Simplify code --- Source/Engine/AI/Behavior.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Source/Engine/AI/Behavior.cpp b/Source/Engine/AI/Behavior.cpp index f0c4acee3..d727bdef1 100644 --- a/Source/Engine/AI/Behavior.cpp +++ b/Source/Engine/AI/Behavior.cpp @@ -108,12 +108,7 @@ void Behavior::UpdateAsync() _result = result; if (_result != BehaviorUpdateResult::Running && tree->Graph.Root->Loop) { - // Ensure to have tree loaded on play - CHECK(Tree && !Tree->WaitForLoaded()); - BehaviorTree* tree = Tree.Get(); - CHECK(tree->Graph.Root); - - // Setup state + // Reset State _result = BehaviorUpdateResult::Running; _accumulatedTime = 0.0f; _totalTime = 0; From 18a0e8d6122303dba3a75af1e6e7adf2d2327e8e Mon Sep 17 00:00:00 2001 From: frank Date: Sat, 4 Oct 2025 22:37:37 +0800 Subject: [PATCH 04/70] add msdfgen for windows --- Source/Engine/Render2D/Render2D.Build.cs | 1 + Source/ThirdParty/msdfgen/LICENSE.txt | 21 +++ Source/ThirdParty/msdfgen/msdfgen.Build.cs | 45 +++++ Source/ThirdParty/msdfgen/msdfgen.h | 4 + .../ThirdParty/msdfgen/msdfgen/core/Bitmap.h | 50 ++++++ .../msdfgen/msdfgen/core/Bitmap.hpp | 117 ++++++++++++ .../msdfgen/msdfgen/core/BitmapRef.hpp | 41 +++++ .../ThirdParty/msdfgen/msdfgen/core/Contour.h | 34 ++++ .../msdfgen/msdfgen/core/DistanceMapping.h | 36 ++++ .../msdfgen/msdfgen/core/EdgeColor.h | 20 +++ .../msdfgen/msdfgen/core/EdgeHolder.h | 41 +++++ .../msdfgen/core/MSDFErrorCorrection.h | 55 ++++++ .../msdfgen/msdfgen/core/Projection.h | 37 ++++ .../ThirdParty/msdfgen/msdfgen/core/Range.hpp | 46 +++++ .../msdfgen/msdfgen/core/SDFTransformation.h | 24 +++ .../msdfgen/msdfgen/core/Scanline.h | 56 ++++++ .../ThirdParty/msdfgen/msdfgen/core/Shape.h | 53 ++++++ .../msdfgen/core/ShapeDistanceFinder.h | 37 ++++ .../msdfgen/core/ShapeDistanceFinder.hpp | 60 +++++++ .../msdfgen/msdfgen/core/SignedDistance.hpp | 38 ++++ .../msdfgen/msdfgen/core/Vector2.hpp | 167 ++++++++++++++++++ .../msdfgen/msdfgen/core/arithmetics.hpp | 63 +++++++ Source/ThirdParty/msdfgen/msdfgen/core/base.h | 16 ++ .../msdfgen/core/bitmap-interpolation.hpp | 25 +++ .../msdfgen/msdfgen/core/contour-combiners.h | 47 +++++ .../msdfgen/core/convergent-curve-ordering.h | 11 ++ .../msdfgen/msdfgen/core/edge-coloring.h | 29 +++ .../msdfgen/msdfgen/core/edge-segments.h | 146 +++++++++++++++ .../msdfgen/msdfgen/core/edge-selectors.h | 117 ++++++++++++ .../msdfgen/msdfgen/core/equation-solver.h | 14 ++ .../msdfgen/msdfgen/core/export-svg.h | 11 ++ .../msdfgen/msdfgen/core/generator-config.h | 66 +++++++ .../msdfgen/core/msdf-error-correction.h | 40 +++++ .../msdfgen/msdfgen/core/pixel-conversion.hpp | 16 ++ .../msdfgen/msdfgen/core/rasterization.h | 25 +++ .../msdfgen/msdfgen/core/render-sdf.h | 23 +++ .../msdfgen/msdfgen/core/save-bmp.h | 16 ++ .../msdfgen/msdfgen/core/save-fl32.h | 12 ++ .../msdfgen/msdfgen/core/save-rgba.h | 16 ++ .../msdfgen/msdfgen/core/save-tiff.h | 13 ++ .../msdfgen/core/sdf-error-estimation.h | 30 ++++ .../msdfgen/msdfgen/core/shape-description.h | 15 ++ .../msdfgen/msdfgen/msdfgen-config.h | 13 ++ Source/ThirdParty/msdfgen/msdfgen/msdfgen.h | 78 ++++++++ .../msdfgen/msdfgen/msdfgen/msdfgen-config.h | 13 ++ .../Flax.Build/Deps/Dependencies/msdfgen.cs | 126 +++++++++++++ 46 files changed, 1964 insertions(+) create mode 100644 Source/ThirdParty/msdfgen/LICENSE.txt create mode 100644 Source/ThirdParty/msdfgen/msdfgen.Build.cs create mode 100644 Source/ThirdParty/msdfgen/msdfgen.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/Bitmap.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/Bitmap.hpp create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/BitmapRef.hpp create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/Contour.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/DistanceMapping.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/EdgeColor.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/EdgeHolder.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/MSDFErrorCorrection.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/Projection.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/Range.hpp create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/SDFTransformation.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/Scanline.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/Shape.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/ShapeDistanceFinder.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/ShapeDistanceFinder.hpp create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/SignedDistance.hpp create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/Vector2.hpp create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/arithmetics.hpp create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/base.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/bitmap-interpolation.hpp create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/contour-combiners.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/convergent-curve-ordering.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/edge-coloring.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/edge-segments.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/edge-selectors.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/equation-solver.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/export-svg.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/generator-config.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/msdf-error-correction.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/pixel-conversion.hpp create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/rasterization.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/render-sdf.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/save-bmp.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/save-fl32.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/save-rgba.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/save-tiff.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/sdf-error-estimation.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/core/shape-description.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/msdfgen-config.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/msdfgen.h create mode 100644 Source/ThirdParty/msdfgen/msdfgen/msdfgen/msdfgen-config.h create mode 100644 Source/Tools/Flax.Build/Deps/Dependencies/msdfgen.cs diff --git a/Source/Engine/Render2D/Render2D.Build.cs b/Source/Engine/Render2D/Render2D.Build.cs index f0be43983..a8f09270c 100644 --- a/Source/Engine/Render2D/Render2D.Build.cs +++ b/Source/Engine/Render2D/Render2D.Build.cs @@ -14,6 +14,7 @@ public class Render2D : EngineModule base.Setup(options); options.PrivateDependencies.Add("freetype"); + options.PrivateDependencies.Add("msdfgen"); options.PrivateDefinitions.Add("RENDER2D_USE_LINE_AA"); } diff --git a/Source/ThirdParty/msdfgen/LICENSE.txt b/Source/ThirdParty/msdfgen/LICENSE.txt new file mode 100644 index 000000000..fbea359b2 --- /dev/null +++ b/Source/ThirdParty/msdfgen/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2014 - 2025 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 +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Source/ThirdParty/msdfgen/msdfgen.Build.cs b/Source/ThirdParty/msdfgen/msdfgen.Build.cs new file mode 100644 index 000000000..4d4262960 --- /dev/null +++ b/Source/ThirdParty/msdfgen/msdfgen.Build.cs @@ -0,0 +1,45 @@ +// Copyright (c) Wojciech Figat. All rights reserved. + +using System.IO; +using Flax.Build; +using Flax.Build.NativeCpp; + +/// +/// https://github.com/Chlumsky/msdfgen +/// +public class msdfgen : DepsModule +{ + /// + public override void Init() + { + base.Init(); + + LicenseType = LicenseTypes.MIT; + LicenseFilePath = "LICENSE.TXT"; + + // Merge third-party modules into engine binary + BinaryModuleName = "FlaxEngine"; + } + + /// + public override void Setup(BuildOptions options) + { + base.Setup(options); + + var depsRoot = options.DepsFolder; + switch (options.Platform.Target) + { + case TargetPlatform.Windows: + options.OutputFiles.Add(Path.Combine(depsRoot, "msdfgen-core.lib")); + break; + case TargetPlatform.Linux: + case TargetPlatform.Mac: + // todo + //options.OutputFiles.Add(Path.Combine(depsRoot, "msdfgen-core.a")); + break; + default: throw new InvalidPlatformException(options.Platform.Target); + } + + options.PublicIncludePaths.Add(Path.Combine(Globals.EngineRoot, @"Source\ThirdParty\msdfgen")); + } +} diff --git a/Source/ThirdParty/msdfgen/msdfgen.h b/Source/ThirdParty/msdfgen/msdfgen.h new file mode 100644 index 000000000..a0d69e2a5 --- /dev/null +++ b/Source/ThirdParty/msdfgen/msdfgen.h @@ -0,0 +1,4 @@ + +#pragma once + +#include "msdfgen/msdfgen.h" diff --git a/Source/ThirdParty/msdfgen/msdfgen/core/Bitmap.h b/Source/ThirdParty/msdfgen/msdfgen/core/Bitmap.h new file mode 100644 index 000000000..9a08749f4 --- /dev/null +++ b/Source/ThirdParty/msdfgen/msdfgen/core/Bitmap.h @@ -0,0 +1,50 @@ + +#pragma once + +#include "BitmapRef.hpp" + +namespace msdfgen { + +/// A 2D image bitmap with N channels of type T. Pixel memory is managed by the class. +template +class Bitmap { + +public: + Bitmap(); + Bitmap(int width, int height); + Bitmap(const BitmapConstRef &orig); + Bitmap(const Bitmap &orig); +#ifdef MSDFGEN_USE_CPP11 + Bitmap(Bitmap &&orig); +#endif + ~Bitmap(); + Bitmap &operator=(const BitmapConstRef &orig); + Bitmap &operator=(const Bitmap &orig); +#ifdef MSDFGEN_USE_CPP11 + Bitmap &operator=(Bitmap &&orig); +#endif + /// Bitmap width in pixels. + int width() const; + /// Bitmap height in pixels. + int height() const; + T *operator()(int x, int y); + const T *operator()(int x, int y) const; +#ifdef MSDFGEN_USE_CPP11 + explicit operator T *(); + explicit operator const T *() const; +#else + operator T *(); + operator const T *() const; +#endif + operator BitmapRef(); + operator BitmapConstRef() const; + +private: + T *pixels; + int w, h; + +}; + +} + +#include "Bitmap.hpp" diff --git a/Source/ThirdParty/msdfgen/msdfgen/core/Bitmap.hpp b/Source/ThirdParty/msdfgen/msdfgen/core/Bitmap.hpp new file mode 100644 index 000000000..940435778 --- /dev/null +++ b/Source/ThirdParty/msdfgen/msdfgen/core/Bitmap.hpp @@ -0,0 +1,117 @@ + +#include "Bitmap.h" + +#include +#include + +namespace msdfgen { + +template +Bitmap::Bitmap() : pixels(NULL), w(0), h(0) { } + +template +Bitmap::Bitmap(int width, int height) : w(width), h(height) { + pixels = new T[N*w*h]; +} + +template +Bitmap::Bitmap(const BitmapConstRef &orig) : w(orig.width), h(orig.height) { + pixels = new T[N*w*h]; + memcpy(pixels, orig.pixels, sizeof(T)*N*w*h); +} + +template +Bitmap::Bitmap(const Bitmap &orig) : w(orig.w), h(orig.h) { + pixels = new T[N*w*h]; + memcpy(pixels, orig.pixels, sizeof(T)*N*w*h); +} + +#ifdef MSDFGEN_USE_CPP11 +template +Bitmap::Bitmap(Bitmap &&orig) : pixels(orig.pixels), w(orig.w), h(orig.h) { + orig.pixels = NULL; + orig.w = 0, orig.h = 0; +} +#endif + +template +Bitmap::~Bitmap() { + delete [] pixels; +} + +template +Bitmap &Bitmap::operator=(const BitmapConstRef &orig) { + if (pixels != orig.pixels) { + delete [] pixels; + w = orig.width, h = orig.height; + pixels = new T[N*w*h]; + memcpy(pixels, orig.pixels, sizeof(T)*N*w*h); + } + return *this; +} + +template +Bitmap &Bitmap::operator=(const Bitmap &orig) { + if (this != &orig) { + delete [] pixels; + w = orig.w, h = orig.h; + pixels = new T[N*w*h]; + memcpy(pixels, orig.pixels, sizeof(T)*N*w*h); + } + return *this; +} + +#ifdef MSDFGEN_USE_CPP11 +template +Bitmap &Bitmap::operator=(Bitmap &&orig) { + if (this != &orig) { + delete [] pixels; + pixels = orig.pixels; + w = orig.w, h = orig.h; + orig.pixels = NULL; + } + return *this; +} +#endif + +template +int Bitmap::width() const { + return w; +} + +template +int Bitmap::height() const { + return h; +} + +template +T *Bitmap::operator()(int x, int y) { + return pixels+N*(w*y+x); +} + +template +const T *Bitmap::operator()(int x, int y) const { + return pixels+N*(w*y+x); +} + +template +Bitmap::operator T *() { + return pixels; +} + +template +Bitmap::operator const T *() const { + return pixels; +} + +template +Bitmap::operator BitmapRef() { + return BitmapRef(pixels, w, h); +} + +template +Bitmap::operator BitmapConstRef() const { + return BitmapConstRef(pixels, w, h); +} + +} diff --git a/Source/ThirdParty/msdfgen/msdfgen/core/BitmapRef.hpp b/Source/ThirdParty/msdfgen/msdfgen/core/BitmapRef.hpp new file mode 100644 index 000000000..cb17f95dc --- /dev/null +++ b/Source/ThirdParty/msdfgen/msdfgen/core/BitmapRef.hpp @@ -0,0 +1,41 @@ + +#pragma once + +#include "base.h" + +namespace msdfgen { + +/// Reference to a 2D image bitmap or a buffer acting as one. Pixel storage not owned or managed by the object. +template +struct BitmapRef { + + T *pixels; + int width, height; + + inline BitmapRef() : pixels(NULL), width(0), height(0) { } + inline BitmapRef(T *pixels, int width, int height) : pixels(pixels), width(width), height(height) { } + + inline T *operator()(int x, int y) const { + return pixels+N*(width*y+x); + } + +}; + +/// Constant reference to a 2D image bitmap or a buffer acting as one. Pixel storage not owned or managed by the object. +template +struct BitmapConstRef { + + const T *pixels; + int width, height; + + inline BitmapConstRef() : pixels(NULL), width(0), height(0) { } + inline BitmapConstRef(const T *pixels, int width, int height) : pixels(pixels), width(width), height(height) { } + inline BitmapConstRef(const BitmapRef &orig) : pixels(orig.pixels), width(orig.width), height(orig.height) { } + + inline const T *operator()(int x, int y) const { + return pixels+N*(width*y+x); + } + +}; + +} diff --git a/Source/ThirdParty/msdfgen/msdfgen/core/Contour.h b/Source/ThirdParty/msdfgen/msdfgen/core/Contour.h new file mode 100644 index 000000000..4cae48fad --- /dev/null +++ b/Source/ThirdParty/msdfgen/msdfgen/core/Contour.h @@ -0,0 +1,34 @@ + +#pragma once + +#include +#include "EdgeHolder.h" + +namespace msdfgen { + +/// A single closed contour of a shape. +class Contour { + +public: + /// The sequence of edges that make up the contour. + std::vector edges; + + /// Adds an edge to the contour. + void addEdge(const EdgeHolder &edge); +#ifdef MSDFGEN_USE_CPP11 + void addEdge(EdgeHolder &&edge); +#endif + /// Creates a new edge in the contour and returns its reference. + EdgeHolder &addEdge(); + /// Adjusts the bounding box to fit the contour. + void bound(double &l, double &b, double &r, double &t) const; + /// 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; + /// Computes the winding of the contour. Returns 1 if positive, -1 if negative. + int winding() const; + /// Reverses the sequence of edges on the contour. + void reverse(); + +}; + +} diff --git a/Source/ThirdParty/msdfgen/msdfgen/core/DistanceMapping.h b/Source/ThirdParty/msdfgen/msdfgen/core/DistanceMapping.h new file mode 100644 index 000000000..fadbefa54 --- /dev/null +++ b/Source/ThirdParty/msdfgen/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/Source/ThirdParty/msdfgen/msdfgen/core/EdgeColor.h b/Source/ThirdParty/msdfgen/msdfgen/core/EdgeColor.h new file mode 100644 index 000000000..5d3730c9a --- /dev/null +++ b/Source/ThirdParty/msdfgen/msdfgen/core/EdgeColor.h @@ -0,0 +1,20 @@ + +#pragma once + +#include "base.h" + +namespace msdfgen { + +/// Edge color specifies which color channels an edge belongs to. +enum EdgeColor { + BLACK = 0, + RED = 1, + GREEN = 2, + YELLOW = 3, + BLUE = 4, + MAGENTA = 5, + CYAN = 6, + WHITE = 7 +}; + +} diff --git a/Source/ThirdParty/msdfgen/msdfgen/core/EdgeHolder.h b/Source/ThirdParty/msdfgen/msdfgen/core/EdgeHolder.h new file mode 100644 index 000000000..5ae2dc231 --- /dev/null +++ b/Source/ThirdParty/msdfgen/msdfgen/core/EdgeHolder.h @@ -0,0 +1,41 @@ + +#pragma once + +#include "edge-segments.h" + +namespace msdfgen { + +/// Container for a single edge of dynamic type. +class EdgeHolder { + +public: + /// Swaps the edges held by a and b. + static void swap(EdgeHolder &a, EdgeHolder &b); + + 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); +#endif + ~EdgeHolder(); + EdgeHolder &operator=(const EdgeHolder &orig); +#ifdef MSDFGEN_USE_CPP11 + EdgeHolder &operator=(EdgeHolder &&orig); +#endif + EdgeSegment &operator*(); + const EdgeSegment &operator*() const; + EdgeSegment *operator->(); + const EdgeSegment *operator->() const; + operator EdgeSegment *(); + operator const EdgeSegment *() const; + +private: + EdgeSegment *edgeSegment; + +}; + +} diff --git a/Source/ThirdParty/msdfgen/msdfgen/core/MSDFErrorCorrection.h b/Source/ThirdParty/msdfgen/msdfgen/core/MSDFErrorCorrection.h new file mode 100644 index 000000000..9cd14eccf --- /dev/null +++ b/Source/ThirdParty/msdfgen/msdfgen/core/MSDFErrorCorrection.h @@ -0,0 +1,55 @@ + +#pragma once + +#include "SDFTransformation.h" +#include "Shape.h" +#include "BitmapRef.hpp" + +namespace msdfgen { + +/// Performs error correction on a computed MSDF to eliminate interpolation artifacts. This is a low-level class, you may want to use the API in msdf-error-correction.h instead. +class MSDFErrorCorrection { + +public: + /// Stencil flags. + enum Flags { + /// Texel marked as potentially causing interpolation errors. + ERROR = 1, + /// Texel marked as protected. Protected texels are only given the error flag if they cause inversion artifacts. + PROTECTED = 2 + }; + + MSDFErrorCorrection(); + explicit MSDFErrorCorrection(const BitmapRef &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. + void setMinImproveRatio(double minImproveRatio); + /// Flags all texels that are interpolated at corners as protected. + void protectCorners(const Shape &shape); + /// Flags all texels that contribute to edges as protected. + template + void protectEdges(const BitmapConstRef &sdf); + /// Flags all texels as protected. + void protectAll(); + /// Flags texels that are expected to cause interpolation artifacts based on analysis of the SDF only. + template + void findErrors(const BitmapConstRef &sdf); + /// Flags texels that are expected to cause interpolation artifacts based on analysis of the SDF and comparison with the exact shape distance. + template