git: 79e5fba255ef - main - cad/PrusaSlicer: update to 2.6.0
Date: Fri, 28 Jul 2023 12:48:14 UTC
The branch main has been updated by fernape:
URL: https://cgit.FreeBSD.org/ports/commit/?id=79e5fba255ef2620dd872e21bdd7dc667fea3c19
commit 79e5fba255ef2620dd872e21bdd7dc667fea3c19
Author: zielonka michal <michal.zielonka.8001@gmail.com>
AuthorDate: 2023-07-27 06:38:24 +0000
Commit: Fernando Apesteguía <fernape@FreeBSD.org>
CommitDate: 2023-07-28 12:47:57 +0000
cad/PrusaSlicer: update to 2.6.0
PR: 272730
Reported by: michal.zielonka.8001@gmail.com
Approved by: teodorsigaev@gmail.com (maintainer)
---
cad/PrusaSlicer/Makefile | 14 +-
cad/PrusaSlicer/distinfo | 6 +-
cad/PrusaSlicer/files/patch-CMakeLists.txt | 19 +-
cad/PrusaSlicer/files/patch-src_CMakeLists.txt | 15 +-
cad/PrusaSlicer/files/patch-src_avrdude_arduino.c | 10 +
.../files/patch-src_libnanosvg_nanosvg.h | 3109 ++++++++++++++++++++
.../files/patch-src_libnanosvg_nanosvgrast.h | 1485 ++++++++++
.../files/patch-src_libslic3r_CMakeLists.txt | 6 +-
.../files/patch-src_libslic3r_Format_SL1__SVG.cpp | 12 +
.../files/patch-src_libslic3r_GCodeSender.cpp | 20 +
.../files/patch-src_libslic3r_NSVGUtils.hpp | 11 +
.../patch-src_libslic3r_SupportSpotsGenerator.cpp | 11 +
.../files/patch-src_occt__wrapper_CMakeLists.txt | 6 +-
.../files/patch-src_qhull_CMakeLists.txt | 29 -
.../files/patch-src_slic3r_CMakeLists.txt | 18 +-
.../files/patch-src_slic3r_GUI_BitmapCache.cpp | 32 +
.../files/patch-src_slic3r_GUI_ConfigWizard.cpp | 56 +
.../files/patch-src_slic3r_GUI_ConfigWizard.hpp | 20 +
...tch-src_slic3r_GUI_DesktopIntegrationDialog.cpp | 8 +
...tch-src_slic3r_GUI_DesktopIntegrationDialog.hpp | 15 +
.../files/patch-src_slic3r_GUI_ExtraRenderers.cpp | 11 +
.../files/patch-src_slic3r_GUI_Field.cpp | 11 +
.../files/patch-src_slic3r_GUI_GLCanvas3D.cpp | 11 +
.../files/patch-src_slic3r_GUI_GLTexture.cpp | 13 +
cad/PrusaSlicer/files/patch-src_slic3r_GUI_GUI.cpp | 20 +
cad/PrusaSlicer/files/patch-src_slic3r_GUI_GUI.hpp | 11 +
.../files/patch-src_slic3r_GUI_GUI__App.cpp | 155 +-
.../files/patch-src_slic3r_GUI_GUI__Factories.cpp | 11 +
.../patch-src_slic3r_GUI_GUI__ObjectLayers.cpp | 20 +
...atch-src_slic3r_GUI_GUI__ObjectManipulation.cpp | 12 +
.../files/patch-src_slic3r_GUI_GUI__Preview.cpp | 28 +
.../files/patch-src_slic3r_GUI_GUI__Preview.hpp | 11 +
.../files/patch-src_slic3r_GUI_GUI__Utils.cpp | 20 +
.../patch-src_slic3r_GUI_Gizmos_GLGizmoEmboss.cpp | 11 +
.../files/patch-src_slic3r_GUI_ImGuiWrapper.cpp | 13 +
.../files/patch-src_slic3r_GUI_InstanceCheck.cpp | 11 +-
.../files/patch-src_slic3r_GUI_InstanceCheck.hpp | 20 +
.../patch-src_slic3r_GUI_KBShortcutsDialog.cpp | 11 +
.../patch-src_slic3r_GUI_Mouse3DController.cpp | 20 +
.../files/patch-src_slic3r_GUI_OpenGLManager.cpp | 19 +-
.../files/patch-src_slic3r_GUI_OptionsGroup.cpp | 20 +
.../files/patch-src_slic3r_GUI_Plater.cpp | 29 +
.../files/patch-src_slic3r_GUI_Preferences.cpp | 20 +
.../patch-src_slic3r_GUI_PresetComboBoxes.cpp | 11 +
.../patch-src_slic3r_GUI_PresetComboBoxes.hpp | 11 +
.../patch-src_slic3r_GUI_PrintHostDialogs.cpp | 58 +
.../patch-src_slic3r_GUI_RemovableDriveManager.cpp | 11 +
cad/PrusaSlicer/files/patch-src_slic3r_GUI_Tab.cpp | 56 +
.../patch-src_slic3r_GUI_UnsavedChangesDialog.cpp | 65 +
.../patch-src_slic3r_GUI_UnsavedChangesDialog.hpp | 20 +
.../files/patch-src_slic3r_GUI_UpdateDialogs.cpp | 20 +
.../files/patch-src_slic3r_GUI_wxExtensions.cpp | 41 +
.../files/patch-src_slic3r_GUI_wxExtensions.hpp | 11 +
.../patch-src_slic3r_Utils_FontConfigHelp.hpp | 11 +
.../files/patch-src_slic3r_Utils_Serial.cpp | 20 +
.../files/patch-src_slic3r_Utils_WxFontUtils.cpp | 45 +
.../files/patch-tests_fff__print_test__data.cpp | 21 +-
.../files/patch-tests_libslic3r_test__emboss.cpp | 11 +
58 files changed, 5705 insertions(+), 117 deletions(-)
diff --git a/cad/PrusaSlicer/Makefile b/cad/PrusaSlicer/Makefile
index c01ff53595eb..03f557a5919c 100644
--- a/cad/PrusaSlicer/Makefile
+++ b/cad/PrusaSlicer/Makefile
@@ -1,8 +1,9 @@
PORTNAME= PrusaSlicer
DISTVERSIONPREFIX=version_
-DISTVERSION= 2.5.1
-PORTREVISION= 7
+DISTVERSION= 2.6.0
+PORTREVISION= 1
CATEGORIES= cad
+DIST_SUBDIR= PrusaSlicer
MAINTAINER= teodorsigaev@gmail.com
COMMENT= Slicing application for 3D printers
@@ -14,12 +15,15 @@ LICENSE_FILE= ${WRKSRC}/LICENSE
BUILD_DEPENDS= cereal>=1.3.0.10:devel/cereal \
cgal>=5.0.2:math/cgal \
opencascade>=7.7.0:cad/opencascade
+
LIB_DEPENDS= libtbb.so:devel/onetbb \
libboost_log.so:devel/boost-libs \
libImath.so:math/Imath \
libnlopt.so:math/nlopt \
+ libqhull_r.so:math/qhull \
libcurl.so:ftp/curl \
libexpat.so:textproc/expat2 \
+ libiconv.so:converters/libiconv \
libopenvdb.so:misc/openvdb \
libgmp.so:math/gmp \
libmpfr.so:math/mpfr \
@@ -31,7 +35,8 @@ LIB_DEPENDS= libtbb.so:devel/onetbb \
libfreeimage.so:graphics/freeimage \
libfreetype.so:print/freetype2 \
libavcodec.so:multimedia/ffmpeg \
- libharfbuzz.so:print/harfbuzz
+ libharfbuzz.so:print/harfbuzz \
+ libwayland-egl.so:graphics/wayland
USES= cmake cpe desktop-file-utils eigen:3 gettext gl pkgconfig jpeg iconv gnome xorg
CPE_VENDOR= prusa3d
@@ -44,7 +49,8 @@ USE_XORG= x11
CMAKE_ARGS+= -DwxWidgets_CONFIG_EXECUTABLE="${WX_CONFIG}" \
-DSLIC3R_GTK=3 \
- -DSLIC3R_FHS=1
+ -DSLIC3R_FHS=1 \
+ -DSLIC3R_PCH=OFF
PORTDATA= *
diff --git a/cad/PrusaSlicer/distinfo b/cad/PrusaSlicer/distinfo
index 893c37013372..209b6b9fb7c8 100644
--- a/cad/PrusaSlicer/distinfo
+++ b/cad/PrusaSlicer/distinfo
@@ -1,3 +1,3 @@
-TIMESTAMP = 1679421999
-SHA256 (prusa3d-PrusaSlicer-version_2.5.1_GH0.tar.gz) = 4fa14a4604ccf8042c3cbefe4c0a481d293e075030920799fe3f5e6247ef93ca
-SIZE (prusa3d-PrusaSlicer-version_2.5.1_GH0.tar.gz) = 48888707
+TIMESTAMP = 1690319127
+SHA256 (PrusaSlicer/prusa3d-PrusaSlicer-version_2.6.0_GH0.tar.gz) = a15f68e3b18a047c8c9a18a9d91629d2c777be1932087684cf6d2332d0888e77
+SIZE (PrusaSlicer/prusa3d-PrusaSlicer-version_2.6.0_GH0.tar.gz) = 56430180
diff --git a/cad/PrusaSlicer/files/patch-CMakeLists.txt b/cad/PrusaSlicer/files/patch-CMakeLists.txt
index ef5fab78c7e5..73daa6aa4e9b 100644
--- a/cad/PrusaSlicer/files/patch-CMakeLists.txt
+++ b/cad/PrusaSlicer/files/patch-CMakeLists.txt
@@ -1,6 +1,6 @@
---- CMakeLists.txt.orig 2022-09-06 07:09:19 UTC
+--- CMakeLists.txt.orig 2023-06-19 12:07:14 UTC
+++ CMakeLists.txt
-@@ -4,6 +4,7 @@ project(PrusaSlicer)
+@@ -4,6 +4,7 @@ include(CMakeDependentOption)
include("version.inc")
include(GNUInstallDirs)
include(CMakeDependentOption)
@@ -8,7 +8,7 @@
set(SLIC3R_RESOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/resources")
file(TO_NATIVE_PATH "${SLIC3R_RESOURCES_DIR}" SLIC3R_RESOURCES_DIR_WIN)
-@@ -197,7 +198,7 @@ if (APPLE)
+@@ -207,7 +208,7 @@ endif ()
endif ()
endif ()
@@ -17,7 +17,16 @@
find_package(PkgConfig REQUIRED)
if (CMAKE_VERSION VERSION_LESS "3.1")
-@@ -597,8 +598,8 @@ elseif (SLIC3R_FHS)
+@@ -446,7 +447,7 @@ find_package(EXPAT REQUIRED)
+ # no matter what.
+ find_package(EXPAT REQUIRED)
+
+-add_library(libexpat INTERFACE)
++# add_library(libexpat INTERFACE)
+
+ if (TARGET EXPAT::EXPAT )
+ target_link_libraries(libexpat INTERFACE EXPAT::EXPAT)
+@@ -627,8 +628,8 @@ elseif (SLIC3R_FHS)
install(DIRECTORY ${SLIC3R_RESOURCES_DIR}/ DESTINATION ${SLIC3R_FHS_RESOURCES}
PATTERN "*/udev" EXCLUDE
)
@@ -28,7 +37,7 @@
foreach(SIZE 32 128 192)
install(FILES ${SLIC3R_RESOURCES_DIR}/icons/PrusaSlicer_${SIZE}px.png
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}x${SIZE}/apps RENAME PrusaSlicer.png
-@@ -607,7 +608,8 @@ elseif (SLIC3R_FHS)
+@@ -637,7 +638,8 @@ elseif (SLIC3R_FHS)
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}x${SIZE}/apps RENAME PrusaSlicer-gcodeviewer.png
)
endforeach()
diff --git a/cad/PrusaSlicer/files/patch-src_CMakeLists.txt b/cad/PrusaSlicer/files/patch-src_CMakeLists.txt
index 5072871d7f95..e084cdc3c97c 100644
--- a/cad/PrusaSlicer/files/patch-src_CMakeLists.txt
+++ b/cad/PrusaSlicer/files/patch-src_CMakeLists.txt
@@ -1,10 +1,19 @@
---- src/CMakeLists.txt.orig 2022-09-06 07:09:19 UTC
+--- src/CMakeLists.txt.orig 2023-06-19 12:07:14 UTC
+++ src/CMakeLists.txt
-@@ -127,7 +127,7 @@ if (NOT WIN32 AND NOT APPLE)
+@@ -78,7 +78,7 @@ if (SLIC3R_GUI)
+
+ find_package(JPEG QUIET)
+ find_package(TIFF QUIET)
+- find_package(NanoSVG REQUIRED)
++ # find_package(NanoSVG REQUIRED)
+
+ string(REGEX MATCH "wxpng" WX_PNG_BUILTIN ${wxWidgets_LIBRARIES})
+ if (PNG_FOUND AND NOT WX_PNG_BUILTIN)
+@@ -147,7 +147,7 @@ endif ()
set_target_properties(PrusaSlicer PROPERTIES OUTPUT_NAME "prusa-slicer")
endif ()
--target_link_libraries(PrusaSlicer libslic3r cereal)
+-target_link_libraries(PrusaSlicer libslic3r libcereal)
+target_link_libraries(PrusaSlicer libslic3r)
if (APPLE)
diff --git a/cad/PrusaSlicer/files/patch-src_avrdude_arduino.c b/cad/PrusaSlicer/files/patch-src_avrdude_arduino.c
new file mode 100644
index 000000000000..c7c282d53832
--- /dev/null
+++ b/cad/PrusaSlicer/files/patch-src_avrdude_arduino.c
@@ -0,0 +1,10 @@
+--- src/avrdude/arduino.c.orig 2023-07-25 13:23:52 UTC
++++ src/avrdude/arduino.c
+@@ -28,6 +28,7 @@
+ #include "ac_cfg.h"
+
+ #include <stdio.h>
++#include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+
diff --git a/cad/PrusaSlicer/files/patch-src_libnanosvg_nanosvg.h b/cad/PrusaSlicer/files/patch-src_libnanosvg_nanosvg.h
new file mode 100644
index 000000000000..08bf0beb1ef1
--- /dev/null
+++ b/cad/PrusaSlicer/files/patch-src_libnanosvg_nanosvg.h
@@ -0,0 +1,3109 @@
+--- src/libnanosvg/nanosvg.h.orig 1970-01-01 01:00:00.000000000 +0100
++++ src/libnanosvg/nanosvg.h 2022-12-22 00:42:08.000000000 +0100
+@@ -0,0 +1,3106 @@
++/*
++ * Copyright (c) 2013-14 Mikko Mononen memon@inside.org
++ *
++ * This software is provided 'as-is', without any express or implied
++ * warranty. In no event will the authors be held liable for any damages
++ * arising from the use of this software.
++ *
++ * Permission is granted to anyone to use this software for any purpose,
++ * including commercial applications, and to alter it and redistribute it
++ * freely, subject to the following restrictions:
++ *
++ * 1. The origin of this software must not be misrepresented; you must not
++ * claim that you wrote the original software. If you use this software
++ * in a product, an acknowledgment in the product documentation would be
++ * appreciated but is not required.
++ * 2. Altered source versions must be plainly marked as such, and must not be
++ * misrepresented as being the original software.
++ * 3. This notice may not be removed or altered from any source distribution.
++ *
++ * The SVG parser is based on Anti-Grain Geometry 2.4 SVG example
++ * Copyright (C) 2002-2004 Maxim Shemanarev (McSeem) (http://www.antigrain.com/)
++ *
++ * Arc calculation code based on canvg (https://code.google.com/p/canvg/)
++ *
++ * Bounding box calculation based on http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
++ *
++ */
++
++#ifndef NANOSVG_H
++#define NANOSVG_H
++
++#ifndef NANOSVG_CPLUSPLUS
++#ifdef __cplusplus
++extern "C" {
++#endif
++#endif
++
++// NanoSVG is a simple stupid single-header-file SVG parse. The output of the parser is a list of cubic bezier shapes.
++//
++// The library suits well for anything from rendering scalable icons in your editor application to prototyping a game.
++//
++// NanoSVG supports a wide range of SVG features, but something may be missing, feel free to create a pull request!
++//
++// The shapes in the SVG images are transformed by the viewBox and converted to specified units.
++// That is, you should get the same looking data as your designed in your favorite app.
++//
++// NanoSVG can return the paths in few different units. For example if you want to render an image, you may choose
++// to get the paths in pixels, or if you are feeding the data into a CNC-cutter, you may want to use millimeters.
++//
++// The units passed to NanoSVG should be one of: 'px', 'pt', 'pc' 'mm', 'cm', or 'in'.
++// DPI (dots-per-inch) controls how the unit conversion is done.
++//
++// If you don't know or care about the units stuff, "px" and 96 should get you going.
++
++
++/* Example Usage:
++ // Load SVG
++ NSVGimage* image;
++ image = nsvgParseFromFile("test.svg", "px", 96);
++ printf("size: %f x %f\n", image->width, image->height);
++ // Use...
++ for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) {
++ for (NSVGpath *path = shape->paths; path != NULL; path = path->next) {
++ for (int i = 0; i < path->npts-1; i += 3) {
++ float* p = &path->pts[i*2];
++ drawCubicBez(p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7]);
++ }
++ }
++ }
++ // Delete
++ nsvgDelete(image);
++*/
++
++enum NSVGpaintType {
++ NSVG_PAINT_UNDEF = -1,
++ NSVG_PAINT_NONE = 0,
++ NSVG_PAINT_COLOR = 1,
++ NSVG_PAINT_LINEAR_GRADIENT = 2,
++ NSVG_PAINT_RADIAL_GRADIENT = 3
++};
++
++enum NSVGspreadType {
++ NSVG_SPREAD_PAD = 0,
++ NSVG_SPREAD_REFLECT = 1,
++ NSVG_SPREAD_REPEAT = 2
++};
++
++enum NSVGlineJoin {
++ NSVG_JOIN_MITER = 0,
++ NSVG_JOIN_ROUND = 1,
++ NSVG_JOIN_BEVEL = 2
++};
++
++enum NSVGlineCap {
++ NSVG_CAP_BUTT = 0,
++ NSVG_CAP_ROUND = 1,
++ NSVG_CAP_SQUARE = 2
++};
++
++enum NSVGfillRule {
++ NSVG_FILLRULE_NONZERO = 0,
++ NSVG_FILLRULE_EVENODD = 1
++};
++
++enum NSVGflags {
++ NSVG_FLAGS_VISIBLE = 0x01
++};
++
++typedef struct NSVGgradientStop {
++ unsigned int color;
++ float offset;
++} NSVGgradientStop;
++
++typedef struct NSVGgradient {
++ float xform[6];
++ char spread;
++ float fx, fy;
++ int nstops;
++ NSVGgradientStop stops[1];
++} NSVGgradient;
++
++typedef struct NSVGpaint {
++ signed char type;
++ union {
++ unsigned int color;
++ NSVGgradient* gradient;
++ };
++} NSVGpaint;
++
++typedef struct NSVGpath
++{
++ float* pts; // Cubic bezier points: x0,y0, [cpx1,cpx1,cpx2,cpy2,x1,y1], ...
++ int npts; // Total number of bezier points.
++ char closed; // Flag indicating if shapes should be treated as closed.
++ float bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy].
++ struct NSVGpath* next; // Pointer to next path, or NULL if last element.
++} NSVGpath;
++
++typedef struct NSVGshape
++{
++ char id[64]; // Optional 'id' attr of the shape or its group
++ NSVGpaint fill; // Fill paint
++ NSVGpaint stroke; // Stroke paint
++ float opacity; // Opacity of the shape.
++ float strokeWidth; // Stroke width (scaled).
++ float strokeDashOffset; // Stroke dash offset (scaled).
++ float strokeDashArray[8]; // Stroke dash array (scaled).
++ char strokeDashCount; // Number of dash values in dash array.
++ char strokeLineJoin; // Stroke join type.
++ char strokeLineCap; // Stroke cap type.
++ float miterLimit; // Miter limit
++ char fillRule; // Fill rule, see NSVGfillRule.
++ unsigned char flags; // Logical or of NSVG_FLAGS_* flags
++ float bounds[4]; // Tight bounding box of the shape [minx,miny,maxx,maxy].
++ char fillGradient[64]; // Optional 'id' of fill gradient
++ char strokeGradient[64]; // Optional 'id' of stroke gradient
++ float xform[6]; // Root transformation for fill/stroke gradient
++ NSVGpath* paths; // Linked list of paths in the image.
++ struct NSVGshape* next; // Pointer to next shape, or NULL if last element.
++} NSVGshape;
++
++typedef struct NSVGimage
++{
++ float width; // Width of the image.
++ float height; // Height of the image.
++ NSVGshape* shapes; // Linked list of shapes in the image.
++} NSVGimage;
++
++// Parses SVG file from a file, returns SVG image as paths.
++NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi);
++
++// Parses SVG file from a null terminated string, returns SVG image as paths.
++// Important note: changes the string.
++NSVGimage* nsvgParse(char* input, const char* units, float dpi);
++
++// Duplicates a path.
++NSVGpath* nsvgDuplicatePath(NSVGpath* p);
++
++// Deletes an image.
++void nsvgDelete(NSVGimage* image);
++
++#ifndef NANOSVG_CPLUSPLUS
++#ifdef __cplusplus
++}
++#endif
++#endif
++
++#ifdef NANOSVG_IMPLEMENTATION
++
++#include <string.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <math.h>
++
++#define NSVG_PI (3.14159265358979323846264338327f)
++#define NSVG_KAPPA90 (0.5522847493f) // Length proportional to radius of a cubic bezier handle for 90deg arcs.
++
++#define NSVG_ALIGN_MIN 0
++#define NSVG_ALIGN_MID 1
++#define NSVG_ALIGN_MAX 2
++#define NSVG_ALIGN_NONE 0
++#define NSVG_ALIGN_MEET 1
++#define NSVG_ALIGN_SLICE 2
++
++#define NSVG_NOTUSED(v) do { (void)(1 ? (void)0 : ( (void)(v) ) ); } while(0)
++#define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16))
++
++#ifdef _MSC_VER
++ #pragma warning (disable: 4996) // Switch off security warnings
++ #pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings
++ #ifdef __cplusplus
++ #define NSVG_INLINE inline
++ #else
++ #define NSVG_INLINE
++ #endif
++#else
++ #define NSVG_INLINE inline
++#endif
++
++
++static int nsvg__isspace(char c)
++{
++ return strchr(" \t\n\v\f\r", c) != 0;
++}
++
++static int nsvg__isdigit(char c)
++{
++ return c >= '0' && c <= '9';
++}
++
++static NSVG_INLINE float nsvg__minf(float a, float b) { return a < b ? a : b; }
++static NSVG_INLINE float nsvg__maxf(float a, float b) { return a > b ? a : b; }
++
++
++// Simple XML parser
++
++#define NSVG_XML_TAG 1
++#define NSVG_XML_CONTENT 2
++#define NSVG_XML_MAX_ATTRIBS 256
++
++static void nsvg__parseContent(char* s,
++ void (*contentCb)(void* ud, const char* s),
++ void* ud)
++{
++ // Trim start white spaces
++ while (*s && nsvg__isspace(*s)) s++;
++ if (!*s) return;
++
++ if (contentCb)
++ (*contentCb)(ud, s);
++}
++
++static void nsvg__parseElement(char* s,
++ void (*startelCb)(void* ud, const char* el, const char** attr),
++ void (*endelCb)(void* ud, const char* el),
++ void* ud)
++{
++ const char* attr[NSVG_XML_MAX_ATTRIBS];
++ int nattr = 0;
++ char* name;
++ int start = 0;
++ int end = 0;
++ char quote;
++
++ // Skip white space after the '<'
++ while (*s && nsvg__isspace(*s)) s++;
++
++ // Check if the tag is end tag
++ if (*s == '/') {
++ s++;
++ end = 1;
++ } else {
++ start = 1;
++ }
++
++ // Skip comments, data and preprocessor stuff.
++ if (!*s || *s == '?' || *s == '!')
++ return;
++
++ // Get tag name
++ name = s;
++ while (*s && !nsvg__isspace(*s)) s++;
++ if (*s) { *s++ = '\0'; }
++
++ // Get attribs
++ while (!end && *s && nattr < NSVG_XML_MAX_ATTRIBS-3) {
++ char* name = NULL;
++ char* value = NULL;
++
++ // Skip white space before the attrib name
++ while (*s && nsvg__isspace(*s)) s++;
++ if (!*s) break;
++ if (*s == '/') {
++ end = 1;
++ break;
++ }
++ name = s;
++ // Find end of the attrib name.
++ while (*s && !nsvg__isspace(*s) && *s != '=') s++;
++ if (*s) { *s++ = '\0'; }
++ // Skip until the beginning of the value.
++ while (*s && *s != '\"' && *s != '\'') s++;
++ if (!*s) break;
++ quote = *s;
++ s++;
++ // Store value and find the end of it.
++ value = s;
++ while (*s && *s != quote) s++;
++ if (*s) { *s++ = '\0'; }
++
++ // Store only well formed attributes
++ if (name && value) {
++ attr[nattr++] = name;
++ attr[nattr++] = value;
++ }
++ }
++
++ // List terminator
++ attr[nattr++] = 0;
++ attr[nattr++] = 0;
++
++ // Call callbacks.
++ if (start && startelCb)
++ (*startelCb)(ud, name, attr);
++ if (end && endelCb)
++ (*endelCb)(ud, name);
++}
++
++int nsvg__parseXML(char* input,
++ void (*startelCb)(void* ud, const char* el, const char** attr),
++ void (*endelCb)(void* ud, const char* el),
++ void (*contentCb)(void* ud, const char* s),
++ void* ud)
++{
++ char* s = input;
++ char* mark = s;
++ int state = NSVG_XML_CONTENT;
++ while (*s) {
++ if (*s == '<' && state == NSVG_XML_CONTENT) {
++ // Start of a tag
++ *s++ = '\0';
++ nsvg__parseContent(mark, contentCb, ud);
++ mark = s;
++ state = NSVG_XML_TAG;
++ } else if (*s == '>' && state == NSVG_XML_TAG) {
++ // Start of a content or new tag.
++ *s++ = '\0';
++ nsvg__parseElement(mark, startelCb, endelCb, ud);
++ mark = s;
++ state = NSVG_XML_CONTENT;
++ } else {
++ s++;
++ }
++ }
++
++ return 1;
++}
++
++
++/* Simple SVG parser. */
++
++#define NSVG_MAX_ATTR 128
++
++enum NSVGgradientUnits {
++ NSVG_USER_SPACE = 0,
++ NSVG_OBJECT_SPACE = 1
++};
++
++#define NSVG_MAX_DASHES 8
++
++enum NSVGunits {
++ NSVG_UNITS_USER,
++ NSVG_UNITS_PX,
++ NSVG_UNITS_PT,
++ NSVG_UNITS_PC,
++ NSVG_UNITS_MM,
++ NSVG_UNITS_CM,
++ NSVG_UNITS_IN,
++ NSVG_UNITS_PERCENT,
++ NSVG_UNITS_EM,
++ NSVG_UNITS_EX
++};
++
++typedef struct NSVGcoordinate {
++ float value;
++ int units;
++} NSVGcoordinate;
++
++typedef struct NSVGlinearData {
++ NSVGcoordinate x1, y1, x2, y2;
++} NSVGlinearData;
++
++typedef struct NSVGradialData {
++ NSVGcoordinate cx, cy, r, fx, fy;
++} NSVGradialData;
++
++typedef struct NSVGgradientData
++{
++ char id[64];
++ char ref[64];
++ signed char type;
++ union {
++ NSVGlinearData linear;
++ NSVGradialData radial;
++ };
++ char spread;
++ char units;
++ float xform[6];
++ int nstops;
++ NSVGgradientStop* stops;
++ struct NSVGgradientData* next;
++} NSVGgradientData;
++
++typedef struct NSVGattrib
++{
++ char id[64];
++ float xform[6];
++ unsigned int fillColor;
++ unsigned int strokeColor;
++ float opacity;
++ float fillOpacity;
++ float strokeOpacity;
++ char fillGradient[64];
++ char strokeGradient[64];
++ float strokeWidth;
++ float strokeDashOffset;
++ float strokeDashArray[NSVG_MAX_DASHES];
++ int strokeDashCount;
++ char strokeLineJoin;
++ char strokeLineCap;
++ float miterLimit;
++ char fillRule;
++ float fontSize;
++ unsigned int stopColor;
++ float stopOpacity;
++ float stopOffset;
++ char hasFill;
++ char hasStroke;
++ char visible;
++} NSVGattrib;
++
++typedef struct NSVGparser
++{
++ NSVGattrib attr[NSVG_MAX_ATTR];
++ int attrHead;
++ float* pts;
++ int npts;
++ int cpts;
++ NSVGpath* plist;
++ NSVGimage* image;
++ NSVGgradientData* gradients;
++ NSVGshape* shapesTail;
++ float viewMinx, viewMiny, viewWidth, viewHeight;
++ int alignX, alignY, alignType;
++ float dpi;
++ char pathFlag;
++ char defsFlag;
++} NSVGparser;
++
++static void nsvg__xformIdentity(float* t)
++{
++ t[0] = 1.0f; t[1] = 0.0f;
++ t[2] = 0.0f; t[3] = 1.0f;
++ t[4] = 0.0f; t[5] = 0.0f;
++}
++
++static void nsvg__xformSetTranslation(float* t, float tx, float ty)
++{
++ t[0] = 1.0f; t[1] = 0.0f;
++ t[2] = 0.0f; t[3] = 1.0f;
++ t[4] = tx; t[5] = ty;
++}
++
++static void nsvg__xformSetScale(float* t, float sx, float sy)
++{
++ t[0] = sx; t[1] = 0.0f;
++ t[2] = 0.0f; t[3] = sy;
++ t[4] = 0.0f; t[5] = 0.0f;
++}
++
++static void nsvg__xformSetSkewX(float* t, float a)
++{
++ t[0] = 1.0f; t[1] = 0.0f;
++ t[2] = tanf(a); t[3] = 1.0f;
++ t[4] = 0.0f; t[5] = 0.0f;
++}
++
++static void nsvg__xformSetSkewY(float* t, float a)
++{
++ t[0] = 1.0f; t[1] = tanf(a);
++ t[2] = 0.0f; t[3] = 1.0f;
++ t[4] = 0.0f; t[5] = 0.0f;
++}
++
++static void nsvg__xformSetRotation(float* t, float a)
++{
++ float cs = cosf(a), sn = sinf(a);
++ t[0] = cs; t[1] = sn;
++ t[2] = -sn; t[3] = cs;
++ t[4] = 0.0f; t[5] = 0.0f;
++}
++
++static void nsvg__xformMultiply(float* t, float* s)
++{
++ float t0 = t[0] * s[0] + t[1] * s[2];
++ float t2 = t[2] * s[0] + t[3] * s[2];
++ float t4 = t[4] * s[0] + t[5] * s[2] + s[4];
++ t[1] = t[0] * s[1] + t[1] * s[3];
++ t[3] = t[2] * s[1] + t[3] * s[3];
++ t[5] = t[4] * s[1] + t[5] * s[3] + s[5];
++ t[0] = t0;
++ t[2] = t2;
++ t[4] = t4;
++}
++
++static void nsvg__xformInverse(float* inv, float* t)
++{
++ double invdet, det = (double)t[0] * t[3] - (double)t[2] * t[1];
++ if (det > -1e-6 && det < 1e-6) {
++ nsvg__xformIdentity(t);
++ return;
++ }
++ invdet = 1.0 / det;
++ inv[0] = (float)(t[3] * invdet);
++ inv[2] = (float)(-t[2] * invdet);
++ inv[4] = (float)(((double)t[2] * t[5] - (double)t[3] * t[4]) * invdet);
++ inv[1] = (float)(-t[1] * invdet);
++ inv[3] = (float)(t[0] * invdet);
++ inv[5] = (float)(((double)t[1] * t[4] - (double)t[0] * t[5]) * invdet);
++}
++
++static void nsvg__xformPremultiply(float* t, float* s)
++{
++ float s2[6];
++ memcpy(s2, s, sizeof(float)*6);
++ nsvg__xformMultiply(s2, t);
++ memcpy(t, s2, sizeof(float)*6);
++}
++
++static void nsvg__xformPoint(float* dx, float* dy, float x, float y, float* t)
++{
++ *dx = x*t[0] + y*t[2] + t[4];
++ *dy = x*t[1] + y*t[3] + t[5];
++}
++
++static void nsvg__xformVec(float* dx, float* dy, float x, float y, float* t)
++{
++ *dx = x*t[0] + y*t[2];
++ *dy = x*t[1] + y*t[3];
++}
++
++#define NSVG_EPSILON (1e-12)
++
++static int nsvg__ptInBounds(float* pt, float* bounds)
++{
++ return pt[0] >= bounds[0] && pt[0] <= bounds[2] && pt[1] >= bounds[1] && pt[1] <= bounds[3];
++}
++
++
++static double nsvg__evalBezier(double t, double p0, double p1, double p2, double p3)
++{
++ double it = 1.0-t;
++ return it*it*it*p0 + 3.0*it*it*t*p1 + 3.0*it*t*t*p2 + t*t*t*p3;
++}
++
++static void nsvg__curveBounds(float* bounds, float* curve)
++{
++ int i, j, count;
++ double roots[2], a, b, c, b2ac, t, v;
++ float* v0 = &curve[0];
++ float* v1 = &curve[2];
++ float* v2 = &curve[4];
++ float* v3 = &curve[6];
++
++ // Start the bounding box by end points
++ bounds[0] = nsvg__minf(v0[0], v3[0]);
++ bounds[1] = nsvg__minf(v0[1], v3[1]);
++ bounds[2] = nsvg__maxf(v0[0], v3[0]);
++ bounds[3] = nsvg__maxf(v0[1], v3[1]);
++
++ // Bezier curve fits inside the convex hull of it's control points.
++ // If control points are inside the bounds, we're done.
++ if (nsvg__ptInBounds(v1, bounds) && nsvg__ptInBounds(v2, bounds))
++ return;
++
++ // Add bezier curve inflection points in X and Y.
++ for (i = 0; i < 2; i++) {
++ a = -3.0 * v0[i] + 9.0 * v1[i] - 9.0 * v2[i] + 3.0 * v3[i];
++ b = 6.0 * v0[i] - 12.0 * v1[i] + 6.0 * v2[i];
++ c = 3.0 * v1[i] - 3.0 * v0[i];
++ count = 0;
++ if (fabs(a) < NSVG_EPSILON) {
++ if (fabs(b) > NSVG_EPSILON) {
++ t = -c / b;
++ if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON)
++ roots[count++] = t;
++ }
++ } else {
++ b2ac = b*b - 4.0*c*a;
++ if (b2ac > NSVG_EPSILON) {
++ t = (-b + sqrt(b2ac)) / (2.0 * a);
++ if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON)
++ roots[count++] = t;
++ t = (-b - sqrt(b2ac)) / (2.0 * a);
++ if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON)
++ roots[count++] = t;
++ }
++ }
++ for (j = 0; j < count; j++) {
++ v = nsvg__evalBezier(roots[j], v0[i], v1[i], v2[i], v3[i]);
++ bounds[0+i] = nsvg__minf(bounds[0+i], (float)v);
++ bounds[2+i] = nsvg__maxf(bounds[2+i], (float)v);
++ }
++ }
++}
++
++static NSVGparser* nsvg__createParser(void)
++{
++ NSVGparser* p;
++ p = (NSVGparser*)malloc(sizeof(NSVGparser));
++ if (p == NULL) goto error;
++ memset(p, 0, sizeof(NSVGparser));
++
++ p->image = (NSVGimage*)malloc(sizeof(NSVGimage));
++ if (p->image == NULL) goto error;
++ memset(p->image, 0, sizeof(NSVGimage));
++
++ // Init style
++ nsvg__xformIdentity(p->attr[0].xform);
++ memset(p->attr[0].id, 0, sizeof p->attr[0].id);
++ p->attr[0].fillColor = NSVG_RGB(0,0,0);
++ p->attr[0].strokeColor = NSVG_RGB(0,0,0);
++ p->attr[0].opacity = 1;
++ p->attr[0].fillOpacity = 1;
++ p->attr[0].strokeOpacity = 1;
++ p->attr[0].stopOpacity = 1;
++ p->attr[0].strokeWidth = 1;
++ p->attr[0].strokeLineJoin = NSVG_JOIN_MITER;
++ p->attr[0].strokeLineCap = NSVG_CAP_BUTT;
++ p->attr[0].miterLimit = 4;
++ p->attr[0].fillRule = NSVG_FILLRULE_NONZERO;
++ p->attr[0].hasFill = 1;
++ p->attr[0].visible = 1;
++
++ return p;
++
++error:
++ if (p) {
++ if (p->image) free(p->image);
++ free(p);
++ }
++ return NULL;
++}
++
++static void nsvg__deletePaths(NSVGpath* path)
++{
++ while (path) {
++ NSVGpath *next = path->next;
++ if (path->pts != NULL)
++ free(path->pts);
++ free(path);
++ path = next;
++ }
++}
++
++static void nsvg__deletePaint(NSVGpaint* paint)
++{
++ if (paint->type == NSVG_PAINT_LINEAR_GRADIENT || paint->type == NSVG_PAINT_RADIAL_GRADIENT)
++ free(paint->gradient);
++}
++
++static void nsvg__deleteGradientData(NSVGgradientData* grad)
++{
++ NSVGgradientData* next;
++ while (grad != NULL) {
++ next = grad->next;
++ free(grad->stops);
++ free(grad);
++ grad = next;
++ }
++}
++
++static void nsvg__deleteParser(NSVGparser* p)
++{
++ if (p != NULL) {
++ nsvg__deletePaths(p->plist);
++ nsvg__deleteGradientData(p->gradients);
++ nsvgDelete(p->image);
++ free(p->pts);
++ free(p);
++ }
++}
++
++static void nsvg__resetPath(NSVGparser* p)
++{
++ p->npts = 0;
++}
++
++static void nsvg__addPoint(NSVGparser* p, float x, float y)
++{
++ if (p->npts+1 > p->cpts) {
++ p->cpts = p->cpts ? p->cpts*2 : 8;
++ p->pts = (float*)realloc(p->pts, p->cpts*2*sizeof(float));
++ if (!p->pts) return;
++ }
++ p->pts[p->npts*2+0] = x;
++ p->pts[p->npts*2+1] = y;
++ p->npts++;
++}
++
++static void nsvg__moveTo(NSVGparser* p, float x, float y)
++{
++ if (p->npts > 0) {
++ p->pts[(p->npts-1)*2+0] = x;
++ p->pts[(p->npts-1)*2+1] = y;
++ } else {
++ nsvg__addPoint(p, x, y);
++ }
++}
++
++static void nsvg__lineTo(NSVGparser* p, float x, float y)
++{
++ float px,py, dx,dy;
++ if (p->npts > 0) {
++ px = p->pts[(p->npts-1)*2+0];
++ py = p->pts[(p->npts-1)*2+1];
++ dx = x - px;
++ dy = y - py;
++ nsvg__addPoint(p, px + dx/3.0f, py + dy/3.0f);
++ nsvg__addPoint(p, x - dx/3.0f, y - dy/3.0f);
++ nsvg__addPoint(p, x, y);
++ }
++}
++
++static void nsvg__cubicBezTo(NSVGparser* p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y)
++{
++ if (p->npts > 0) {
++ nsvg__addPoint(p, cpx1, cpy1);
++ nsvg__addPoint(p, cpx2, cpy2);
++ nsvg__addPoint(p, x, y);
++ }
++}
++
++static NSVGattrib* nsvg__getAttr(NSVGparser* p)
++{
++ return &p->attr[p->attrHead];
++}
*** 5361 LINES SKIPPED ***