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 ***