Hello community, here is the log from the commit of package wxsvg for openSUSE:Factory checked in at 2019-09-16 10:53:19 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/wxsvg (Old) and /work/SRC/openSUSE:Factory/.wxsvg.new.7948 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "wxsvg" Mon Sep 16 10:53:19 2019 rev:5 rq:731056 version:1.5.20 Changes: -------- --- /work/SRC/openSUSE:Factory/wxsvg/wxsvg.changes 2019-02-27 17:28:13.683340593 +0100 +++ /work/SRC/openSUSE:Factory/.wxsvg.new.7948/wxsvg.changes 2019-09-16 10:53:21.503149260 +0200 @@ -1,0 +2,21 @@ +Sat Sep 14 12:50:32 UTC 2019 - Mariusz Fik <fi...@opensuse.org> + +- Update to 1.5.20: + * added handling of fill-rule + * added handling of spreadMethod + * added handling of clipPath + * added support of dash-offset + * added support of mask for path element + * fixed handling of pt units + * fixed fill pattern with opacity + * fixed handling of referenced patterns +- Update to 1.5.19: + * fixed rendering polyline element + * fixed drawing a cubic Bézier curve if the previous command was not + an c or s +- Update to 1.5.18: + * wxFfmpegMediaDecoder: fixed support of ffmpeg 3.4.x +- Update to 1.5.17: + * wxSVGUseElement: fixed GetBBox() and GetResultBBox() + +------------------------------------------------------------------- Old: ---- wxsvg-1.5.16.tar.bz2 New: ---- wxsvg-1.5.20.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ wxsvg.spec ++++++ --- /var/tmp/diff_new_pack.mXkLFA/_old 2019-09-16 10:53:21.983149197 +0200 +++ /var/tmp/diff_new_pack.mXkLFA/_new 2019-09-16 10:53:21.987149197 +0200 @@ -2,7 +2,7 @@ # spec file for package wxsvg # # Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. -# Copyright (c) 2012-2015 Mariusz Fik <fi...@opensuse.org> +# Copyright (c) 2012-2019 Mariusz Fik <fi...@opensuse.org> # Copyright (c) 2012 Stefan Seyfried <seife+...@b1-systems.com> # # All modifications and additions to the file contributed by third parties @@ -20,7 +20,7 @@ %define sover 3 Name: wxsvg -Version: 1.5.16 +Version: 1.5.20 Release: 0 Summary: Library to create, manipulate and render SVG files License: GPL-2.0-or-later ++++++ wxsvg-1.5.16.tar.bz2 -> wxsvg-1.5.20.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wxsvg-1.5.16/ChangeLog new/wxsvg-1.5.20/ChangeLog --- old/wxsvg-1.5.16/ChangeLog 2019-01-27 20:26:55.000000000 +0100 +++ new/wxsvg-1.5.20/ChangeLog 2019-08-02 23:01:01.000000000 +0200 @@ -1,3 +1,31 @@ +Version 1.5.20 <2019-08-02> +--------------------------- + + * added handling of fill-rule + * added handling of spreadMethod + * added handling of clipPath + * added support of dash-offset + * added support of mask for path element + * fixed handling of pt units + * fixed fill pattern with opacity + * fixed handling of referenced patterns + +Version 1.5.19 <2019-06-24> +--------------------------- + + * fixed rendering polyline element + * fixed drawing a cubic Bézier curve if the previous command was not an c or s + +Version 1.5.18 <2019-05-19> +--------------------------- + + * wxFfmpegMediaDecoder: fixed support of ffmpeg 3.4.x + +Version 1.5.17 <2019-05-19> +--------------------------- + + * wxSVGUseElement: fixed GetBBox() and GetResultBBox() + Version 1.5.16 <2019-01-27> --------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wxsvg-1.5.16/configure new/wxsvg-1.5.20/configure --- old/wxsvg-1.5.16/configure 2019-01-27 20:26:59.000000000 +0100 +++ new/wxsvg-1.5.20/configure 2019-08-02 23:01:05.000000000 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for wxsvg 1.5.16. +# Generated by GNU Autoconf 2.69 for wxsvg 1.5.20. # # Report bugs to <http://wxsvg.sourceforge.net/>. # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='wxsvg' PACKAGE_TARNAME='wxsvg' -PACKAGE_VERSION='1.5.16' -PACKAGE_STRING='wxsvg 1.5.16' +PACKAGE_VERSION='1.5.20' +PACKAGE_STRING='wxsvg 1.5.20' PACKAGE_BUGREPORT='http://wxsvg.sourceforge.net/' PACKAGE_URL='' @@ -1394,7 +1394,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures wxsvg 1.5.16 to adapt to many kinds of systems. +\`configure' configures wxsvg 1.5.20 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1465,7 +1465,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of wxsvg 1.5.16:";; + short | recursive ) echo "Configuration of wxsvg 1.5.20:";; esac cat <<\_ACEOF @@ -1612,7 +1612,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -wxsvg configure 1.5.16 +wxsvg configure 1.5.20 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2133,7 +2133,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by wxsvg $as_me 1.5.16, which was +It was created by wxsvg $as_me 1.5.20, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2997,7 +2997,7 @@ # Define the identity of the package. PACKAGE='wxsvg' - VERSION='1.5.16' + VERSION='1.5.20' cat >>confdefs.h <<_ACEOF @@ -3122,7 +3122,7 @@ # 4. If any interfaces have been added since the last public release, then increment age. # 5. If any interfaces have been removed since the last public release then set age to 0. -LIBRARY_VERSION=15:0:12 # current:revision:age -> libwxsvg.so.(C-A).(A).(R) +LIBRARY_VERSION=15:4:12 # current:revision:age -> libwxsvg.so.(C-A).(A).(R) # options @@ -17775,7 +17775,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by wxsvg $as_me 1.5.16, which was +This file was extended by wxsvg $as_me 1.5.20, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -17832,7 +17832,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -wxsvg config.status 1.5.16 +wxsvg config.status 1.5.20 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wxsvg-1.5.16/configure.ac new/wxsvg-1.5.20/configure.ac --- old/wxsvg-1.5.16/configure.ac 2019-01-27 20:26:55.000000000 +0100 +++ new/wxsvg-1.5.20/configure.ac 2019-08-02 23:01:01.000000000 +0200 @@ -2,7 +2,7 @@ # initialization AC_PREREQ(2.59) -AC_INIT([wxsvg], [1.5.16], [http://wxsvg.sourceforge.net/]) +AC_INIT([wxsvg], [1.5.20], [http://wxsvg.sourceforge.net/]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE(foreign) AM_MAINTAINER_MODE @@ -15,7 +15,7 @@ # 4. If any interfaces have been added since the last public release, then increment age. # 5. If any interfaces have been removed since the last public release then set age to 0. -LIBRARY_VERSION=15:0:12 # current:revision:age -> libwxsvg.so.(C-A).(A).(R) +LIBRARY_VERSION=15:4:12 # current:revision:age -> libwxsvg.so.(C-A).(A).(R) AC_SUBST(LIBRARY_VERSION) # options diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wxsvg-1.5.16/include/wxSVG/SVGCanvas.h new/wxsvg-1.5.20/include/wxSVG/SVGCanvas.h --- old/wxsvg-1.5.16/include/wxSVG/SVGCanvas.h 2019-01-27 20:26:55.000000000 +0100 +++ new/wxsvg-1.5.20/include/wxSVG/SVGCanvas.h 2019-08-02 23:01:01.000000000 +0200 @@ -70,7 +70,7 @@ virtual void DrawCanvasText(wxSVGCanvasText& canvasText, wxSVGMatrix& matrix, const wxCSSStyleDeclaration& style, wxSVGSVGElement& svgElem); - wxSVGPatternElement* GetPatternElement(const wxSVGSVGElement& svgElem, const wxString& href); + wxSVGPatternElement* GetPatternElement(const wxSVGSVGElement& svgElem, wxString href); wxSVGMarkerElement* GetMarkerElement(const wxSVGSVGElement& svgElem, const wxString& href); wxSVGGradientElement* GetGradientElement(const wxSVGSVGElement& svgElem, const wxString& href); unsigned int GetGradientStops(const wxSVGSVGElement& svgElem, wxSVGGradientElement* gradElem, float opacity); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wxsvg-1.5.16/libwxsvg.pc.in new/wxsvg-1.5.20/libwxsvg.pc.in --- old/wxsvg-1.5.16/libwxsvg.pc.in 2019-01-27 20:26:55.000000000 +0100 +++ new/wxsvg-1.5.20/libwxsvg.pc.in 2019-08-02 23:01:01.000000000 +0200 @@ -4,8 +4,9 @@ includedir=@includedir@ Name: libwxsvg -Description: C++ library to create, manipulate and render SVG files +Description: C++ library to create, manipulate and render SVG files Requires: +Requires.private: pango, libexif Version: @VERSION@ Libs: -L${libdir} -lwxsvg Cflags: -I${includedir} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wxsvg-1.5.16/src/CSSValue.cpp new/wxsvg-1.5.20/src/CSSValue.cpp --- old/wxsvg-1.5.16/src/CSSValue.cpp 2019-01-27 20:26:55.000000000 +0100 +++ new/wxsvg-1.5.20/src/CSSValue.cpp 2019-08-02 23:01:01.000000000 +0200 @@ -111,85 +111,70 @@ return wxT(""); } -void wxCSSPrimitiveValue::SetFloatValue(wxCSS_PRIMITIVE_TYPE unitType, double doubleValue) -{ - CleanUp(); - m_primitiveType = - int(unitType) >= int(wxCSS_NUMBER) && - int(unitType) <= int(wxCSS_DIMENSION) ? unitType : wxCSS_NUMBER; - m_number = doubleValue; -} - -double wxCSSPrimitiveValue::GetFloatValue(wxCSS_PRIMITIVE_TYPE unitType) const -{ - if (int(m_primitiveType) >= int(wxCSS_NUMBER) && - int(m_primitiveType) <= int(wxCSS_DIMENSION)) - return m_number; - return 0; -} - -void wxCSSPrimitiveValue::SetRectValue(const wxRect& rect) -{ - if (m_primitiveType != wxCSS_RECT) - { +void wxCSSPrimitiveValue::SetFloatValue(wxCSS_PRIMITIVE_TYPE unitType, double doubleValue) { CleanUp(); - m_rect = new wxRect; - } - m_primitiveType = wxCSS_RECT; - *m_rect = rect; -} - -wxRect wxCSSPrimitiveValue::GetRectValue() const -{ - if (m_primitiveType == wxCSS_RECT) - return *m_rect; - return wxRect(); -} - -void wxCSSPrimitiveValue::SetRGBColorValue(const wxRGBColor& color) -{ - if (m_primitiveType != wxCSS_RGBCOLOR) - { - CleanUp(); - m_color = new wxRGBColor; - } - m_primitiveType = wxCSS_RGBCOLOR; - *m_color = color; -} - -wxRGBColor wxCSSPrimitiveValue::GetRGBColorValue() const -{ - if (m_primitiveType == wxCSS_RGBCOLOR) - return *m_color; - return wxRGBColor(); -} - -void wxCSSPrimitiveValue::SetIdentValue(wxCSS_VALUE ident) -{ - if (m_primitiveType != wxCSS_IDENT) - CleanUp(); - m_primitiveType = wxCSS_IDENT; - m_ident = ident; + m_primitiveType = + int(unitType) >= int(wxCSS_NUMBER) && int(unitType) <= int(wxCSS_DIMENSION) ? unitType : wxCSS_NUMBER; + m_number = doubleValue; +} + +double wxCSSPrimitiveValue::GetFloatValue(wxCSS_PRIMITIVE_TYPE unitType) const { + if (int(m_primitiveType) >= int(wxCSS_NUMBER) && int(m_primitiveType) <= int(wxCSS_DIMENSION)) + return m_number; + return 0; +} + +void wxCSSPrimitiveValue::SetRectValue(const wxRect& rect) { + if (m_primitiveType != wxCSS_RECT) { + CleanUp(); + m_rect = new wxRect; + } + m_primitiveType = wxCSS_RECT; + *m_rect = rect; +} + +wxRect wxCSSPrimitiveValue::GetRectValue() const { + if (m_primitiveType == wxCSS_RECT) + return *m_rect; + return wxRect(); +} + +void wxCSSPrimitiveValue::SetRGBColorValue(const wxRGBColor& color) { + if (m_primitiveType != wxCSS_RGBCOLOR) { + CleanUp(); + m_color = new wxRGBColor; + } + m_primitiveType = wxCSS_RGBCOLOR; + *m_color = color; +} + +wxRGBColor wxCSSPrimitiveValue::GetRGBColorValue() const { + if (m_primitiveType == wxCSS_RGBCOLOR) + return *m_color; + return wxRGBColor(); +} + +void wxCSSPrimitiveValue::SetIdentValue(wxCSS_VALUE ident) { + if (m_primitiveType != wxCSS_IDENT) + CleanUp(); + m_primitiveType = wxCSS_IDENT; + m_ident = ident; +} + +wxCSS_VALUE wxCSSPrimitiveValue::GetIdentValue() const { + if (m_primitiveType == wxCSS_IDENT) + return m_ident; + return wxCSS_VALUE_UNKNOWN; } -wxCSS_VALUE wxCSSPrimitiveValue::GetIdentValue() const -{ - if (m_primitiveType == wxCSS_IDENT) - return m_ident; - return wxCSS_VALUE_UNKNOWN; -} - -void wxCSSPrimitiveValue::CleanUp() -{ - if (m_primitiveType == wxCSS_STRING || - m_primitiveType == wxCSS_URI || - m_primitiveType == wxCSS_ATTR) - delete m_string; - else if (m_primitiveType == wxCSS_RECT) - delete m_rect; - else if (m_primitiveType == wxCSS_RGBCOLOR) - delete m_color; - m_primitiveType = wxCSS_UNKNOWN; +void wxCSSPrimitiveValue::CleanUp() { + if (m_primitiveType == wxCSS_STRING || m_primitiveType == wxCSS_URI || m_primitiveType == wxCSS_ATTR) + delete m_string; + else if (m_primitiveType == wxCSS_RECT) + delete m_rect; + else if (m_primitiveType == wxCSS_RGBCOLOR) + delete m_color; + m_primitiveType = wxCSS_UNKNOWN; } ////////////////////////////////////////////////////////////////////////////// diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wxsvg-1.5.16/src/SVGCanvas.cpp new/wxsvg-1.5.20/src/SVGCanvas.cpp --- old/wxsvg-1.5.16/src/SVGCanvas.cpp 2019-01-27 20:26:55.000000000 +0100 +++ new/wxsvg-1.5.20/src/SVGCanvas.cpp 2019-08-02 23:01:01.000000000 +0200 @@ -126,11 +126,19 @@ } } -wxSVGPatternElement* wxSVGCanvas::GetPatternElement(const wxSVGSVGElement& svgElem, const wxString& href) { - if (href.length() == 0 || href[0] != wxT('#') || &svgElem == NULL) - return NULL; - wxSVGElement* elem = (wxSVGElement*) svgElem.GetElementById(href.substr(1)); - return elem != NULL && elem->GetDtd() == wxSVG_PATTERN_ELEMENT ? (wxSVGPatternElement*) elem : NULL; +wxSVGPatternElement* wxSVGCanvas::GetPatternElement(const wxSVGSVGElement& svgElem, wxString href) { + // Search for the most referenced pattern + wxSVGPatternElement* pElem = NULL; + while (true) { + if (href.length() == 0 || href[0] != wxT('#') || &svgElem == NULL) + break; + wxSVGElement* elem = (wxSVGElement*) svgElem.GetElementById(href.substr(1)); + if (elem == NULL || elem->GetDtd() != wxSVG_PATTERN_ELEMENT) + break; + pElem = (wxSVGPatternElement*) elem; + href = pElem->GetHref(); + } + return pElem; } wxSVGMarkerElement* wxSVGCanvas::GetMarkerElement(const wxSVGSVGElement& svgElem, const wxString& href) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wxsvg-1.5.16/src/SVGCanvasItem.cpp new/wxsvg-1.5.20/src/SVGCanvasItem.cpp --- old/wxsvg-1.5.16/src/SVGCanvasItem.cpp 2019-01-27 20:26:55.000000000 +0100 +++ new/wxsvg-1.5.20/src/SVGCanvasItem.cpp 2019-08-02 23:01:01.000000000 +0200 @@ -47,7 +47,6 @@ void wxSVGCanvasPath::Init(wxSVGPolylineElement& element) { m_element = &element; - SetFill(false); const wxSVGPointList& points = element.GetPoints(); if (points.Count()) @@ -285,236 +284,216 @@ ///////////////////////// Path functions ///////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -void wxSVGCanvasPath::MoveTo(double x, double y, bool relative) -{ - if (relative) - { - x += m_curx; - y += m_cury; - } - MoveToImpl(x, y); - m_begx = m_curx = x; - m_begy = m_cury = y; -} - -void wxSVGCanvasPath::LineTo(double x, double y, bool relative) -{ - if (relative) - { - x += m_curx; - y += m_cury; - } - LineToImpl(x, y); - m_curx = x; - m_cury = y; -} - -void wxSVGCanvasPath::LineToHorizontal(double x, bool relative) -{ - if (relative) - x += m_curx; - LineToImpl(x, m_cury); - m_curx = x; -} - -void wxSVGCanvasPath::LineToVertical(double y, bool relative) -{ - if (relative) - y += m_cury; - LineToImpl(m_curx, y); - m_cury = y; -} - -void wxSVGCanvasPath::CurveToCubic(double x1, double y1, double x2, double y2, double x, double y, bool relative) -{ - if (relative) - { - x1 += m_curx; - y1 += m_cury; - x2 += m_curx; - y2 += m_cury; - x += m_curx; - y += m_cury; - } - CurveToCubicImpl(x1, y1, x2, y2, x, y); - m_curx = x; - m_cury = y; - m_cubicx = 2*m_curx - x2; - m_cubicy = 2*m_cury - y2; -} - -void wxSVGCanvasPath::CurveToCubicSmooth(double x2, double y2, double x, double y, bool relative) -{ - if (relative) - { - x2 += m_curx; - y2 += m_cury; - x += m_curx; - y += m_cury; - } - CurveToCubicImpl(m_cubicx, m_cubicy, x2, y2, x, y); - m_curx = x; - m_cury = y; - m_cubicx = 2*m_curx - x2; - m_cubicy = 2*m_cury - y2; -} - -void wxSVGCanvasPath::CurveToQuadratic(double x1, double y1, double x, double y, bool relative) -{ - if (relative) - { - x1 += m_curx; - y1 += m_cury; - x += m_curx; - y += m_cury; - } - m_quadx = 2*x - x1; - m_quady = 2*y - y1; - double x2 = (x + 2*x1)/3; - double y2 = (y + 2*y1)/3; - x1 = (m_curx + 2*x1)/3; - y1 = (m_cury + 2*y1)/3; - CurveToCubicImpl(x1, y1, x2, y2, x, y); - m_curx = x; - m_cury = y; -} - -void wxSVGCanvasPath::CurveToQuadraticSmooth(double x, double y, bool relative) -{ - if (relative) - { - x += m_curx; - y += m_cury; - } - double x1 = (m_curx + 2*m_quadx)/3; - double y1 = (m_cury + 2*m_quady)/3; - double x2 = (x + 2*m_quadx)/3; - double y2 = (y + 2*m_quady)/3; - CurveToCubicImpl(x1, y1, x2, y2, x, y); - m_curx = x; - m_cury = y; - m_quadx = 2*x - m_quadx; - m_quady = 2*y - m_quady; +void wxSVGCanvasPath::MoveTo(double x, double y, bool relative) { + if (relative) { + x += m_curx; + y += m_cury; + } + MoveToImpl(x, y); + m_begx = m_curx = m_cubicx = m_quadx = x; + m_begy = m_cury = m_cubicy = m_quady = y; +} + +void wxSVGCanvasPath::LineTo(double x, double y, bool relative) { + if (relative) { + x += m_curx; + y += m_cury; + } + LineToImpl(x, y); + m_curx = m_cubicx = m_quadx = x; + m_cury = m_cubicy = m_quady = y; +} + +void wxSVGCanvasPath::LineToHorizontal(double x, bool relative) { + if (relative) + x += m_curx; + LineToImpl(x, m_cury); + m_curx = m_cubicx = m_quadx = x; +} + +void wxSVGCanvasPath::LineToVertical(double y, bool relative) { + if (relative) + y += m_cury; + LineToImpl(m_curx, y); + m_cury = m_cubicy = m_quady = y; +} + +void wxSVGCanvasPath::CurveToCubic(double x1, double y1, double x2, double y2, double x, double y, bool relative) { + if (relative) { + x1 += m_curx; + y1 += m_cury; + x2 += m_curx; + y2 += m_cury; + x += m_curx; + y += m_cury; + } + CurveToCubicImpl(x1, y1, x2, y2, x, y); + m_curx = m_quadx = x; + m_cury = m_quady = y; + m_cubicx = 2 * m_curx - x2; + m_cubicy = 2 * m_cury - y2; +} + +void wxSVGCanvasPath::CurveToCubicSmooth(double x2, double y2, double x, double y, bool relative) { + if (relative) { + x2 += m_curx; + y2 += m_cury; + x += m_curx; + y += m_cury; + } + CurveToCubicImpl(m_cubicx, m_cubicy, x2, y2, x, y); + m_curx = m_quadx = x; + m_cury = m_quady = y; + m_cubicx = 2 * m_curx - x2; + m_cubicy = 2 * m_cury - y2; +} + +void wxSVGCanvasPath::CurveToQuadratic(double x1, double y1, double x, double y, bool relative) { + if (relative) { + x1 += m_curx; + y1 += m_cury; + x += m_curx; + y += m_cury; + } + m_quadx = 2 * x - x1; + m_quady = 2 * y - y1; + double x2 = (x + 2 * x1) / 3; + double y2 = (y + 2 * y1) / 3; + x1 = (m_curx + 2 * x1) / 3; + y1 = (m_cury + 2 * y1) / 3; + CurveToCubicImpl(x1, y1, x2, y2, x, y); + m_curx = m_cubicx = x; + m_cury = m_cubicy = y; +} + +void wxSVGCanvasPath::CurveToQuadraticSmooth(double x, double y, bool relative) { + if (relative) { + x += m_curx; + y += m_cury; + } + double x1 = (m_curx + 2 * m_quadx) / 3; + double y1 = (m_cury + 2 * m_quady) / 3; + double x2 = (x + 2 * m_quadx) / 3; + double y2 = (y + 2 * m_quady) / 3; + CurveToCubicImpl(x1, y1, x2, y2, x, y); + m_curx = m_cubicx = x; + m_cury = m_cubicy = y; + m_quadx = 2 * x - m_quadx; + m_quady = 2 * y - m_quady; } // This works by converting the SVG arc to "simple" beziers. // For each bezier found a svgToCurve call is done. // Adapted from Niko's code in kdelibs/kdecore/svgicons. -void wxSVGCanvasPath::Arc(double x, double y, double r1, double r2, - double angle, bool largeArcFlag, bool sweepFlag, - bool relative) -{ - if (relative) - { - x += m_curx; - y += m_cury; - } - - double sin_th = sin(angle*(M_PI/180.0)); - double cos_th = cos(angle*(M_PI/180.0)); - - double dx = (m_curx - x)/2.0; - double dy = (m_cury - y)/2.0; - - double _x1 = cos_th*dx + sin_th*dy; - double _y1 = -sin_th*dx + cos_th*dy; - double Pr1 = r1*r1; - double Pr2 = r2*r2; - double Px = _x1*_x1; - double Py = _y1*_y1; - - // Spec : check if radii are large enough - double check = Px/Pr1 + Py/Pr2; - if (check > 1) - { - r1 = r1*sqrt(check); - r2 = r2*sqrt(check); - } - - double a00 = cos_th/r1; - double a01 = sin_th/r1; - double a10 = -sin_th/r2; - double a11 = cos_th/r2; +void wxSVGCanvasPath::Arc(double x, double y, double r1, double r2, double angle, bool largeArcFlag, bool sweepFlag, + bool relative) { + if (relative) { + x += m_curx; + y += m_cury; + } + + double sin_th = sin(angle * (M_PI / 180.0)); + double cos_th = cos(angle * (M_PI / 180.0)); + + double dx = (m_curx - x) / 2.0; + double dy = (m_cury - y) / 2.0; + + double _x1 = cos_th * dx + sin_th * dy; + double _y1 = -sin_th * dx + cos_th * dy; + double Pr1 = r1 * r1; + double Pr2 = r2 * r2; + double Px = _x1 * _x1; + double Py = _y1 * _y1; + + // Spec : check if radii are large enough + double check = Px / Pr1 + Py / Pr2; + if (check > 1) { + r1 = r1 * sqrt(check); + r2 = r2 * sqrt(check); + } + + double a00 = cos_th / r1; + double a01 = sin_th / r1; + double a10 = -sin_th / r2; + double a11 = cos_th / r2; - double x0 = a00*m_curx + a01*m_cury; - double y0 = a10*m_curx + a11*m_cury; + double x0 = a00 * m_curx + a01 * m_cury; + double y0 = a10 * m_curx + a11 * m_cury; - double x1 = a00*x + a01*y; - double y1 = a10*x + a11*y; + double x1 = a00 * x + a01 * y; + double y1 = a10 * x + a11 * y; - /* (x0, y0) is current point in transformed coordinate space. + /* (x0, y0) is current point in transformed coordinate space. (x1, y1) is new point in transformed coordinate space. The arc fits a unit-radius circle in this space. */ - double d = (x1 - x0)*(x1 - x0) + (y1 - y0)*(y1 - y0); + double d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0); + + double sfactor_sq = 1.0 / d - 0.25; - double sfactor_sq = 1.0/d - 0.25; + if (sfactor_sq < 0) + sfactor_sq = 0; - if (sfactor_sq < 0) - sfactor_sq = 0; + double sfactor = sqrt(sfactor_sq); - double sfactor = sqrt(sfactor_sq); + if (sweepFlag == largeArcFlag) + sfactor = -sfactor; + + double xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0); + double yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0); + + /* (xc, yc) is center of the circle. */ + double th0 = atan2(y0 - yc, x0 - xc); + double th1 = atan2(y1 - yc, x1 - xc); + + double th_arc = th1 - th0; + if (th_arc < 0 && sweepFlag) + th_arc += 2 * M_PI; + else if (th_arc > 0 && !sweepFlag) + th_arc -= 2 * M_PI; + + int n_segs = (int) (int) ceil(fabs(th_arc / (M_PI * 0.5 + 0.001))); + + for (int i = 0; i < n_segs; i++) { + double sin_th, cos_th; + double a00, a01, a10, a11; + double x1, y1, x2, y2, x3, y3; + double t; + double th_half; + + double _th0 = th0 + i * th_arc / n_segs; + double _th1 = th0 + (i + 1) * th_arc / n_segs; + + sin_th = sin(angle * (M_PI / 180.0)); + cos_th = cos(angle * (M_PI / 180.0)); + + /* inverse transform compared with rsvg_path_arc */ + a00 = cos_th * r1; + a01 = -sin_th * r2; + a10 = sin_th * r1; + a11 = cos_th * r2; + + th_half = 0.5 * (_th1 - _th0); + t = (8.0 / 3.0) * sin(th_half * 0.5) * sin(th_half * 0.5) / sin(th_half); + x1 = xc + cos(_th0) - t * sin(_th0); + y1 = yc + sin(_th0) + t * cos(_th0); + x3 = xc + cos(_th1); + y3 = yc + sin(_th1); + x2 = x3 + t * sin(_th1); + y2 = y3 - t * cos(_th1); + + CurveToCubicImpl(a00 * x1 + a01 * y1, a10 * x1 + a11 * y1, a00 * x2 + a01 * y2, a10 * x2 + a11 * y2, + a00 * x3 + a01 * y3, a10 * x3 + a11 * y3); + } + m_curx = m_cubicx = m_quadx = x; + m_cury = m_cubicy = m_quady = y; +} - if (sweepFlag == largeArcFlag) - sfactor = -sfactor; - - double xc = 0.5*(x0 + x1) - sfactor*(y1 - y0); - double yc = 0.5*(y0 + y1) + sfactor*(x1 - x0); - - /* (xc, yc) is center of the circle. */ - double th0 = atan2(y0 - yc, x0 - xc); - double th1 = atan2(y1 - yc, x1 - xc); - - double th_arc = th1 - th0; - if (th_arc < 0 && sweepFlag) - th_arc += 2*M_PI; - else if (th_arc > 0 && !sweepFlag) - th_arc -= 2*M_PI; - - int n_segs = (int) (int) ceil(fabs(th_arc/(M_PI*0.5 + 0.001))); - - for (int i = 0; i < n_segs; i++) - { - double sin_th, cos_th; - double a00, a01, a10, a11; - double x1, y1, x2, y2, x3, y3; - double t; - double th_half; - - double _th0 = th0 + i*th_arc/n_segs; - double _th1 = th0 + (i + 1)*th_arc/n_segs; - - sin_th = sin(angle*(M_PI/180.0)); - cos_th = cos(angle*(M_PI/180.0)); - - /* inverse transform compared with rsvg_path_arc */ - a00 = cos_th*r1; - a01 = -sin_th*r2; - a10 = sin_th*r1; - a11 = cos_th*r2; - - th_half = 0.5*(_th1 - _th0); - t = (8.0/3.0)*sin(th_half*0.5)*sin(th_half*0.5)/sin(th_half); - x1 = xc + cos(_th0) - t*sin(_th0); - y1 = yc + sin(_th0) + t*cos(_th0); - x3 = xc + cos(_th1); - y3 = yc + sin(_th1); - x2 = x3 + t*sin(_th1); - y2 = y3 - t*cos(_th1); - - CurveToCubicImpl(a00*x1 + a01*y1, a10*x1 + a11*y1, a00*x2 + a01*y2, - a10*x2 + a11*y2, a00*x3 + a01*y3, a10*x3 + a11*y3); - } - m_curx = x; - m_cury = y; -} - -bool wxSVGCanvasPath::ClosePath() -{ - bool isClosed = ClosePathImpl(); - m_curx = m_begx; - m_cury = m_begy; - return isClosed; +bool wxSVGCanvasPath::ClosePath() { + bool isClosed = ClosePathImpl(); + m_curx = m_begx; + m_cury = m_begy; + return isClosed; } double AngleOfVector(const wxSVGPoint& vec) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wxsvg-1.5.16/src/SVGLength.cpp new/wxsvg-1.5.20/src/SVGLength.cpp --- old/wxsvg-1.5.16/src/SVGLength.cpp 2019-01-27 20:26:55.000000000 +0100 +++ new/wxsvg-1.5.20/src/SVGLength.cpp 2019-08-02 23:01:01.000000000 +0200 @@ -10,11 +10,9 @@ #include "SVGLength.h" -wxString wxSVGLength::GetValueAsString() const -{ +wxString wxSVGLength::GetValueAsString() const { wxString value = wxString::Format(wxT("%g"), m_valueInSpecifiedUnits); - switch (m_unitType) - { + switch (m_unitType) { case wxSVG_LENGTHTYPE_UNKNOWN: break; case wxSVG_LENGTHTYPE_NUMBER: break; case wxSVG_LENGTHTYPE_PX: value += wxT("px"); break; @@ -30,85 +28,76 @@ return value; } -void wxSVGLength::SetValueAsString(const wxString& n) -{ - m_valueInSpecifiedUnits = 0; - m_unitType = wxSVG_LENGTHTYPE_NUMBER; - wxString value = n.Strip(wxString::both); - wxString unit; - if (value.length()>=2) - { - const wxString s_numeric = wxT("0123456789"); - const wxString s_numericFirst = wxT("+-.Ee") + s_numeric; - if (!s_numeric.Contains(value.Right(1))) - { - if (s_numericFirst.Contains(value.Mid(value.Length()-2,1))) - { - unit = value.Right(1); - value = value.Left(value.Length()-1); - } - else - { - unit = value.Right(2); - value = value.Left(value.Length()-2); - } +void wxSVGLength::SetValueAsString(const wxString& n) { + m_valueInSpecifiedUnits = 0; + m_unitType = wxSVG_LENGTHTYPE_NUMBER; + wxString value = n.Strip(wxString::both); + wxString unit; + if (value.length() >= 2) { + const wxString s_numeric = wxT("0123456789"); + const wxString s_numericFirst = wxT("+-.Ee") + s_numeric; + if (!s_numeric.Contains(value.Right(1))) { + if (s_numericFirst.Contains(value.Mid(value.Length() - 2, 1))) { + unit = value.Right(1); + value = value.Left(value.Length() - 1); + } else { + unit = value.Right(2); + value = value.Left(value.Length() - 2); + } + } } - } - - double d; - if (!value.ToDouble(&d)) - return; - m_valueInSpecifiedUnits = d; - - if (unit.length() == 0); - else if (unit == wxT("px")) - m_unitType = wxSVG_LENGTHTYPE_PX; - else if (unit.Right(1) == wxT("%")) - m_unitType = wxSVG_LENGTHTYPE_PERCENTAGE; - else if (unit == wxT("em")) - m_unitType = wxSVG_LENGTHTYPE_EMS; - else if (unit == wxT("ex")) - m_unitType = wxSVG_LENGTHTYPE_EXS; - else if (unit == wxT("cm")) - m_unitType = wxSVG_LENGTHTYPE_CM; - else if (unit == wxT("mm")) - m_unitType = wxSVG_LENGTHTYPE_MM; - else if (unit == wxT("in")) - m_unitType = wxSVG_LENGTHTYPE_IN; - else if (unit == wxT("pt")) - m_unitType = wxSVG_LENGTHTYPE_PT; - else if (unit == wxT("pc")) - m_unitType = wxSVG_LENGTHTYPE_PC; - SetValueInSpecifiedUnits(m_valueInSpecifiedUnits); + + double d; + if (!value.ToDouble(&d)) + return; + m_valueInSpecifiedUnits = d; + + if (unit.length() > 0) { + if (unit == wxT("px")) + m_unitType = wxSVG_LENGTHTYPE_PX; + else if (unit.Right(1) == wxT("%")) + m_unitType = wxSVG_LENGTHTYPE_PERCENTAGE; + else if (unit == wxT("em")) + m_unitType = wxSVG_LENGTHTYPE_EMS; + else if (unit == wxT("ex")) + m_unitType = wxSVG_LENGTHTYPE_EXS; + else if (unit == wxT("cm")) + m_unitType = wxSVG_LENGTHTYPE_CM; + else if (unit == wxT("mm")) + m_unitType = wxSVG_LENGTHTYPE_MM; + else if (unit == wxT("in")) + m_unitType = wxSVG_LENGTHTYPE_IN; + else if (unit == wxT("pt")) + m_unitType = wxSVG_LENGTHTYPE_PT; + else if (unit == wxT("pc")) + m_unitType = wxSVG_LENGTHTYPE_PC; + } + SetValueInSpecifiedUnits(m_valueInSpecifiedUnits); } -void wxSVGLength::NewValueSpecifiedUnits(wxSVG_LENGTHTYPE unitType, double valueInSpecifiedUnits) -{ - m_unitType = unitType; - SetValueInSpecifiedUnits(valueInSpecifiedUnits); +void wxSVGLength::NewValueSpecifiedUnits(wxSVG_LENGTHTYPE unitType, double valueInSpecifiedUnits) { + m_unitType = unitType; + SetValueInSpecifiedUnits(valueInSpecifiedUnits); } -void wxSVGLength::ConvertToSpecifiedUnits(wxSVG_LENGTHTYPE unitType) -{ - m_unitType = unitType; +void wxSVGLength::ConvertToSpecifiedUnits(wxSVG_LENGTHTYPE unitType) { + m_unitType = unitType; } -void wxSVGLength::SetValueInSpecifiedUnits(double n) -{ - m_valueInSpecifiedUnits = n; - m_value = n; - switch (m_unitType) - { - case wxSVG_LENGTHTYPE_UNKNOWN: break; - case wxSVG_LENGTHTYPE_NUMBER: break; - case wxSVG_LENGTHTYPE_PX: break; - case wxSVG_LENGTHTYPE_PERCENTAGE: break; // todo - case wxSVG_LENGTHTYPE_EMS: break; // todo - case wxSVG_LENGTHTYPE_EXS: break; // todo - case wxSVG_LENGTHTYPE_CM: m_value *= 35.43307; break; - case wxSVG_LENGTHTYPE_MM: m_value *= 3.543307; break; - case wxSVG_LENGTHTYPE_IN: m_value *= 90; break; - case wxSVG_LENGTHTYPE_PT: m_value *= 1.25; break; - case wxSVG_LENGTHTYPE_PC: m_value *= 15; break; - } +void wxSVGLength::SetValueInSpecifiedUnits(double n) { + m_valueInSpecifiedUnits = n; + m_value = n; + switch (m_unitType) { + case wxSVG_LENGTHTYPE_UNKNOWN: break; + case wxSVG_LENGTHTYPE_NUMBER: break; + case wxSVG_LENGTHTYPE_PX: break; + case wxSVG_LENGTHTYPE_PERCENTAGE: break; // todo + case wxSVG_LENGTHTYPE_EMS: break; // todo + case wxSVG_LENGTHTYPE_EXS: break; // todo + case wxSVG_LENGTHTYPE_CM: m_value *= 35.43307; break; + case wxSVG_LENGTHTYPE_MM: m_value *= 3.543307; break; + case wxSVG_LENGTHTYPE_IN: m_value *= 90; break; + case wxSVG_LENGTHTYPE_PT: m_value = m_value * 96 / 72; break; + case wxSVG_LENGTHTYPE_PC: m_value *= 15; break; + } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wxsvg-1.5.16/src/SVGTransformList.cpp new/wxsvg-1.5.20/src/SVGTransformList.cpp --- old/wxsvg-1.5.16/src/SVGTransformList.cpp 2019-01-27 20:26:55.000000000 +0100 +++ new/wxsvg-1.5.20/src/SVGTransformList.cpp 2019-08-02 23:01:01.000000000 +0200 @@ -12,26 +12,25 @@ WX_DEFINE_OBJARRAY(wxSVGTransformListBase); wxString wxSVGTransformList::GetValueAsString() const { - wxString value; - for (int i = 0; i < (int)GetCount(); i++) { - if (i > 0) - value += wxT(" "); - value += Item(i).GetValueAsString(); - } - return value; + wxString value; + for (int i = 0; i < (int) GetCount(); i++) { + if (i > 0) + value += wxT(" "); + value += Item(i).GetValueAsString(); + } + return value; } void wxSVGTransformList::SetValueAsString(const wxString& value) { - Clear(); - wxStringTokenizer tkz(value, wxT(" \t")); - while (tkz.HasMoreTokens()) - { - wxString token = tkz.GetNextToken(); - if (token.length() == 0) - continue; - wxSVGTransform transform; - transform.SetValueAsString(token); - if (transform.GetType() != wxSVG_TRANSFORM_UNKNOWN) - Add(transform); - } + Clear(); + wxStringTokenizer tkz(value, wxT(")")); + while (tkz.HasMoreTokens()) { + wxString token = tkz.GetNextToken().Strip(wxString::both); + if (token.length() == 0) + continue; + wxSVGTransform transform; + transform.SetValueAsString(token + ")"); + if (transform.GetType() != wxSVG_TRANSFORM_UNKNOWN) + Add(transform); + } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wxsvg-1.5.16/src/SVGUseElement.cpp new/wxsvg-1.5.20/src/SVGUseElement.cpp --- old/wxsvg-1.5.16/src/SVGUseElement.cpp 2019-01-27 20:26:55.000000000 +0100 +++ new/wxsvg-1.5.20/src/SVGUseElement.cpp 2019-08-02 23:01:01.000000000 +0200 @@ -11,13 +11,31 @@ #include "SVGUseElement.h" wxSVGRect wxSVGUseElement::GetBBox(wxSVG_COORDINATES coordinates) { - wxSVGRect bbox = wxSVGRect(GetX().GetAnimVal(), GetY().GetAnimVal(), GetWidth().GetAnimVal(), - GetHeight().GetAnimVal()); + wxSVGRect bbox; + wxString href = GetHref(); + if (href.length() == 0 || href.GetChar(0) != wxT('#')) + return bbox; + href.Remove(0, 1); + wxSVGElement* refElem = (wxSVGElement*) GetOwnerSVGElement()->GetElementById(href); + if (!refElem) + return bbox; + bbox = wxSVGLocatable::GetChildrenBBox(refElem, coordinates); if (coordinates != wxSVG_COORDINATES_USER) bbox = bbox.MatrixTransform(GetMatrix(coordinates)); return bbox; } wxSVGRect wxSVGUseElement::GetResultBBox(wxSVG_COORDINATES coordinates) { - return GetBBox(coordinates); + wxSVGRect bbox; + wxString href = GetHref(); + if (href.length() == 0 || href.GetChar(0) != wxT('#')) + return bbox; + href.Remove(0, 1); + wxSVGElement* refElem = (wxSVGElement*) GetOwnerSVGElement()->GetElementById(href); + if (!refElem) + return bbox; + bbox = wxSVGLocatable::GetChildrenResultBBox(refElem, coordinates); + if (coordinates != wxSVG_COORDINATES_USER) + bbox = bbox.MatrixTransform(GetMatrix(coordinates)); + return bbox; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wxsvg-1.5.16/src/cairo/SVGCanvasCairo.cpp new/wxsvg-1.5.20/src/cairo/SVGCanvasCairo.cpp --- old/wxsvg-1.5.16/src/cairo/SVGCanvasCairo.cpp 2019-01-27 20:26:55.000000000 +0100 +++ new/wxsvg-1.5.20/src/cairo/SVGCanvasCairo.cpp 2019-08-02 23:01:01.000000000 +0200 @@ -187,6 +187,10 @@ int nstops = GetGradientStops(svgElem, gradElem, opacity); if (nstops) { cairo_set_source(cr, m_pattern); + if (gradElem->GetSpreadMethod() == wxSVG_SPREADMETHOD_REFLECT) + cairo_pattern_set_extend(m_pattern, CAIRO_EXTEND_REFLECT); + else if (gradElem->GetSpreadMethod() == wxSVG_SPREADMETHOD_REPEAT) + cairo_pattern_set_extend(m_pattern, CAIRO_EXTEND_REPEAT); } else { cairo_pattern_destroy(m_pattern); m_pattern = NULL; @@ -209,30 +213,34 @@ cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, lround(patternElem->GetWidth().GetAnimVal()*scaleX), lround(patternElem->GetHeight().GetAnimVal()*scaleY)); - cairo_t* cr = cairo_create(surface); + cairo_t* ptCr = cairo_create(surface); wxSVGMatrix patMatrix; patMatrix = patMatrix.ScaleNonUniform(scaleX, scaleY); - wxCSSStyleDeclaration style; - DrawMask(cr, patternElem, patMatrix, style, svgElem); + wxCSSStyleDeclaration patStyle; + patStyle.SetOpacity(opacity); + + cairo_t* tmp = m_cr; + m_cr = ptCr; + RenderChilds(patternElem, NULL, &patMatrix, &patStyle, &svgElem, &svgElem, NULL); + m_cr = tmp; + m_pattern = cairo_pattern_create_for_surface(surface); if (patternElem->GetX().GetAnimVal() > 0 || patternElem->GetY().GetAnimVal() > 0) { patMatrix = patMatrix.Translate(patternElem->GetX().GetAnimVal(), patternElem->GetY().GetAnimVal()); } - if (patternElem->GetPatternTransform().GetAnimVal().size()) { - const wxSVGTransformList& transforms = patternElem->GetPatternTransform().GetAnimVal(); - for (unsigned int i = 0; i < transforms.Count(); i++) { - patMatrix = patMatrix.Multiply(transforms[i].GetMatrix().Inverse()); - } + wxSVGPatternElement* topPattern = (wxSVGPatternElement*) svgElem.GetElementById(paint.GetUri().substr(1)); + for (int i = topPattern->GetPatternTransform().GetAnimVal().Count()-1; i >= 0 ; i--) { + patMatrix = patMatrix.Multiply(topPattern->GetPatternTransform().GetAnimVal()[i].GetMatrix().Inverse()); } cairo_matrix_t mat; cairo_matrix_init(&mat, patMatrix.GetA(), patMatrix.GetB(), patMatrix.GetC(), patMatrix.GetD(), patMatrix.GetE(), patMatrix.GetF()); cairo_pattern_set_matrix(m_pattern, &mat); - cairo_set_source(m_cr, m_pattern); + cairo_set_source(cr, m_pattern); cairo_pattern_set_extend(m_pattern, CAIRO_EXTEND_REPEAT); - cairo_destroy(cr); + cairo_destroy(ptCr); cairo_surface_destroy(surface); } } else { @@ -408,6 +416,7 @@ cairo_path_t* path = canvasPath.GetPath(); cairo_append_path(cr, path); SetPaint(cr, style.GetFill(), style.GetOpacity()*style.GetFillOpacity(), canvasPath, svgElem, matrix); + cairo_set_fill_rule(cr, style.GetFillRule() == wxCSS_VALUE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING); cairo_fill(cr); cairo_path_destroy(path); } @@ -437,7 +446,9 @@ void wxSVGCanvasCairo::DrawCanvasPath(wxSVGCanvasPathCairo& canvasPath, wxSVGMatrix& matrix, const wxCSSStyleDeclaration& style, wxSVGSVGElement& svgElem) { - // check Filter + // clipPath + SetClipPath(style.GetClipPath(), matrix, svgElem); + // filter if (style.GetFilter().GetCSSPrimitiveType() == wxCSS_URI && style.GetFilter().GetStringValue().length() > 1) { wxString filterId = style.GetFilter().GetStringValue().substr(1); wxSVGElement* filterElem = (wxSVGElement*) svgElem.GetElementById(filterId); @@ -478,6 +489,49 @@ cairo_surface_destroy(surface); return; } + } else + // Mask + if (style.GetMask().GetCSSPrimitiveType() == wxCSS_URI && style.GetMask().GetStringValue().length() > 1) { + wxString maskId = style.GetMask().GetStringValue().substr(1); + wxSVGMaskElement* maskElem = (wxSVGMaskElement*) svgElem.GetElementById(maskId); + if (maskElem && maskElem->GetDtd() == wxSVG_MASK_ELEMENT) { + wxSVGRect rect = canvasPath.GetResultBBox(style, &matrix); + int width = (int) rect.GetWidth(); + int height = (int) rect.GetHeight(); + + // draw mask + maskElem->SetOwnerSVGElement(&svgElem); + maskElem->SetViewportElement(&svgElem); + cairo_surface_t* maskSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + cairo_t* maskCr = cairo_create(maskSurface); + wxSVGMatrix maskMatrix = wxSVGMatrix(1, 0, 0, 1, - rect.GetX(), - rect.GetY()).Multiply(matrix); + wxCSSStyleDeclaration maskStyle; + + cairo_t* tmp = m_cr; + m_cr = maskCr; + RenderChilds(maskElem, NULL, &maskMatrix, &maskStyle, &svgElem, &svgElem, NULL); + m_cr = tmp; + + // draw surface + cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + cairo_t* cr = cairo_create(surface); + wxSVGMatrix matrix2 = wxSVGMatrix(1, 0, 0, 1, - rect.GetX(), - rect.GetY()).Multiply(matrix); + DrawPath(cr, canvasPath, matrix2, style, svgElem); + + cairo_save(m_cr); + SetMatrix(m_cr, wxSVGMatrix(1, 0, 0, 1, rect.GetX(), rect.GetY())); + cairo_set_source_surface(m_cr, surface, 0, 0); + cairo_rectangle(m_cr, 0, 0, width, height); + cairo_mask_surface(m_cr, maskSurface, 0, 0); + cairo_new_path(m_cr); + cairo_restore(m_cr); + + cairo_destroy(cr); + cairo_surface_destroy(surface); + cairo_destroy(maskCr); + cairo_surface_destroy(maskSurface); + return; + } } DrawPath(m_cr, canvasPath, matrix, style, svgElem); } @@ -489,6 +543,21 @@ cairo_set_matrix(cr, &mat); } +void wxSVGCanvasCairo::SetClipPath(const wxCSSPrimitiveValue& clipPath, wxSVGMatrix& matrix, wxSVGSVGElement& svgElem) { + cairo_reset_clip(m_cr); + if (clipPath.GetCSSPrimitiveType() != wxCSS_URI || clipPath.GetStringValue().length() < 2) + return; + wxString clipPathId = clipPath.GetStringValue().substr(1); + wxSVGClipPathElement* clipPathElem = (wxSVGClipPathElement*) svgElem.GetElementById(clipPathId); + if (!clipPathElem && clipPathElem->GetDtd() != wxSVG_CLIPPATH_ELEMENT) + return; + clipPathElem->SetOwnerSVGElement(&svgElem); + clipPathElem->SetViewportElement(&svgElem); + wxSVGMatrix clipMatrix(matrix); + clipPathElem->UpdateMatrix(clipMatrix); + SetClipPath(clipPathElem, clipMatrix); +} + void wxSVGCanvasCairo::SetClipPath(wxSVGElement* clipPathElem, wxSVGMatrix matrix) { SetMatrix(m_cr, matrix); wxSVGElement* elem = (wxSVGElement*) (clipPathElem->GetFirstChild()); @@ -545,149 +614,6 @@ } } -void wxSVGCanvasCairo::DrawMask(cairo_t* cr, wxSVGElement* maskElem, const wxSVGMatrix& matrix, - const wxCSSStyleDeclaration& style, wxSVGSVGElement& svgElem) { - SetMatrix(cr, matrix); - wxSVGElement* elem = (wxSVGElement*) (maskElem->GetFirstChild()); - while (elem != NULL) { - elem->SetOwnerSVGElement(maskElem->GetOwnerSVGElement()); - elem->SetViewportElement(maskElem->GetViewportElement()); - wxSVGDocument* doc = (wxSVGDocument*) elem->GetOwnerDocument(); - wxSVGCanvasItem* canvasItem = NULL; - wxCSSStyleDeclaration resStyle = style; - switch (elem->GetDtd()) { - case wxSVG_G_ELEMENT: { - wxSVGGElement* gElement = (wxSVGGElement*) elem; - if (gElement->GetVisibility() == wxCSS_VALUE_HIDDEN) - break; - resStyle.Add(((wxSVGGElement*) elem)->GetStyle()); - DrawMask(cr, elem, matrix, resStyle, svgElem); - break; - } - case wxSVG_LINE_ELEMENT: { - wxSVGLineElement* element = (wxSVGLineElement*) elem; - if (element->GetVisibility() == wxCSS_VALUE_HIDDEN) - break; - canvasItem = doc->GetCanvas()->CreateItem(element); - resStyle.Add(element->GetStyle()); - resStyle.Add(element->GetAnimStyle()); - break; - } - case wxSVG_POLYLINE_ELEMENT: { - wxSVGPolylineElement* element = (wxSVGPolylineElement*) elem; - if (element->GetVisibility() == wxCSS_VALUE_HIDDEN) - break; - canvasItem = doc->GetCanvas()->CreateItem(element); - resStyle.Add(element->GetStyle()); - resStyle.Add(element->GetAnimStyle()); - break; - } - case wxSVG_POLYGON_ELEMENT: { - wxSVGPolygonElement* element = (wxSVGPolygonElement*) elem; - if (element->GetVisibility() == wxCSS_VALUE_HIDDEN) - break; - canvasItem = doc->GetCanvas()->CreateItem(element); - resStyle.Add(element->GetStyle()); - resStyle.Add(element->GetAnimStyle()); - break; - } - case wxSVG_RECT_ELEMENT: { - wxSVGRectElement* element = (wxSVGRectElement*) elem; - if (element->GetVisibility() == wxCSS_VALUE_HIDDEN) - break; - canvasItem = doc->GetCanvas()->CreateItem(element); - resStyle.Add(element->GetStyle()); - resStyle.Add(element->GetAnimStyle()); - break; - } - case wxSVG_CIRCLE_ELEMENT: { - wxSVGCircleElement* element = (wxSVGCircleElement*) elem; - if (element->GetVisibility() == wxCSS_VALUE_HIDDEN) - break; - canvasItem = doc->GetCanvas()->CreateItem(element); - resStyle.Add(element->GetStyle()); - resStyle.Add(element->GetAnimStyle()); - break; - } - case wxSVG_ELLIPSE_ELEMENT: { - wxSVGEllipseElement* element = (wxSVGEllipseElement*) elem; - if (element->GetVisibility() == wxCSS_VALUE_HIDDEN) - break; - canvasItem = doc->GetCanvas()->CreateItem(element); - resStyle.Add(element->GetStyle()); - resStyle.Add(element->GetAnimStyle()); - break; - } - case wxSVG_PATH_ELEMENT: { - wxSVGPathElement* element = (wxSVGPathElement*) elem; - if (element->GetVisibility() == wxCSS_VALUE_HIDDEN) - break; - canvasItem = doc->GetCanvas()->CreateItem(element); - resStyle.Add(element->GetStyle()); - resStyle.Add(element->GetAnimStyle()); - break; - } - case wxSVG_USE_ELEMENT: { - wxSVGUseElement* element = (wxSVGUseElement*) elem; - if (element->GetVisibility() == wxCSS_VALUE_HIDDEN) - break; - resStyle.Add(element->GetStyle()); - resStyle.Add(element->GetAnimStyle()); - // get ref element - wxString href = element->GetHref(); - if (href.length() == 0 || href.GetChar(0) != wxT('#')) - break; - href.Remove(0, 1); - wxSVGElement* refElem = (wxSVGElement*) maskElem->GetOwnerSVGElement()->GetElementById(href); - if (!refElem) - break; - - // create shadow tree - wxSVGGElement* gElem = new wxSVGGElement(); - gElem->SetOwnerDocument(elem->GetOwnerDocument()); - gElem->SetOwnerSVGElement(maskElem->GetOwnerSVGElement()); - gElem->SetViewportElement(maskElem->GetViewportElement()); - gElem->SetStyle(element->GetStyle()); - if (element->GetX().GetAnimVal().GetUnitType() != wxSVG_LENGTHTYPE_UNKNOWN) - gElem->Translate(element->GetX().GetAnimVal(), element->GetY().GetAnimVal()); - if (refElem->GetDtd() == wxSVG_SYMBOL_ELEMENT || refElem->GetDtd() == wxSVG_SVG_ELEMENT) { - wxSVGSVGElement* svgElem; - if (refElem->GetDtd() == wxSVG_SVG_ELEMENT) - svgElem = (wxSVGSVGElement*) refElem->CloneNode(); - else { - svgElem = new wxSVGSVGElement(); - wxSvgXmlElement* child = refElem->GetChildren(); - while (child) { - svgElem->AddChild(child->CloneNode()); - child = child->GetNext(); - } - svgElem->SetViewBox(((wxSVGSymbolElement*) refElem)->GetViewBox()); - svgElem->SetPreserveAspectRatio(((wxSVGSymbolElement*) refElem)->GetPreserveAspectRatio()); - } - if (element->GetWidth().GetAnimVal().GetUnitType() != wxSVG_LENGTHTYPE_UNKNOWN) - svgElem->SetWidth(element->GetWidth().GetAnimVal()); - if (element->GetHeight().GetAnimVal().GetUnitType() != wxSVG_LENGTHTYPE_UNKNOWN) - svgElem->SetHeight(element->GetHeight().GetAnimVal()); - gElem->AddChild(svgElem); - } else - gElem->AddChild(refElem->CloneNode()); - // render - DrawMask(cr, gElem, matrix, resStyle, svgElem); - // delete shadow tree - delete gElem; - break; - } - default: - break; - } - if (canvasItem != NULL) { - DrawPath(cr, ((wxSVGCanvasPathCairo&) *canvasItem), matrix, resStyle, svgElem); - delete canvasItem; - } - elem = (wxSVGElement*) elem->GetNextSibling(); - } -} - void wxSVGCanvasCairo::DrawCanvasImage(wxSVGCanvasImage& canvasImage, cairo_surface_t* cairoSurface, wxSVGMatrix& matrix, const wxCSSStyleDeclaration& style, wxSVGSVGElement& svgElem) { if (cairoSurface == NULL) @@ -695,19 +621,7 @@ cairo_save(m_cr); - // ClipPath - if (style.GetClipPath().GetCSSPrimitiveType() == wxCSS_URI && style.GetClipPath().GetStringValue().length() > 1) { - wxString clipPathId = style.GetClipPath().GetStringValue().substr(1); - wxSVGClipPathElement* clipPathElem = (wxSVGClipPathElement*) svgElem.GetElementById(clipPathId); - if (clipPathElem && clipPathElem->GetDtd() == wxSVG_CLIPPATH_ELEMENT) { - clipPathElem->SetOwnerSVGElement(&svgElem); - clipPathElem->SetViewportElement(&svgElem); - wxSVGMatrix clipMatrix(matrix); - clipPathElem->UpdateMatrix(clipMatrix); - SetClipPath(clipPathElem, clipMatrix); - } - } - + SetClipPath(style.GetClipPath(), matrix, svgElem); SetMatrix(m_cr, matrix); // scale context @@ -766,12 +680,18 @@ maskElem->SetViewportElement(&svgElem); cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, svgElem.GetWidth().GetAnimVal()/scaleX, svgElem.GetHeight().GetAnimVal()/scaleY); - cairo_t* cr = cairo_create(surface); + cairo_t* maskCr = cairo_create(surface); wxSVGMatrix maskMatrix; maskMatrix = maskMatrix.Translate(x, y).ScaleNonUniform(scaleX, scaleY).Inverse(); - DrawMask(cr, maskElem, maskMatrix, style, svgElem); + wxCSSStyleDeclaration maskStyle; + + cairo_t* tmp = m_cr; + m_cr = maskCr; + RenderChilds(maskElem, NULL, &maskMatrix, &maskStyle, &svgElem, &svgElem, NULL); + m_cr = tmp; + cairo_mask_surface(m_cr, surface, 0, 0); - cairo_destroy(cr); + cairo_destroy(maskCr); cairo_surface_destroy(surface); } } else { @@ -802,15 +722,20 @@ CAIRO_FORMAT_ARGB32, lround(markerElem->GetMarkerWidth().GetAnimVal() * scaleX), lround(markerElem->GetMarkerHeight().GetAnimVal() * scaleY)); - cairo_t* cr = cairo_create(surface); + cairo_t* markerCr = cairo_create(surface); wxSVGMatrix markerMatrix; markerMatrix = markerMatrix.ScaleNonUniform(scaleX, scaleY); - wxCSSStyleDeclaration style; - DrawMask(cr, markerElem, markerMatrix, style, svgElem); + wxCSSStyleDeclaration markerStyle; + + cairo_t* tmp = m_cr; + m_cr = markerCr; + RenderChilds(markerElem, NULL, &markerMatrix, &markerStyle, &svgElem, &svgElem, NULL); + m_cr = tmp; + // draw surface cairo_save(m_cr); - double refX = markerElem->GetRefX().GetAnimVal() * style.GetStrokeWidth(); - double refY = markerElem->GetRefY().GetAnimVal() * style.GetStrokeWidth(); + double refX = markerElem->GetRefX().GetAnimVal() * markerStyle.GetStrokeWidth(); + double refY = markerElem->GetRefY().GetAnimVal() * markerStyle.GetStrokeWidth(); wxSVGPoint point(markPoint.x - refX, markPoint.y - refY); point = point.MatrixTransform(matrix); wxSVGMatrix m; @@ -824,7 +749,7 @@ cairo_set_source_surface(m_cr, surface, 0, 0); cairo_paint(m_cr); cairo_restore(m_cr); - cairo_destroy(cr); + cairo_destroy(markerCr); cairo_surface_destroy(surface); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wxsvg-1.5.16/src/cairo/SVGCanvasCairo.h new/wxsvg-1.5.20/src/cairo/SVGCanvasCairo.h --- old/wxsvg-1.5.16/src/cairo/SVGCanvasCairo.h 2019-01-27 20:26:55.000000000 +0100 +++ new/wxsvg-1.5.20/src/cairo/SVGCanvasCairo.h 2019-08-02 23:01:01.000000000 +0200 @@ -59,9 +59,8 @@ void DrawPath(cairo_t* cr, wxSVGCanvasPathCairo& canvasPath, const wxSVGMatrix& matrix, const wxCSSStyleDeclaration& style, wxSVGSVGElement& svgElem); void SetMatrix(cairo_t* cr, const wxSVGMatrix& matrix); + void SetClipPath(const wxCSSPrimitiveValue& clipPath, wxSVGMatrix& matrix, wxSVGSVGElement& svgElem); void SetClipPath(wxSVGElement* clipPathElem, wxSVGMatrix matrix); - void DrawMask(cairo_t* cr, wxSVGElement* maskElem, const wxSVGMatrix& matrix, const wxCSSStyleDeclaration& style, - wxSVGSVGElement& svgElem); void DrawMarker(const wxString& uri, wxSVGMark::Type type, wxSVGCanvasPathCairo& canvasPath, const wxSVGMatrix& matrix, const wxCSSStyleDeclaration& style, wxSVGSVGElement& svgElem); }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wxsvg-1.5.16/src/cairo/SVGCanvasPathCairo.cpp new/wxsvg-1.5.20/src/cairo/SVGCanvasPathCairo.cpp --- old/wxsvg-1.5.16/src/cairo/SVGCanvasPathCairo.cpp 2019-01-27 20:26:55.000000000 +0100 +++ new/wxsvg-1.5.20/src/cairo/SVGCanvasPathCairo.cpp 2019-08-02 23:01:01.000000000 +0200 @@ -124,7 +124,7 @@ for (int i = 0; i < style.GetStrokeDasharray().GetLength(); i++) { dashed[i] = style.GetStrokeDasharray().Item(i).GetFloatValue(); } - cairo_set_dash(cr, dashed, style.GetStrokeDasharray().GetLength(), 0.0); + cairo_set_dash(cr, dashed, style.GetStrokeDasharray().GetLength(), style.GetStrokeDashoffset()); delete dashed; } else cairo_set_dash(cr, NULL, 0, 0); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wxsvg-1.5.16/src/mediadec_ffmpeg.cpp new/wxsvg-1.5.20/src/mediadec_ffmpeg.cpp --- old/wxsvg-1.5.16/src/mediadec_ffmpeg.cpp 2019-01-27 20:26:55.000000000 +0100 +++ new/wxsvg-1.5.20/src/mediadec_ffmpeg.cpp 2019-08-02 23:01:01.000000000 +0200 @@ -47,6 +47,9 @@ void wxFfmpegMediaDecoder::Init() { // nothing to do +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 0, 0) + av_register_all(); +#endif } void PrintError(const wxString& msg, int err) {