diff --git a/core/SCsub b/core/SCsub index 06efc8408d2..166b7083e4e 100644 --- a/core/SCsub +++ b/core/SCsub @@ -58,6 +58,7 @@ thirdparty_misc_sources = [ "md5.cpp", "pcg.cpp", "triangulator.cpp", + "clipper.cpp", ] thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_misc_sources] env_thirdparty.add_source_files(env.core_sources, thirdparty_misc_sources) diff --git a/editor/SCsub b/editor/SCsub index 82a4ecb6c07..7d48e47c9fa 100644 --- a/editor/SCsub +++ b/editor/SCsub @@ -79,9 +79,6 @@ if env['tools']: env.CommandNoCache('#editor/builtin_fonts.gen.h', flist, run_in_subprocess(editor_builders.make_fonts_header)) env.add_source_files(env.editor_sources, "*.cpp") - env_thirdparty = env.Clone() - env_thirdparty.disable_warnings() - env_thirdparty.add_source_files(env.editor_sources, ["#thirdparty/misc/clipper.cpp"]) SConscript('collada/SCsub') SConscript('doc/SCsub') diff --git a/thirdparty/README.md b/thirdparty/README.md index bc820634bb2..732c08fdea4 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -346,7 +346,7 @@ Collection of single-file libraries used in Godot components. * License: Public Domain - `clipper.{cpp,hpp}` * Upstream: https://sourceforge.net/projects/polyclipping - * Version: 6.4.2 + * Version: 6.4.2 + Godot changes (added optional exceptions handling) * License: BSL-1.0 - `fastlz.{c,h}` * Upstream: https://github.com/ariya/FastLZ diff --git a/thirdparty/misc/clipper-exceptions.patch b/thirdparty/misc/clipper-exceptions.patch new file mode 100644 index 00000000000..537afd59b3d --- /dev/null +++ b/thirdparty/misc/clipper-exceptions.patch @@ -0,0 +1,154 @@ +diff --git a/thirdparty/misc/clipper.cpp b/thirdparty/misc/clipper.cpp +index 8c3a59c4ca..c67045d113 100644 +--- a/thirdparty/misc/clipper.cpp ++++ b/thirdparty/misc/clipper.cpp +@@ -48,6 +48,38 @@ + #include + #include + ++//Explicitly disables exceptions handling for target platform ++//#define CLIPPER_NOEXCEPTION ++ ++#define CLIPPER_THROW(exception) std::abort() ++#define CLIPPER_TRY if(true) ++#define CLIPPER_CATCH(exception) if(false) ++ ++#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND) ++ #ifndef CLIPPER_NOEXCEPTION ++ #undef CLIPPER_THROW ++ #define CLIPPER_THROW(exception) throw exception ++ #undef CLIPPER_TRY ++ #define CLIPPER_TRY try ++ #undef CLIPPER_CATCH ++ #define CLIPPER_CATCH(exception) catch(exception) ++ #endif ++#endif ++ ++//Optionally allows to override exception macros ++#if defined(CLIPPER_THROW_USER) ++ #undef CLIPPER_THROW ++ #define CLIPPER_THROW CLIPPER_THROW_USER ++#endif ++#if defined(CLIPPER_TRY_USER) ++ #undef CLIPPER_TRY ++ #define CLIPPER_TRY CLIPPER_TRY_USER ++#endif ++#if defined(CLIPPER_CATCH_USER) ++ #undef CLIPPER_CATCH ++ #define CLIPPER_CATCH CLIPPER_CATCH_USER ++#endif ++ + namespace ClipperLib { + + static double const pi = 3.141592653589793238; +@@ -898,7 +930,7 @@ void RangeTest(const IntPoint& Pt, bool& useFullRange) + if (useFullRange) + { + if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange) +- throw clipperException("Coordinate outside allowed range"); ++ CLIPPER_THROW(clipperException("Coordinate outside allowed range")); + } + else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange) + { +@@ -1046,10 +1078,10 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) + { + #ifdef use_lines + if (!Closed && PolyTyp == ptClip) +- throw clipperException("AddPath: Open paths must be subject."); ++ CLIPPER_THROW(clipperException("AddPath: Open paths must be subject.")); + #else + if (!Closed) +- throw clipperException("AddPath: Open paths have been disabled."); ++ CLIPPER_THROW(clipperException("AddPath: Open paths have been disabled.")); + #endif + + int highI = (int)pg.size() -1; +@@ -1062,7 +1094,7 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) + + bool IsFlat = true; + //1. Basic (first) edge initialization ... +- try ++ CLIPPER_TRY + { + edges[1].Curr = pg[1]; + RangeTest(pg[0], m_UseFullRange); +@@ -1075,10 +1107,10 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) + InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]); + } + } +- catch(...) ++ CLIPPER_CATCH(...) + { + delete [] edges; +- throw; //range test fails ++ CLIPPER_THROW(); //range test fails + } + TEdge *eStart = &edges[0]; + +@@ -1442,7 +1474,7 @@ void ClipperBase::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2) + void ClipperBase::UpdateEdgeIntoAEL(TEdge *&e) + { + if (!e->NextInLML) +- throw clipperException("UpdateEdgeIntoAEL: invalid call"); ++ CLIPPER_THROW(clipperException("UpdateEdgeIntoAEL: invalid call")); + + e->NextInLML->OutIdx = e->OutIdx; + TEdge* AelPrev = e->PrevInAEL; +@@ -1510,7 +1542,7 @@ bool Clipper::Execute(ClipType clipType, Paths &solution, + { + if( m_ExecuteLocked ) return false; + if (m_HasOpenPaths) +- throw clipperException("Error: PolyTree struct is needed for open path clipping."); ++ CLIPPER_THROW(clipperException("Error: PolyTree struct is needed for open path clipping.")); + m_ExecuteLocked = true; + solution.resize(0); + m_SubjFillType = subjFillType; +@@ -1560,7 +1592,7 @@ void Clipper::FixHoleLinkage(OutRec &outrec) + bool Clipper::ExecuteInternal() + { + bool succeeded = true; +- try { ++ CLIPPER_TRY { + Reset(); + m_Maxima = MaximaList(); + m_SortedEdges = 0; +@@ -1583,7 +1615,7 @@ bool Clipper::ExecuteInternal() + InsertLocalMinimaIntoAEL(botY); + } + } +- catch(...) ++ CLIPPER_CATCH(...) + { + succeeded = false; + } +@@ -2827,18 +2859,18 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge) + bool Clipper::ProcessIntersections(const cInt topY) + { + if( !m_ActiveEdges ) return true; +- try { ++ CLIPPER_TRY { + BuildIntersectList(topY); + size_t IlSize = m_IntersectList.size(); + if (IlSize == 0) return true; + if (IlSize == 1 || FixupIntersectionOrder()) ProcessIntersectList(); + else return false; + } +- catch(...) ++ CLIPPER_CATCH(...) + { + m_SortedEdges = 0; + DisposeIntersectNodes(); +- throw clipperException("ProcessIntersections error"); ++ CLIPPER_THROW(clipperException("ProcessIntersections error")); + } + m_SortedEdges = 0; + return true; +@@ -3002,7 +3034,7 @@ void Clipper::DoMaxima(TEdge *e) + DeleteFromAEL(eMaxPair); + } + #endif +- else throw clipperException("DoMaxima error"); ++ else CLIPPER_THROW(clipperException("DoMaxima error")); + } + //------------------------------------------------------------------------------ + diff --git a/thirdparty/misc/clipper.cpp b/thirdparty/misc/clipper.cpp index 8c3a59c4cad..c67045d1132 100644 --- a/thirdparty/misc/clipper.cpp +++ b/thirdparty/misc/clipper.cpp @@ -48,6 +48,38 @@ #include #include +//Explicitly disables exceptions handling for target platform +//#define CLIPPER_NOEXCEPTION + +#define CLIPPER_THROW(exception) std::abort() +#define CLIPPER_TRY if(true) +#define CLIPPER_CATCH(exception) if(false) + +#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND) + #ifndef CLIPPER_NOEXCEPTION + #undef CLIPPER_THROW + #define CLIPPER_THROW(exception) throw exception + #undef CLIPPER_TRY + #define CLIPPER_TRY try + #undef CLIPPER_CATCH + #define CLIPPER_CATCH(exception) catch(exception) + #endif +#endif + +//Optionally allows to override exception macros +#if defined(CLIPPER_THROW_USER) + #undef CLIPPER_THROW + #define CLIPPER_THROW CLIPPER_THROW_USER +#endif +#if defined(CLIPPER_TRY_USER) + #undef CLIPPER_TRY + #define CLIPPER_TRY CLIPPER_TRY_USER +#endif +#if defined(CLIPPER_CATCH_USER) + #undef CLIPPER_CATCH + #define CLIPPER_CATCH CLIPPER_CATCH_USER +#endif + namespace ClipperLib { static double const pi = 3.141592653589793238; @@ -898,7 +930,7 @@ void RangeTest(const IntPoint& Pt, bool& useFullRange) if (useFullRange) { if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange) - throw clipperException("Coordinate outside allowed range"); + CLIPPER_THROW(clipperException("Coordinate outside allowed range")); } else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange) { @@ -1046,10 +1078,10 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) { #ifdef use_lines if (!Closed && PolyTyp == ptClip) - throw clipperException("AddPath: Open paths must be subject."); + CLIPPER_THROW(clipperException("AddPath: Open paths must be subject.")); #else if (!Closed) - throw clipperException("AddPath: Open paths have been disabled."); + CLIPPER_THROW(clipperException("AddPath: Open paths have been disabled.")); #endif int highI = (int)pg.size() -1; @@ -1062,7 +1094,7 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) bool IsFlat = true; //1. Basic (first) edge initialization ... - try + CLIPPER_TRY { edges[1].Curr = pg[1]; RangeTest(pg[0], m_UseFullRange); @@ -1075,10 +1107,10 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]); } } - catch(...) + CLIPPER_CATCH(...) { delete [] edges; - throw; //range test fails + CLIPPER_THROW(); //range test fails } TEdge *eStart = &edges[0]; @@ -1442,7 +1474,7 @@ void ClipperBase::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2) void ClipperBase::UpdateEdgeIntoAEL(TEdge *&e) { if (!e->NextInLML) - throw clipperException("UpdateEdgeIntoAEL: invalid call"); + CLIPPER_THROW(clipperException("UpdateEdgeIntoAEL: invalid call")); e->NextInLML->OutIdx = e->OutIdx; TEdge* AelPrev = e->PrevInAEL; @@ -1510,7 +1542,7 @@ bool Clipper::Execute(ClipType clipType, Paths &solution, { if( m_ExecuteLocked ) return false; if (m_HasOpenPaths) - throw clipperException("Error: PolyTree struct is needed for open path clipping."); + CLIPPER_THROW(clipperException("Error: PolyTree struct is needed for open path clipping.")); m_ExecuteLocked = true; solution.resize(0); m_SubjFillType = subjFillType; @@ -1560,7 +1592,7 @@ void Clipper::FixHoleLinkage(OutRec &outrec) bool Clipper::ExecuteInternal() { bool succeeded = true; - try { + CLIPPER_TRY { Reset(); m_Maxima = MaximaList(); m_SortedEdges = 0; @@ -1583,7 +1615,7 @@ bool Clipper::ExecuteInternal() InsertLocalMinimaIntoAEL(botY); } } - catch(...) + CLIPPER_CATCH(...) { succeeded = false; } @@ -2827,18 +2859,18 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge) bool Clipper::ProcessIntersections(const cInt topY) { if( !m_ActiveEdges ) return true; - try { + CLIPPER_TRY { BuildIntersectList(topY); size_t IlSize = m_IntersectList.size(); if (IlSize == 0) return true; if (IlSize == 1 || FixupIntersectionOrder()) ProcessIntersectList(); else return false; } - catch(...) + CLIPPER_CATCH(...) { m_SortedEdges = 0; DisposeIntersectNodes(); - throw clipperException("ProcessIntersections error"); + CLIPPER_THROW(clipperException("ProcessIntersections error")); } m_SortedEdges = 0; return true; @@ -3002,7 +3034,7 @@ void Clipper::DoMaxima(TEdge *e) DeleteFromAEL(eMaxPair); } #endif - else throw clipperException("DoMaxima error"); + else CLIPPER_THROW(clipperException("DoMaxima error")); } //------------------------------------------------------------------------------