kopia lustrzana https://github.com/jaseg/gerbolyze
svg-flatten: Add wasmtime support
rodzic
c58b6573f2
commit
7eb0b9d7e4
svg-flatten
upstream/clipper-6.4.2/cpp
|
@ -6,10 +6,17 @@ PKG_CONFIG ?= pkg-config
|
|||
PYTHON3 ?= python3
|
||||
|
||||
BUILDDIR ?= build
|
||||
CACHEDIR ?= cache
|
||||
PREFIX ?= /usr/local
|
||||
UPSTREAM_DIR ?= ../upstream
|
||||
UPSTREAM_DIR ?= upstream
|
||||
|
||||
SOURCES := src/svg_color.cpp \
|
||||
WASI_SDK ?= wasi-sdk-11.0
|
||||
WASI_SDK_URL ?= https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-11/wasi-sdk-11.0-linux.tar.gz
|
||||
WASI_SDK_PATH ?= $(CACHEDIR)/$(WASI_SDK)
|
||||
WASI_CXX ?= $(WASI_SDK_PATH)/bin/clang++ --sysroot=$(WASI_SDK_PATH)/share/wasi-sysroot
|
||||
|
||||
SOURCES := \
|
||||
src/svg_color.cpp \
|
||||
src/svg_doc.cpp \
|
||||
src/svg_geom.cpp \
|
||||
src/svg_import_util.cpp \
|
||||
|
@ -47,28 +54,47 @@ STB_INCLUDES ?= -isystem$(UPSTREAM_DIR)/stb
|
|||
INCLUDES := -Iinclude -Isrc $(CLIPPER_INCLUDES) $(VORONOI_INCLUDES) $(POISSON_INCLUDES) $(BASE64_INCLUDES) $(ARGAGG_INCLUDES) $(CAVC_INCLUDES) $(SUBPROCESS_INCLUDES) $(MINUNIT_INCLUDES) $(STB_INCLUDES)
|
||||
|
||||
CXXFLAGS := -std=c++2a -g -Wall -Wextra -O2
|
||||
LDFLAGS := -lm -lstdc++ -lstdc++fs # for debian's ancient compilers
|
||||
LDFLAGS := -lm -lstdc++
|
||||
|
||||
PKG_CONFIG_DEPS :=
|
||||
ifdef USE_SYSTEM_PUGIXML
|
||||
CXXFLAGS += $(shell $(PKG_CONFIG) --cflags pugixml)
|
||||
LDFLAGS += $(shell $(PKG_CONFIG) --libs pugixml)
|
||||
HOST_CXXFLAGS := $(CXXFLAGS) $(shell $(PKG_CONFIG) --cflags pugixml)
|
||||
HOST_LDFLAGS := $(LDFLAGS) $(shell $(PKG_CONFIG) --libs pugixml)
|
||||
HOST_SOURCES := $(SOURCES)
|
||||
HOST_INCLUDES := $(INCLUDES)
|
||||
else
|
||||
SOURCES += $(PUGIXML_SOURCES)
|
||||
INCLUDES += $(PUGIXML_INCLUDES)
|
||||
HOST_CXXFLAGS := $(CXXFLAGS)
|
||||
HOST_LDFLAGS := $(LDFLAGS)
|
||||
HOST_SOURCES := $(SOURCES) $(PUGIXML_SOURCES)
|
||||
HOST_INCLUDES := $(INCLUDES) $(PUGIXML_INCLUDES)
|
||||
endif
|
||||
|
||||
TARGET := svg-flatten
|
||||
HOST_LDFLAGS += -lstdc++fs # for debian's ancient compilers
|
||||
|
||||
all: $(BUILDDIR)/$(TARGET)
|
||||
WASI_CXXFLAGS ?= -DNOFORK -DNOTHROW -DWASI -DPUGIXML_NO_EXCEPTIONS -fno-exceptions $(CXXFLAGS)
|
||||
|
||||
$(BUILDDIR)/%.o: %.cpp
|
||||
BINARY := svg-flatten
|
||||
|
||||
all: $(BUILDDIR)/$(BINARY)
|
||||
|
||||
$(CACHEDIR)/$(WASI_SDK):
|
||||
mkdir -p $(dir $@)
|
||||
cd $(dir $@); curl -L ${WASI_SDK_URL} | tar xzf -
|
||||
|
||||
$(BUILDDIR)/wasi/%.o: %.cpp $(CACHEDIR)/$(WASI_SDK)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CXX) -c $(CXXFLAGS) $(CXXFLAGS) $(INCLUDES) -o $@ $^
|
||||
$(WASI_CXX) -c $(WASI_CXXFLAGS) $(INCLUDES) $(PUGIXML_INCLUDES) -o $@ $<
|
||||
|
||||
$(BUILDDIR)/$(TARGET): $(SOURCES:%.cpp=$(BUILDDIR)/%.o)
|
||||
$(BUILDDIR)/$(BINARY).wasm: $(patsubst %.cpp,$(BUILDDIR)/wasi/%.o,$(SOURCES) $(PUGIXML_SOURCES))
|
||||
@mkdir -p $(dir $@)
|
||||
$(WASI_CXX) $(WASI_CXXFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
$(BUILDDIR)/host/%.o: %.cpp
|
||||
@mkdir -p $(dir $@)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
$(CXX) -c $(HOST_CXXFLAGS) $(HOST_CXXFLAGS) $(HOST_INCLUDES) -o $@ $<
|
||||
|
||||
$(BUILDDIR)/$(BINARY): $(HOST_SOURCES:%.cpp=$(BUILDDIR)/host/%.o)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CXX) $(HOST_CXXFLAGS) -o $@ $^ $(HOST_LDFLAGS)
|
||||
|
||||
$(BUILDDIR)/nopencv-test: src/test/nopencv_test.cpp src/nopencv.cpp src/util.cpp
|
||||
@mkdir -p $(dir $@)
|
||||
|
@ -82,8 +108,12 @@ tests: $(BUILDDIR)/nopencv-test
|
|||
|
||||
.PHONY: install
|
||||
install:
|
||||
$(INSTALL) $(BUILDDIR)/$(TARGET) $(PREFIX)/bin
|
||||
$(INSTALL) $(BUILDDIR)/$(BINARY) $(PREFIX)/bin
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf $(BUILDDIR)
|
||||
|
||||
.PHONY: mrproper
|
||||
mrproper: clean
|
||||
rm -rf $(CACHEDIR)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <cstdio>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
@ -17,6 +18,34 @@ using argagg::parser;
|
|||
using namespace std;
|
||||
using namespace gerbolyze;
|
||||
|
||||
string temp_file_path(const char *suffix) {
|
||||
ifstream rnd;
|
||||
rnd.open("/dev/urandom", ios::in | ios::binary);
|
||||
|
||||
char fn_buf[8];
|
||||
rnd.read(fn_buf, sizeof(fn_buf));
|
||||
|
||||
if (rnd.rdstate()) {
|
||||
cerr << "Error getting random data for temporary file name" << endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
ostringstream out;
|
||||
out << "tmp_";
|
||||
for (size_t i=0; i<sizeof(fn_buf); i++) {
|
||||
out << setfill('0') << setw(2) << setbase(16) << static_cast<int>(fn_buf[i] & 0xff);
|
||||
}
|
||||
out << suffix;
|
||||
|
||||
cerr << "out \"" << out.str() << "\"" << endl;
|
||||
#ifndef WASI
|
||||
filesystem::path base = filesystem::temp_directory_path();
|
||||
return (base / out.str()).native();
|
||||
#else
|
||||
return "/tmp/" + out.str();
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
parser argparser {{
|
||||
{"help", {"-h", "--help"},
|
||||
|
@ -114,15 +143,7 @@ int main(int argc, char **argv) {
|
|||
<< endl;
|
||||
|
||||
argagg::parser_results args;
|
||||
try {
|
||||
args = argparser.parse(argc, argv);
|
||||
} catch (const std::exception& e) {
|
||||
argagg::fmt_ostream fmt(cerr);
|
||||
fmt << usage.str() << argparser << '\n'
|
||||
<< "Encountered exception while parsing arguments: " << e.what()
|
||||
<< '\n';
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
args = argparser.parse(argc, argv);
|
||||
|
||||
if (args["help"]) {
|
||||
argagg::fmt_ostream fmt(cerr);
|
||||
|
@ -267,8 +288,8 @@ int main(int argc, char **argv) {
|
|||
transform(ending.begin(), ending.end(), ending.begin(), [](unsigned char c){ return std::tolower(c); }); /* c++ yeah */
|
||||
}
|
||||
|
||||
filesystem::path barf = { filesystem::temp_directory_path() /= (std::tmpnam(nullptr) + string(".svg")) };
|
||||
filesystem::path frob = { filesystem::temp_directory_path() /= (std::tmpnam(nullptr) + string(".svg")) };
|
||||
string barf = temp_file_path(".svg");
|
||||
string frob = temp_file_path(".svg");
|
||||
|
||||
bool is_svg = args["force_svg"] || (ending == ".svg" && !args["force_png"]);
|
||||
if (!is_svg) {
|
||||
|
@ -352,10 +373,15 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
string dpi_str = to_string(dpi);
|
||||
|
||||
#ifndef NOFORK
|
||||
const char *command_line[] = {nullptr, "--keep-named-groups", "--dpi", dpi_str.c_str(), barf.c_str(), frob.c_str(), nullptr};
|
||||
if (run_cargo_command("usvg", command_line, "USVG")) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
#else
|
||||
cerr << "Error: The caller of svg-flatten (you?) must use --no-usvg and run usvg externally since wasi does not yet support fork/exec." << endl;
|
||||
return EXIT_FAILURE;
|
||||
#endif
|
||||
}
|
||||
|
||||
VectorizerSelectorizer vec_sel(vectorizer, args["vectorizer_map"] ? args["vectorizer_map"].as<string>() : "");
|
||||
|
|
|
@ -61,6 +61,11 @@ string gerbolyze::parse_data_iri(const string &data_url) {
|
|||
size_t b64_begin = data_url.find_first_not_of(" ", foo + strlen("base64,"));
|
||||
assert(b64_begin != string::npos);
|
||||
|
||||
return base64_decode(data_url.substr(b64_begin));
|
||||
bool err_out;
|
||||
string out = base64_decode(data_url.substr(b64_begin), false, &err_out);
|
||||
|
||||
if (err_out)
|
||||
return "";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#ifndef NOFORK
|
||||
#include <pwd.h>
|
||||
#include <subprocess.h>
|
||||
#endif
|
||||
#include <filesystem>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifndef NOFORK
|
||||
int gerbolyze::run_cargo_command(const char *cmd_name, const char *cmdline[], const char *envvar) {
|
||||
const char *homedir;
|
||||
if ((homedir = getenv("HOME")) == NULL) {
|
||||
|
@ -81,4 +84,11 @@ int gerbolyze::run_cargo_command(const char *cmd_name, const char *cmdline[], co
|
|||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int gerbolyze::run_cargo_command(const char *cmd_name, const char *cmdline[], const char *envvar) {
|
||||
(void) cmd_name, (void) cmdline, (void) envvar;
|
||||
cerr << "Error: Cannot spawn " << cmd_name << " subprocess since binary was built with fork/exec disabled (-DNOFORK=1)" << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
../upstream
|
|
@ -39,6 +39,9 @@
|
|||
*******************************************************************************/
|
||||
|
||||
#include "clipper.hpp"
|
||||
#ifdef NOTHROW
|
||||
#include <iostream>
|
||||
#endif
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
@ -133,6 +136,18 @@ struct LocMinSorter
|
|||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline void panic(const char *msg);
|
||||
inline void panic(const char *msg) {
|
||||
#ifdef NOTHROW
|
||||
std::cerr << "Fatal clipper exception: " << msg << std::endl;
|
||||
abort();
|
||||
#else
|
||||
throw clipperException(msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline cInt Round(double val)
|
||||
{
|
||||
if ((val < 0)) return static_cast<cInt>(val - 0.5);
|
||||
|
@ -898,7 +913,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");
|
||||
panic("Coordinate outside allowed range");
|
||||
}
|
||||
else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange)
|
||||
{
|
||||
|
@ -1046,10 +1061,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.");
|
||||
panic("AddPath: Open paths must be subject.");
|
||||
#else
|
||||
if (!Closed)
|
||||
throw clipperException("AddPath: Open paths have been disabled.");
|
||||
panic("AddPath: Open paths have been disabled.");
|
||||
#endif
|
||||
|
||||
int highI = (int)pg.size() -1;
|
||||
|
@ -1062,8 +1077,10 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
|
|||
|
||||
bool IsFlat = true;
|
||||
//1. Basic (first) edge initialization ...
|
||||
#ifndef NOTHROW
|
||||
try
|
||||
{
|
||||
#endif
|
||||
edges[1].Curr = pg[1];
|
||||
RangeTest(pg[0], m_UseFullRange);
|
||||
RangeTest(pg[highI], m_UseFullRange);
|
||||
|
@ -1074,12 +1091,14 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
|
|||
RangeTest(pg[i], m_UseFullRange);
|
||||
InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]);
|
||||
}
|
||||
#ifndef NOTHROW
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
delete [] edges;
|
||||
throw; //range test fails
|
||||
}
|
||||
#endif
|
||||
TEdge *eStart = &edges[0];
|
||||
|
||||
//2. Remove duplicate vertices, and (when closed) collinear edges ...
|
||||
|
@ -1439,10 +1458,10 @@ void ClipperBase::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2)
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void ClipperBase::UpdateEdgeIntoAEL(TEdge *&e)
|
||||
void ClipperBase::UpdateEdgeIntoAEL(TEdge *&e, bool *err_out)
|
||||
{
|
||||
if (!e->NextInLML)
|
||||
throw clipperException("UpdateEdgeIntoAEL: invalid call");
|
||||
*err_out = true;
|
||||
|
||||
e->NextInLML->OutIdx = e->OutIdx;
|
||||
TEdge* AelPrev = e->PrevInAEL;
|
||||
|
@ -1510,7 +1529,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.");
|
||||
panic("Error: PolyTree struct is needed for open path clipping.");
|
||||
m_ExecuteLocked = true;
|
||||
solution.resize(0);
|
||||
m_SubjFillType = subjFillType;
|
||||
|
@ -1559,36 +1578,30 @@ void Clipper::FixHoleLinkage(OutRec &outrec)
|
|||
|
||||
bool Clipper::ExecuteInternal()
|
||||
{
|
||||
bool succeeded = true;
|
||||
try {
|
||||
Reset();
|
||||
m_Maxima = MaximaList();
|
||||
m_SortedEdges = 0;
|
||||
bool error = false;
|
||||
Reset();
|
||||
m_Maxima = MaximaList();
|
||||
m_SortedEdges = 0;
|
||||
|
||||
succeeded = true;
|
||||
cInt botY, topY;
|
||||
if (!PopScanbeam(botY)) return false;
|
||||
InsertLocalMinimaIntoAEL(botY);
|
||||
while (PopScanbeam(topY) || LocalMinimaPending())
|
||||
{
|
||||
ProcessHorizontals();
|
||||
ClearGhostJoins();
|
||||
if (!ProcessIntersections(topY))
|
||||
{
|
||||
succeeded = false;
|
||||
break;
|
||||
}
|
||||
ProcessEdgesAtTopOfScanbeam(topY);
|
||||
botY = topY;
|
||||
InsertLocalMinimaIntoAEL(botY);
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
error = false;
|
||||
cInt botY, topY;
|
||||
if (!PopScanbeam(botY)) return false;
|
||||
InsertLocalMinimaIntoAEL(botY);
|
||||
while (PopScanbeam(topY) || LocalMinimaPending())
|
||||
{
|
||||
succeeded = false;
|
||||
ProcessHorizontals(&error);
|
||||
ClearGhostJoins();
|
||||
if (!ProcessIntersections(topY, &error))
|
||||
{
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
ProcessEdgesAtTopOfScanbeam(topY, &error);
|
||||
botY = topY;
|
||||
InsertLocalMinimaIntoAEL(botY);
|
||||
}
|
||||
|
||||
if (succeeded)
|
||||
if (!error)
|
||||
{
|
||||
//fix orientations ...
|
||||
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
|
||||
|
@ -1617,7 +1630,7 @@ bool Clipper::ExecuteInternal()
|
|||
|
||||
ClearJoins();
|
||||
ClearGhostJoins();
|
||||
return succeeded;
|
||||
return !error;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
@ -2509,11 +2522,11 @@ OutPt* Clipper::GetLastOutPt(TEdge *e)
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void Clipper::ProcessHorizontals()
|
||||
void Clipper::ProcessHorizontals(bool *err_out)
|
||||
{
|
||||
TEdge* horzEdge;
|
||||
while (PopEdgeFromSEL(horzEdge))
|
||||
ProcessHorizontal(horzEdge);
|
||||
ProcessHorizontal(horzEdge, err_out);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
@ -2633,7 +2646,7 @@ void GetHorzDirection(TEdge& HorzEdge, Direction& Dir, cInt& Left, cInt& Right)
|
|||
* the AEL. These 'promoted' edges may in turn intersect [%] with other HEs. *
|
||||
*******************************************************************************/
|
||||
|
||||
void Clipper::ProcessHorizontal(TEdge *horzEdge)
|
||||
void Clipper::ProcessHorizontal(TEdge *horzEdge, bool *err_out)
|
||||
{
|
||||
Direction dir;
|
||||
cInt horzLeft, horzRight;
|
||||
|
@ -2762,7 +2775,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
|
|||
//Break out of loop if HorzEdge.NextInLML is not also horizontal ...
|
||||
if (!horzEdge->NextInLML || !IsHorizontal(*horzEdge->NextInLML)) break;
|
||||
|
||||
UpdateEdgeIntoAEL(horzEdge);
|
||||
UpdateEdgeIntoAEL(horzEdge, err_out);
|
||||
if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Bot);
|
||||
GetHorzDirection(*horzEdge, dir, horzLeft, horzRight);
|
||||
|
||||
|
@ -2791,7 +2804,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
|
|||
if(horzEdge->OutIdx >= 0)
|
||||
{
|
||||
op1 = AddOutPt( horzEdge, horzEdge->Top);
|
||||
UpdateEdgeIntoAEL(horzEdge);
|
||||
UpdateEdgeIntoAEL(horzEdge, err_out);
|
||||
if (horzEdge->WindDelta == 0) return;
|
||||
//nb: HorzEdge is no longer horizontal here
|
||||
TEdge* ePrev = horzEdge->PrevInAEL;
|
||||
|
@ -2814,7 +2827,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
|
|||
}
|
||||
}
|
||||
else
|
||||
UpdateEdgeIntoAEL(horzEdge);
|
||||
UpdateEdgeIntoAEL(horzEdge, err_out);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2824,22 +2837,25 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool Clipper::ProcessIntersections(const cInt topY)
|
||||
bool Clipper::ProcessIntersections(const cInt topY, bool *err_out)
|
||||
{
|
||||
(void) err_out;
|
||||
if( !m_ActiveEdges ) return true;
|
||||
try {
|
||||
//try {
|
||||
BuildIntersectList(topY);
|
||||
size_t IlSize = m_IntersectList.size();
|
||||
if (IlSize == 0) return true;
|
||||
if (IlSize == 1 || FixupIntersectionOrder()) ProcessIntersectList();
|
||||
else return false;
|
||||
/*
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
m_SortedEdges = 0;
|
||||
DisposeIntersectNodes();
|
||||
throw clipperException("ProcessIntersections error");
|
||||
*err_out = true;
|
||||
}
|
||||
*/
|
||||
m_SortedEdges = 0;
|
||||
return true;
|
||||
}
|
||||
|
@ -2954,7 +2970,7 @@ bool Clipper::FixupIntersectionOrder()
|
|||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void Clipper::DoMaxima(TEdge *e)
|
||||
void Clipper::DoMaxima(TEdge *e, bool *err_out)
|
||||
{
|
||||
TEdge* eMaxPair = GetMaximaPairEx(e);
|
||||
if (!eMaxPair)
|
||||
|
@ -3002,11 +3018,11 @@ void Clipper::DoMaxima(TEdge *e)
|
|||
DeleteFromAEL(eMaxPair);
|
||||
}
|
||||
#endif
|
||||
else throw clipperException("DoMaxima error");
|
||||
else *err_out = true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
|
||||
void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY, bool *err_out)
|
||||
{
|
||||
TEdge* e = m_ActiveEdges;
|
||||
while( e )
|
||||
|
@ -3025,7 +3041,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
|
|||
{
|
||||
if (m_StrictSimple) m_Maxima.push_back(e->Top.X);
|
||||
TEdge* ePrev = e->PrevInAEL;
|
||||
DoMaxima(e);
|
||||
DoMaxima(e, err_out);
|
||||
if( !ePrev ) e = m_ActiveEdges;
|
||||
else e = ePrev->NextInAEL;
|
||||
}
|
||||
|
@ -3034,7 +3050,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
|
|||
//2. promote horizontal edges, otherwise update Curr.X and Curr.Y ...
|
||||
if (IsIntermediate(e, topY) && IsHorizontal(*e->NextInLML))
|
||||
{
|
||||
UpdateEdgeIntoAEL(e);
|
||||
UpdateEdgeIntoAEL(e, err_out);
|
||||
if (e->OutIdx >= 0)
|
||||
AddOutPt(e, e->Bot);
|
||||
AddEdgeToSEL(e);
|
||||
|
@ -3072,7 +3088,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
|
|||
|
||||
//3. Process horizontals at the Top of the scanbeam ...
|
||||
m_Maxima.sort();
|
||||
ProcessHorizontals();
|
||||
ProcessHorizontals(err_out);
|
||||
m_Maxima.clear();
|
||||
|
||||
//4. Promote intermediate vertices ...
|
||||
|
@ -3084,7 +3100,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
|
|||
OutPt* op = 0;
|
||||
if( e->OutIdx >= 0 )
|
||||
op = AddOutPt(e, e->Top);
|
||||
UpdateEdgeIntoAEL(e);
|
||||
UpdateEdgeIntoAEL(e, err_out);
|
||||
|
||||
//if output polygons share an edge, they'll need joining later ...
|
||||
TEdge* ePrev = e->PrevInAEL;
|
||||
|
|
|
@ -242,7 +242,7 @@ protected:
|
|||
void DisposeOutRec(PolyOutList::size_type index);
|
||||
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
|
||||
void DeleteFromAEL(TEdge *e);
|
||||
void UpdateEdgeIntoAEL(TEdge *&e);
|
||||
void UpdateEdgeIntoAEL(TEdge *&e, bool *err_out);
|
||||
|
||||
typedef std::vector<LocalMinimum> MinimaList;
|
||||
MinimaList::iterator m_CurrentLM;
|
||||
|
@ -317,9 +317,9 @@ private:
|
|||
void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
|
||||
bool IsContributing(const TEdge& edge) const;
|
||||
bool IsTopHorz(const cInt XPos);
|
||||
void DoMaxima(TEdge *e);
|
||||
void ProcessHorizontals();
|
||||
void ProcessHorizontal(TEdge *horzEdge);
|
||||
void DoMaxima(TEdge *e, bool *err_out);
|
||||
void ProcessHorizontals(bool *err_out);
|
||||
void ProcessHorizontal(TEdge *horzEdge, bool *err_out);
|
||||
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
|
||||
OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
|
||||
OutRec* GetOutRec(int idx);
|
||||
|
@ -327,10 +327,10 @@ private:
|
|||
void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt);
|
||||
OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
|
||||
OutPt* GetLastOutPt(TEdge *e);
|
||||
bool ProcessIntersections(const cInt topY);
|
||||
bool ProcessIntersections(const cInt topY, bool *err_out);
|
||||
void BuildIntersectList(const cInt topY);
|
||||
void ProcessIntersectList();
|
||||
void ProcessEdgesAtTopOfScanbeam(const cInt topY);
|
||||
void ProcessEdgesAtTopOfScanbeam(const cInt topY, bool *err_out);
|
||||
void BuildResult(Paths& polys);
|
||||
void BuildResult2(PolyTree& polytree);
|
||||
void SetHoleState(TEdge *e, OutRec *outrec);
|
||||
|
|
Ładowanie…
Reference in New Issue